Знакомство с Python, машинным обучением и библиотекой NLTK

Разработка приложений для категоризации лент RSS при помощи Python, NLTK и машинного обучения

Краткое содержание. Машинное обучение лежит на пересечении ИТ, математики и естественного языка, оно широко применяется в приложениях в области “больших данных”. В данной статье обсуждается программирование на языке Python и использование его библиотеки NLTK, а впоследствии – приложение этих знаний к проекту машинного обучения.

Крис Хоаким, старший программист, Primedia Inc

Photo of Chris JoakimКрис Хоаким (Chris Joakim) занимает пост старшего инженера по разработке ПО в компании Primedia Inc. Крис разрабатывает ПО уже более 25 лет на различных языках программирования, включая Clojure, Ruby, Java, Objective-C, JavaScript, CoffeeScript, Flex, Smalltalk,COBOL, а теперь и Python. Живет в г. Дейвидсон (Северная Каролина). В свободное время он бегает марафоны и пишет программы. С Крисом можно связаться по адресу cjoakim@bellsouth.net.



28.05.2013

Знакомимся с Python

Эта статья предназначена для разработчиков ПО — особенно имеющих опыт работы с языками Ruby или Java, — которые впервые сталкиваются с машинным обучением.

Задача: Использование машинного обучения для категоризации лент RSS

Недавно мне поручили создать систему категоризации лент RSS для одного из клиентов. Задача состояла в том, чтобы читать десятки и даже сотни сообщений в лентах RSS и автоматическом относить их к одной из десятков предварительно определенных тематик. От ежедневных результатов работы этой системы категоризации и получения новостей должны были зависеть наполнение контентом, навигация и возможности поиска на веб-сайте клиента.

Представительница заказчика предложила использовать машинное обучение, возможно на базе Apache Mahout и Hadoop, так как недавно читала об этих технологиях. Однако разработчики как из ее, так и из нашей команды имели больше опыта работы с Ruby, а не с Java™. В этой статье я рассказываю обо всех технических изысканиях, процессе обучения и, наконец, об итоговой реализации решения.

Что такое машинное обучение?

Мой первый вопрос в данном проекте звучал так: "Что такое машинное обучение на самом деле?". Я слышал этот термин и знал, что суперкомпьютер IBM® Watson недавно победил реальных людей в игру Jeopardy. Как покупатель интернет-магазинов и участник социальных сетей я также понимал, что Amazon.com и Facebook прекрасно справляются с задачей подбора рекомендаций (продуктов или людей) на основании данных о своих покупателях. Если говорить кратко, машинное обучение лежит на пересечении ИТ, математики и естественного языка. В основном этот процесс связан с тремя перечисленными ниже аспектами, но решение для нашего клиента было основано на первых двух:

  • Классификация. Отнесение элементов к предварительно объявленным категориям исходя из тренировочных данных для аналогичных элементов.
  • Рекомендация. Выбор рекомендованных элементов исходя из наблюдений за выбором аналогичных элементов
  • Кластеризация. Выявление подгрупп в массиве данных

Неудачная попытка — Mahout и Ruby

Разобравшись в том, что представляет собой машинное обучение, мы перешли к следующему шагу — поиску способов реализации. По предположению клиента, хорошей отправной точкой мог бы стать Mahout. Я загрузил код с сервера Apache и начал изучать процесс машинного обучения в Mahout и в Hadoop. К сожалению, я обнаружил, что Mahout сложен в изучении даже для опытного разработчика на Java и не имеет работающих примеров кода. Не меньше огорчило ограниченное количество инфраструктур и gem-пакетов для машинного обучения на Ruby.

Находка — Python и NLTK

Я продолжил искать решение; в результатах поиска постоянно обнаруживались упоминания Python. Как приверженец Ruby, я знал, что Python является динамическим языком программирования и использует такую же объектно-ориентированную текстовую модель интерпретации, хотя никогда не изучал этот язык. Несмотря на эти сходства, я много лет уклонялся от изучения Python, считая его лишним знанием. Таким образом, Python был моим "слепым пятном", и я подозреваю, что такая же картина наблюдается у многих коллег-программистов на Ruby.

Поиск книг по машинному обучению и детальное изучение их содержания показали, что значительная часть подобных систем реализуется на Python в сочетании с библиотекой для работ с естественными языками Natural Language Toolkit (NLTK). Дальнейшие поиски позволили выяснить, что Python используется гораздо чаще, чем я думал, например, в движке Google App, на YouTube, а также на веб-сайтах, использующих Django. Оказывается, он изначально установлен на рабочих станциях Mac OS X, с которыми я ежедневно работаю! Более того, Python обладает интересными стандартными библиотеками (например, NumPy и SciPy) для математических расчетов, научных изысканий и инженерных решений. Кто же мог знать?

Обнаружив элегантные примеры кода, я решил использовать решение на Python. Например, приведенный ниже однострочный код делает все необходимое для получения RSS-новости по протоколу HTTP и печати ее содержимого:

    print feedparser.parse("http://feeds.nytimes.com/nyt/rss/Technology")

Продвигаемся к цели вместе с Python

При изучении нового языка программирования самой простой частью является обучение самому языку. Более сложный процесс — изучение экосистемы. Нужно разобраться, как его устанавливать, как добавлять библиотеки, писать код, структурировать файлы, запускать, отлаживать и подготавливать тесты. В этой части мы приводим краткое введение в данные разделы; не забудьте просмотреть ссылки из раздела Ресурсы— там может быть много полезной информации.

pip

Python Package Index (pip) — стандартный менеджер пакетов в Python. Это именно та программа, которую вы будете использовать для добавления библиотек в вашу систему. Он аналогичен gem для библиотек Ruby. Чтобы добавить библиотеку NLTK в вашу систему, вам нужно выполнить следующую команду:

  $ pip install nltk

Чтобы отобразить перечень библиотек Python, установленных в вашей системе, используйте команду:

  $ pip freeze

Запуск программ

Запуск программ на Python происходит так же просто. Если у вас есть программа locomotive_main.py, принимающая три аргумента, вы можете скомпилировать и запустить выполнение кода при помощи следующей команды на python:

  $ python locomotive_main.py arg1 arg2 arg3

Синтаксис if __name__ == "__main__", приведенный в листинге 1, используется в языке Python для того, чтобы определить, запущен ли файл отдельно из командной строки или же вызван другим фрагментом кода. Чтобы сделать программу выполняемой, добавьте в нее проверку на "__main__".

Листинг 1. Проверка статуса Main
import sys
import time
import locomotive

if __name__ == "__main__":
    start_time = time.time()
    if len(sys.argv) > 1:
        app = locomotive.app.Application()
        ... дополнительная логика  ...

virtualenv

Многие программисты на Ruby знакомы с проблемой общих системных библиотек, также называемых gem. Применение общесистемных наборов библиотек, как правило, нежелательно, поскольку один из ваших проектов может полагаться на версию 1.0.0 имеющейся библиотеки, а другой — на версию 1.2.7. Разработчики на Java сталкиваются с подобной проблемой в случае общесистемной переменной CLASSPATH. Подобно инструменту rvm в Ruby, в Python используется инструмент virtualenv (см. ссылку в разделе Ресурсы), создающий отдельные среды исполнения программ, включая специальные инструкции Python и наборы библиотек. Команды в листинге 2 показывают, как создать виртуальную среду исполнения с именем p1_env для вашего проекта p1, в состав которого будут входить библиотеки feedparser, numpy, scipy и nltk.

Листинг 2. Создание виртуальной среды исполнения с помощью virualenv
  $ sudo pip install virtualenv
  $ cd ~
  $ mkdir p1
  $ cd p1
  $ virtualenv p1_env --distribute
  $ source p1_env/bin/activate 
  (p1_env)[~/p1]$ pip install feedparser
  (p1_env)[~/p1]$ pip install numpy
  (p1_env)[~/p1]$ pip install scipy
  (p1_env)[~/p1]$ pip install nltk
  (p1_env)[~/p1]$ pip freeze

Скрипт для активации вашей виртуальной среды необходимо запускать каждый раз, когда вы работаете с вашим проектом в окне оболочки. Обратите внимание на то, что после исполнения скрипта активации меняется командное приглашение оболочки. Для удобства перехода к каталогу вашего проекта и активации виртуальной среды после создания окна оболочки в вашей системе полезно добавить в файл ~/.bash_profile запись наподобие следующей:

$ alias p1="cd ~/p1 ; source p1_env/bin/activate"

Базовая структура кода

Освоив простые программы уровня "Hello World", разработчику на Python необходимо научиться правильно структурировать код с учетом каталогов и имен файлов. Как и в Java или Ruby, в Python есть для этого свои правила. Если говорить коротко, Python использует для группировки связанного кода концепцию пакетов и использует однозначно определенные пространства имен. В целях демонстрации в данной статье код размещается в корневом каталоге проекта, например, ~/p1. В нем имеется подкаталог locomotive, содержащий одноименный Python- пакет. Эта структура каталогов показана в листинге 3.

Листинг 3. Пример структуры каталогов
locomotive_main.py
locomotive_tests.py

locomotive/
    __init__.py
    app.py
    capture.py
    category_associations.py
    classify.py
    news.py
    recommend.py
    rss.py

locomotive_tests/
    __init__.py
    app_test.py
    category_associations_test.py
    feed_item_test.pyc
    rss_item_test.py

Обратите внимание на файлы со странным названием __init__.py. В этих файлах содержатся инструкции Python для подгрузки необходимых библиотек к вашей среде, а также к вашим специальным приложениям, которые находятся в том же каталоге. В листинге 4 приведено содержимое файла locomotive/__init__.py.

Листинг 4. locomotive/__init__.py
    # импорт системных компонентов; загрузка установленных компонентов
    import codecs
    import locale
    import sys

    # импорт компонентов приложения; загрузка пользовательских файлов *.py 
    import app
    import capture
    import category_associations
    import classify
    import rss
    import news
    import recommend

При структуре пакета locomotive, показанной в листинге 4, основные программы из корневого каталога вашего проекта могут импортировать и использовать его. Например, файл locomotive_main.py содержит следующие команды импорта:

    import sys         # >-- системная библиотека
    import time        # >-- системная библиотека
    import locomotive  # >-- пользовательская библиотека прикладного кода 
                       #  из каталога "locomotive"

Тестирование

Стандартная Python-библиотека unittest предоставляет удобные ресурсы для тестирования. Разработчики на Java, знакомые с JUnit, а также специалисты по Ruby, работающие с инфраструктурой Test::Unit, легко поймут код Python unittest из листинга 5.

Листинг 5. Python unittest
  class AppTest(unittest.TestCase):

      def setUp(self):
          self.app = locomotive.app.Application()

      def tearDown(self):
          pass

      def test_development_feeds_list(self):
          feeds_list = self.app.development_feeds_list()
          self.assertTrue(len(feeds_list) == 15)
          self.assertTrue('feed://news.yahoo.com/rss/stock-markets' in feeds_list)

Содержимое листинга 5 также демонстрирует отличительную черту Python: для успешной компиляции код должен иметь единообразно установленные отступы. Метод tearDown(self) может показаться странным - зачем в коде теста запрограммирован успешный результат прохождения? На самом деле в этом нет ничего страшного. Таким образом в Python можно запрограммировать пустой метод.

Инструменты

Что мне действительно было необходимо — так это интегрированная среда разработки (IDE) с подсветкой синтаксиса, завершением кода и возможностью исполнения с контрольными точками, чтобы освоиться в Python. Как пользователь Eclipse IDE для Java, я первым делом обратил внимание на pyeclipse. Этот модуль работает достаточно неплохо, но иногда - очень медленно. В конце концов я выбрал IDE PyCharm, которая удовлетворила все мои требования.

Итак, вооружившись базовыми знаниями о Python и его экосистеме, я, наконец, был готов к реализации машинного обучения.


Реализация категорий на Python и NLTK

Для построения решения мне нужно было обрабатывать имитационные ленты новостей RSS, анализировать их текст при помощи NaiveBayesClassifier, а затем классифицировать их по категориям посредством алгоритму kNN. Каждое из этих действий описано в данной статье.

Извлечение и обработка лент новостей

Одна из сложностей проекта состояла в том, что клиент еще не определил перечень целевых лент новостей RSS. Также не было и «данных для обучения». Поэтому ленты новостей и тренировочные данные на начальном этапе разработки приходилось имитировать.

Первый способ получения образцов данных лент новостей, который я использовал, состоял в том, чтобы сохранить содержимое списка лент RSS в текстовом файле. В Python есть очень неплохая библиотека для обработки лент RSS под названием feedparser, которая позволяет скрыть различия между различными форматами RSS и Atom. Еще одна полезная библиотека для сериализации простых текстовых объектов шутливо названа pickle («маринад»). Обе библиотеки используются в коде из листинга 6, который сохраняет каждую ленту RSS в "замаринованном" виде для дальнейшего использования. Как вы можете видеть, программный код на Python является лаконичным и мощным.

Листинг 6. Класс CaptureFeeds
import feedparser
import pickle

class CaptureFeeds:

    def __init__(self):
        for (i, url) in enumerate(self.rss_feeds_list()):
            self.capture_as_pickled_feed(url.strip(), i)

    def rss_feeds_list(self):
        f = open('feeds_list.txt', 'r')
        list = f.readlines()
        f.close
        return list

    def capture_as_pickled_feed(self, url, feed_index):
        feed = feedparser.parse(url)
        f = open('data/feed_' + str(feed_index) + '.pkl', 'w')
        pickle.dump(feed, f)
        f.close()

if __name__ == "__main__":
    cf = CaptureFeeds()

Следующий шаг оказался неожиданно трудоемким. После получения образца данных лент мне необходимо было категоризовать его для последующего использования в качестве тренировочных данных. Тренировочные данные — это именно тот набор информации, который вы предоставляете своему алгоритму категоризации в качестве ресурса для обучения.

Например, среди образцов лент, которые я использовал, был канал спортивных новостей ESPN. Одно из сообщений повествовало о том, что Тим Тэбоу (Tebow) из футбольной команды Denver Broncos был куплен New York Jets, а в то же время Broncos подписали контракт с Пейтоном Мэннингом (Manning), который стал их новым полузащитником (quarterback). Другое сообщение касалось компании Boeing и ее нового реактивного авиалайнера (англ. jet). Возникает вопрос: к какой категории следует отнести первую историю? Прекрасно подходят слова tebow, broncos, manning, jets, quarterback, trade и nfl. Но для указания категории обучающих данных нужно выбрать всего одно слово. То же самое можно сказать и про вторую историю — что выбрать, boeing или jet? Вся сложность работы состояла именно в этих деталях. Тщательное ручное категорирование большого количества обучающих данных просто необходимо, если вы хотите, чтобы ваш алгоритм выдавал точные результаты. И время, которое придется потратить на это, нельзя недооценивать.

Скоро стало очевидно, что мне нужны еще данные для работы, причем они уже должны быть разбиты по категориям — и достаточно точно. Где искать такие данные? И тут на сцену выходит Python NLTK. Помимо того, что это великолепная библиотека для обработки текстов на естественных языках, к ней прилагаются готовые загружаемые наборы исходных данных, т.н. «корпуса», а также программные интерфейсы для удобного доступа к этим данным. Чтобы установить корпус Reuters, вам нужно выполнить приведенные ниже команды, и в ваш каталог ~/nltk_data/corpora/reuters/ будет загружено более 10 000 новостных сообщений. Как и элементы ленты RSS, каждая новостная статья Reuters содержит заголовок и основную часть, поэтому категорированные данные NLTK идеально подходят для имитации лент новостей RSS.

$ python               # входим в интерактивную оболочку Python 
>>> import nltk        # импортируем библиотеку nltk 
>>> nltk.download()    # запускаем загрузчик NLTK и вводим 'd' 
Identifier> reuters    # указываем корпус 'reuters'

Особый интерес представляет файл ~/nltk_data/corpora/reuters/cats.txt. В нем содержится перечень имен файлов с заметками, а также категории, назначенные каждому из файлов. Следующие записи обозначают, что файл 14828 в подкаталоге test отнесен к теме grain.

test/14826 trade
test/14828 grain

Естественный язык — это сложно

Сырьем для нашего алгоритма категорирования RSS-материалов, разумеется, являются простые тексты на английском языке. Термин «сырье» здесь весьма уместен.

Английский, как и любой другой естественный язык (язык повседневного общения) отличается чрезвычайной неоднородностью и непоследовательностью с точки зрения компьютерной обработки. Первым делом возникает вопрос с регистром. Можно ли считать слово Bronco равным bronco? Ответ будет: «возможно». Также важны пунктуация и пробелы. Можно ли сравнивать bronco. с bronco или bronco,? Вроде бы да. Далее, существуют формы множественного числа и схожие слова. Можно ли считать run, running и ran эквивалентными формами? Зависит от ситуации. Эти три слова являются однокоренными. А что если слова из естественного языка также сопровождаются тегами HTML? В этом случае вам придется работать с такими элементами, как <strong>bronco</strong>. Наконец, существует проблема часто используемых, но фактически ничего не значащих слов, таких как артикли, союзы и предлоги. Эти так называемые вспомогательные слова усложняют обработку. Таким образом, естественный язык весьма беспорядочен и требует очистки перед началом работы.

К счастью, Python и NLTK позволяют вам легко избавиться от этого мусора. Метод normalized_words из класса RssItem в листинге 7, позволяет исключить все эти препятствия. В частности, обратите внимание, как NLTK очищает сырой текст статьи от встроенных тегов HTML при помощи всего одной строчки кода! Кроме того, с помощью регулярного выражения выполняется удаление пунктуации, после чего текст делится на слова и переводится в нижний регистр.

Листинг 7. Класс RssItem
class RssItem:
    ...
    regex = re.compile('[%s]' % re.escape(string.punctuation))
    ...
    def normalized_words(self, article_text):
        words   = []
        oneline = article_text.replace('\n', ' ')
        cleaned = nltk.clean_html(oneline.strip())
        toks1   = cleaned.split()
        for t1 in toks1:
            translated = self.regex.sub('', t1)
            toks2 = translated.split()
            for t2 in toks2:
                t2s = t2.strip().lower()
                if self.stop_words.has_key(t2s):
                    pass
                else:
                    words.append(t2s)
        return words

Перечень вспомогательных слов берется из NLTK одной командой; поддерживаются и другие естественные языки.

nltk.corpus.stopwords.words('english')

NLTK также предоставляет несколько классов морфологического анализа для дальнейшей нормализации слов. Подробнее о морфологическом анализе, лемматизации, анализе структуры предложений и грамматике можно узнать в документации NLTK.

Классификация по простому байесовскому алгоритму

Алгоритм Naive Bayes (простой байесовский алгоритм) широко известен и встроен в NLTK в виде класса nltk.NaiveBayesClassifier. Байесовский алгоритм позволяет классифицировать элементы по факту наличия или отсутствия определенных элементов в их составе. В случае с лентами RSS в качестве элементов используются определенные (очищенные) слова естественного языка. Алгоритм является "простым" в том смысле, что не подразумевает взаимосвязей между элементами (в нашем случае словами).

Однако в английском языке имеется более 250 000 слов. Безусловно, я не хотел бы создавать объект с 250 000 логических значений для каждой ленты RSS, чтобы реализовать алгоритм. Итак, какие слова использовать? Если говорить кратко, это должны быть наиболее часто встречающиеся слова из тестовых данных, которые не являются вспомогательными. В NLTK имеется очень удобный класс nltk.probability.FreqDist, который позволяет выявить эти популярные слова. А приведенный в листинге 8, метод collect_all_words возвращает массив, содержащий все слова из всех тренировочных заметок.

Далее этот массив обрабатывается методом identify_top_words, который возвращает наиболее часто встречающиеся слова. Удобная функция класса nltk.FreqDist фактически создает хэш, но его ключи оказываются отсортированными согласно соответствующим значениям (количеству вхождений). Таким образом, можно легко выделить 1000 самых часто встречающихся слов, указав диапазон индексов [:1000] в соответствии с синтаксисом Python.

Листинг 8. Использование класса nltk.FreqDist
  def collect_all_words(self, items):
      all_words = []
      for item in items:
          for w in item.all_words:
              words.append(w)
      return all_words

  def identify_top_words(self, all_words):
      freq_dist = nltk.FreqDist(w.lower() for w in all_words)
      return freq_dist.keys()[:1000]

Для имитации лент RSS на базе данных NLTK из статей Reuters мне нужно было выделить категории для каждой из них. Я сделал это, читая файл ~/nltk_data/corpora/reuters/cats.txt, о котором я уже говорил ранее. Чтение файла на Python происходит просто:

  def read_reuters_metadata(self, cats_file):
      f = open(cats_file, 'r')
      lines = f.readlines()
      f.close()
      return lines

Следующий шаг — получение характеристик каждого сообщения из ленты RSS. Это действие выполняет метод features из класса RssItem, продемонстрированный ниже. При работе данного метода массив всех слов (all_words) статьи сначала сокращается до меньшего по размерам набора уникальных слов (set) за счет устранения дубликатов слов. Далее выполняется проход по списку наиболее распространенных слов top_words и проверка их наличия или отсутствия в статье. В результате мы получаем хэш из 1000 логических значений, ключами которого являются сами слова с префиксом w_. Соответствующий код на Python весьма краток.

  def features(self, top_words):
      word_set = set(self.all_words)
      features = {}
      for w in top_words:
          features["w_%s" % w] = (w in word_set)
      return features

Далее я собираю тренировочный набор сообщений RSS и их индивидуальных характеристик и передаю их на обработку алгоритму. Код из листинга 9 демонстрирует выполнение этой задачи. Обратите внимание, что обучение классификатора занимает ровно одну строчку кода.

Листинг 9. Обучение nltk.NaiveBayesClassifier
  def classify_reuters(self):
        ...
        training_set = []
        for item in rss_items:
            features = item.features(top_words)
            tup = (features, item.category)  # tup is a 2-element tuple
            featuresets.append(tup)
        classifier = nltk.NaiveBayesClassifier.train(training_set)

Итак, классификатор NaiveBayesClassifier, находящийся в памяти работающей программы Python, обучен. Теперь я могу просто пройти по списку лент RSS, которые нужно классифицировать, и определить с помощью классификатора категорию для каждого из элементов. Очень просто.

  for item in rss_items_to_classify:
      features = item.features(top_words)
      category = classifier.classify(feat)

Менее простая классификация

Как уже говорилось ранее, наш алгоритм не подразумевает наличия взаимосвязей между индивидуальными параметрами. Таким образом, фразы типа "machine learning" и "learning machine" либо "New York Jet" и "jet to New York" являются эквивалентами (предлог «to» исключается как вспомогательное слово). В естественном же языке между этими словами имеются очевидные связи. Как сделать алгоритм менее «простым» и научить его распознавать эти взаимосвязи между словами?

Один из методов — включить в набор параметров распространенные словосочетания из двух (биграммы) и трех слов (триграммы). И мы уже не удивляемся тому, что в NLTK имеется поддержка этих возможностей в виде функций nltk.bigrams(...) и nltk.trigrams(...). Точно также как библиотека выбирала из всего набора данных N самых часто встречающихся слов, она может идентифицировать самые популярные двух- и трехсловные словосочетания и использовать их в качестве параметров.

Ваши результаты могут быть другими

Очистка данных и применение алгоритма — это своего рода искусство. Стоит ли нормализовать набор слов еще сильнее, например, выделяя корни? Или нужно включить в набор более чем 1000 самых частых слов? Или меньше? Или, может быть, нужно использовать более объемный набор данных для обучения? Или определить больше слов как вспомогательные? Все эти вопросы вы можете задать самим себе. Экспериментируйте с ними, пробуйте, проходите через ошибки, и вы сможете создать лучший алгоритм для ваших данных. Я решил для себя, что 85% — это хороший уровень успешной категоризации.

Рекомендации к алгоритму k-Nearest Neighbors

Клиент хотел отображать элементы ленты RSS в выбранной категории или в связанных категориях. Теперь, когда данные были категоризованы при помощи простого байесовского алгоритма, первая часть требований заказчика была выполнена. Более сложной оказалась задача определения «связанных категорий». В этом случае нужно использовать системы рекомендаций на основе алгоритмов машинного обучения. Система рекомендаций основывается на схожести одних элементов с другими. Хорошими примерами таких функций являются рекомендации продуктов на Amazon.com и рекомендации друзей в Facebook.

Наиболее популярным алгоритмом для построения рекомендаций является алгоритм k-Nearest Neighbors (kNN, k ближайших соседей). Идея состоит в том, чтобы создать перечень меток (категорий) и сопоставить каждой метке набор данных. Далее алгоритм сравнивает наборы данных, выявляя совпадающие элементы. Набор данных представлен набором численных значений, обычно приведенных к нормализованному виду — от 0 до 1. Затем можно выделять похожие метки на основании наборов данных. В отличие от простого алгоритма Байеса, который дает один результат, kNN может выдать целый перечень рекомендаций со степенями совпадения (определяется значением k).

Алгоритмы рекомендации показались мне более простыми для понимания и реализации, чем алгоритмы классификации, хотя сам код оказался более длинным и слишком сложным с математической точки зрения, чтобы приводить его здесь. Примеры кода для kNN можно найти в великолепной новой книге издательства Manning «Machine Learning in Action (см. ссылку в разделе Ресурсы). В нашем случае с обработкой лент RSS значения меток совпадали с категориями, а наборы данных представляли собой массивы значений для 1000 самых популярных слов. Еще раз повторюсь, что создание такого массива — это частично наука, частично математика и частично искусство. Для каждого слова в массиве значение может представлять собой булеву величину (0 или 1), частоту встречаемости слова в процентах, экспоненциальное выражение от частоты или другую величину.


Заключение

Знакомство с Python, NLTK и машинным обучением оказалось интересным и приятным. Python — это мощный и лаконичный язык программирования, который теперь стал одной из основных частей моего инструментария разработчика. Он прекрасно подходит для реализации машинного обучения, обработки естественного языка и математических и научных приложений. Кроме того, хотя я не упомянул этого в данной статье, он показался мне полезным для создания диаграмм и графиков. И если у вас Python также находился «в слепой зоне», я советую вам познакомиться с ним.

Ресурсы

Научиться

Получить продукты и технологии

  • Ознакомьтесь с сайтом NLTK и узнайте о создании программ на Python для работы с текстами на естественных языках.
  • Загрузите pip и узнайте больше об этом инструменте для установки пакетов Python и управления ими.
  • Узнайте больше об инструменте virtualenv, который позволяет создавать изолированные среды исполнения Python.
  • Познакомьтесь со стандартной библиотекой Python unittest— версией JUnit для языка Python.
  • Узнайте о модуле pyeclipse для Eclipse.
  • Ознакомьтесь с интегрированной средой разработки PyCharm, содержащей полный набор инструментов, необходимых для работы с языком Python и совместимости со средой Django.

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux, Web-архитектура
ArticleID=931595
ArticleTitle=Знакомство с Python, машинным обучением и библиотекой NLTK
publish-date=05282013