Кластериризация данных и Unicode в Python

И снова книга Тоби Сегарана "Программируем
коллективный разум"... Ну нравится она мне :)
Возникло желание разобраться с кластеризацией
данных. Вроде все просто. Скопировал из книги код, вставил и запустил.
И тут начались пляски с бубном. Как "неожиданно оказалось" код (а он написан на Python-е) изначально предполагал работу только с латиницей, а кириллицу  автор книги в расчёт не принимал. По некоторым причинам я работаю с Python версии 2.7 а версию 3.* (где использование кириллицы не вызывает проблем ) использовать не могу.
После долгого гугления решение было найдено. Код нормально работает с кириллическими символами., по крайне мере в Python 2.7.
Пытался ещё улучшить результат работы скрипта удалением из текста предлогов и стоп-слов, но увы, это слабо помогло и этот фрагмент кода был удалён.



  1. # -*- coding: utf-8 -*-
  2. import sys
  3. import feedparser
  4. import re
  5.  
  6.  
  7. def setup_console(sys_enc="utf-8"):
  8. reload(sys)
  9. try:
  10. # для win32 вызываем системную библиотечную функцию
  11. if sys.platform.startswith("win"):
  12. import ctypes
  13. enc = "cp%d" % ctypes.windll.kernel32.GetOEMCP() #TODO: проверить на win64/python64
  14. else:
  15. # для Linux всё, кажется, есть и так
  16. enc = (sys.stdout.encoding if sys.stdout.isatty() else
  17. sys.stderr.encoding if sys.stderr.isatty() else
  18. sys.getfilesystemencoding() or sys_enc)
  19.  
  20. # кодировка для sys
  21. sys.setdefaultencoding(sys_enc)
  22.  
  23. # переопределяем стандартные потоки вывода, если они не перенаправлены
  24. if sys.stdout.isatty() and sys.stdout.encoding != enc:
  25. sys.stdout = codecs.getwriter(enc)(sys.stdout, 'replace')
  26.  
  27. if sys.stderr.isatty() and sys.stderr.encoding != enc:
  28. sys.stderr = codecs.getwriter(enc)(sys.stderr, 'replace')
  29.  
  30. except:
  31. pass # Ошибка? Всё равно какая - работаем по-старому...
  32.  
  33.  
  34. # Возвращает заголовок и словарь слов со счетчиками для RSS-канала
  35. def getwordcounts(url):
  36. # Распарсим RSS канал
  37. d=feedparser.parse(url)
  38.  
  39.  
  40. wc={}
  41.  
  42. # Цикл по всем записям
  43. for e in d.entries:
  44. if 'summary' in e:
  45. summary=e.summary
  46. else: summary=e.description
  47.  
  48. # Формируем список слов
  49. words=getwords(e.title+' '+summary)
  50.  
  51. for word in words:
  52. wc.setdefault(word,0)
  53. wc[word]+=1
  54. return d.feed.title,wc
  55.  
  56. def getwords(html):
  57. # Удаляем HTML теги, знаки пунктуации, предлоги и подобное
  58. txt=re.compile(r'<[^>]+>').sub(' ',html)
  59. txt=re.compile(r'\&[a-z]+\;').sub(' ',txt)
  60. txt=re.compile(r'[:;,-."\[)(\]!?/\r]+').sub(' ',txt)
  61.  
  62. # Выделить слова, ограниченные небуквенными символами
  63. words=re.compile(u'[^А-Я^а-я]+').split(txt)
  64.  
  65. # Преобразовываем все слова в нижний регистр
  66. return [word.lower( ).encode('utf-8') for word in words if word!='']
  67.  
  68.  
  69. setup_console(sys_enc="utf-8")
  70. apcount={}
  71. wordcounts={}
  72. feedlist=[line for line in file('ru-feedlist.txt')]
  73. for feedurl in feedlist:
  74. try:
  75. title,wc=getwordcounts(feedurl)
  76. wordcounts[title]=wc
  77. for word,count in wc.items():
  78. apcount.setdefault(word,0)
  79. if count>1:
  80. apcount[word]+=1
  81. except:
  82. print('Failed to parse feed %s' % feedurl)
  83.  
  84. wordlist=[]
  85. for w,bc in apcount.items():
  86. frac=float(bc)/len(feedlist)
  87. if frac>0.2 and frac<0.5:
  88. wordlist.append(w)
  89.  
  90. out=file('blogdata.txt','w')
  91.  
  92. for word in wordlist: out.write('\t%s' % word)
  93. out.write('\n')
  94. for blog,wc in wordcounts.items():
  95.  
  96. out.write(blog)
  97. for word in wordlist:
  98. if word in wc: out.write('\t%d' % wc[word])
  99. else: out.write('\t0')
  100. out.write('\n')
  101.  


Пользуйтесь на здоровье ! Тестировалось в Ubuntu 12.04 Python 2.7

Комментарии

Популярные сообщения из этого блога

Простой скрипт проверки доступности хоста

Генератор русских имён и фамилий на Python

Букмарклет для скачивания видео с SaveFrom