- 27 января 2014 г.
- Василис Вриниотис
- . 16 комментариев
В предыдущих статьях мы обсудили теоретические основы наивного байесовского классификатора текста и важность использования методов выбора признаков в классификации текста. В этой статье мы собираемся собрать все воедино и построить простую реализацию алгоритма классификации текста наивного байеса в JAVA. Код классификатора находится в открытом доступе (под лицензией GPL v3), и вы можете скачать его с Гитхаб.
Обновление: платформа машинного обучения Datumbox теперь имеет открытый исходный код и бесплатна для скачать. Ознакомьтесь с пакетом com.datumbox.framework.machinelearning.classification, чтобы увидеть реализацию наивного байесовского классификатора в Java.
Наивная байесовская реализация Java
Код написан на языке JAVA и может быть загружен непосредственно с Гитхаб. Он находится под лицензией GPLv3, поэтому не стесняйтесь использовать его, модифицировать и свободно распространять.
Классификатор текста реализует полиномиальную наивную байесовскую модель вместе с алгоритмом выбора признаков Chisquare. Все теоретические детали того, как работают оба метода, описаны в предыдущих статьях, а подробные комментарии javadoc можно найти в исходном коде, описывающем реализацию. Таким образом, в этом сегменте я сосредоточусь на высокоуровневом описании архитектуры классификатора.
1. Класс Наивного Байеса
Это основная часть классификатора текстов. Он реализует такие методы, как train() и predict(), которые отвечают за обучение классификатора и его использование для прогнозов. Следует отметить, что этот класс также отвечает за вызов соответствующих внешних методов для предварительной обработки и токенизации документа перед обучением/прогнозированием.
2. Объект базы знаний NaiveBayesKnowledgeBase
Результатом обучения является объект NaiveBayesKnowledgeBase, в котором хранится вся необходимая информация и вероятности, используемые наивным байесовским классификатором.
3. Объект документа
Тексты обучения и предсказания в реализации хранятся внутри как объекты документа. Объект документа хранит все токены (слова) документа, их статистику и целевую классификацию документа.
4. Объект FeatureStats
Объект FeatureStats хранит несколько статистических данных, созданных на этапе извлечения признаков. Такой статистикой являются совместные подсчеты объектов и классов (из которых оцениваются совместные вероятности и правдоподобия), подсчеты классов (из которых оцениваются априорные значения, если ни один из них не указан в качестве входных данных) и общее количество наблюдений, используемых для обучения.
5. Класс извлечения признаков
Это класс, который отвечает за извлечение признаков. Следует отметить, что, поскольку этот класс вычисляет некоторые статистические данные, которые фактически требуются алгоритму классификации на более позднем этапе, все эти статистические данные кэшируются и возвращаются в объекте FeatureStats, чтобы избежать их повторного расчета.
6. Класс TextTokenizer
Это простой класс токенизации текста, отвечающий за предварительную обработку, очистку и токенизацию исходных текстов и преобразование их в объекты Document.
Использование класса JAVA NaiveBayes
В классе NaiveBayesExample вы можете найти примеры использования класса NaiveBayes. Цель примера кода — представить пример, который обучает простой наивный байесовский классификатор для определения языка текста. Чтобы обучить классификатор, сначала мы предоставляем пути к обучающим наборам данных в HashMap, а затем загружаем их содержимое.
//map of dataset files Map<String, URL> trainingFiles = new HashMap<>(); trainingFiles.put("English", NaiveBayesExample.class.getResource("/datasets/training.language.en.txt")); trainingFiles.put("French", NaiveBayesExample.class.getResource("/datasets/training.language.fr.txt")); trainingFiles.put("German", NaiveBayesExample.class.getResource("/datasets/training.language.de.txt")); //loading examples in memory Map<String, String()> trainingExamples = new HashMap<>(); for(Map.Entry<String, URL> entry : trainingFiles.entrySet()) { trainingExamples.put(entry.getKey(), readLines(entry.getValue())); }
Классификатор NaiveBayes обучается путем передачи ему данных. После завершения обучения объект NaiveBayesKnowledgeBase сохраняется для последующего использования.
//train classifier NaiveBayes nb = new NaiveBayes(); nb.setChisquareCriticalValue(6.63); //0.01 pvalue nb.train(trainingExamples); //get trained classifier NaiveBayesKnowledgeBase knowledgeBase = nb.getKnowledgeBase();
Наконец, чтобы использовать классификатор и предсказать классы новых примеров, все, что вам нужно сделать, это инициализировать новый классификатор, передав объект NaiveBayesKnowledgeBase, который вы получили ранее в результате обучения. Затем, просто вызвав метод предсказания(), вы получите предсказанный класс документа.
//Test classifier nb = new NaiveBayes(knowledgeBase); String exampleEn = "I am English"; String outputEn = nb.predict(exampleEn); System.out.format("The sentense \"%s\" was classified as \"%s\".%n", exampleEn, outputEn);
Необходимые расширения
Конкретную реализацию JAVA не следует рассматривать как готовое к использованию решение сложных задач классификации текста. Вот некоторые из важных расширений, которые можно было бы сделать:
1. Извлечение ключевых слов:
Хотя для простых задач, таких как определение языка, может быть достаточно использования отдельных ключевых слов, другие более сложные задачи требуют извлечения n-грамм. Таким образом, можно либо реализовать более сложный алгоритм извлечения текста, обновив метод TextTokenizer.extractKeywords(), либо использовать метод Datumbox. API извлечения ключевых слов чтобы получить все n-граммы (комбинации ключевых слов) документа.
2. Предварительная обработка текста:
Перед использованием классификатора обычно необходимо предварительно обработать документ, чтобы удалить ненужные символы/части. Несмотря на то, что текущая реализация выполняет ограниченную предварительную обработку с помощью метода TextTokenizer.preprocess(), когда дело доходит до анализа HTML-страниц, все становится сложнее. Можно просто обрезать HTML-теги и оставить только простой текст документа или прибегнуть к более сложным методам машинного обучения, которые обнаруживают основной текст страницы и удаляют контент, принадлежащий нижнему колонтитулу, заголовкам, меню и т. д. В дальнейшем вы можно использовать Datumbox API извлечения текста функция.
3. Дополнительные наивные байесовские модели:
Текущий классификатор реализует мультиномиальный наивный байесовский классификатор, однако, как мы обсуждали в предыдущей статье об анализе настроений, для разных задач классификации требуются разные модели. В некоторых случаях бинаризованная версия алгоритма будет более подходящей, в то время как в других модель Бернулли даст гораздо лучшие результаты. Используйте эту реализацию в качестве отправной точки и следуйте инструкциям Учебника по наивному байесовскому методу, чтобы расширить модель.
4. Методы выбора дополнительных функций:
В этой реализации используется алгоритм выбора признаков Chisquare для выбора наиболее подходящих признаков для классификации. Как мы видели в предыдущей статье, метод выбора признаков Chisquare — это хороший метод, который опирается на статистику для выбора подходящих признаков, тем не менее, он имеет тенденцию давать более высокие оценки для редких признаков, которые появляются только в одной из категорий. Улучшения можно внести, удалив зашумленные/редкие функции, прежде чем переходить к выбору функций, или внедрив дополнительные методы, такие как взаимная информация, которую мы обсуждали в вышеупомянутой статье.
5. Оптимизация производительности:
В конкретной реализации было важно улучшить читаемость кода, а не выполнять микрооптимизацию кода. Несмотря на то, что такие оптимизации делают код более уродливым и трудным для чтения/сопровождения, они часто необходимы, поскольку многие циклы в этом алгоритме выполняются миллионы раз при обучении и тестировании. Эта реализация может стать отличной отправной точкой для разработки вашей собственной настроенной версии.
Почти готово… Заключительные заметки!
Чтобы получить хорошее представление о том, как работает эта реализация, вам настоятельно рекомендуется прочитать две предыдущие статьи о наивном байесовском классификаторе и выборе функций. Вы получите представление о теоретических основах методов, и это сделает части алгоритма/кода более понятными.
Следует отметить, что наивный байесовский метод, несмотря на то, что он простой, быстрый и в большинстве случаев «достаточно точный», также является «наивным», поскольку делает предположение об условной независимости признаков. Поскольку это предположение почти никогда не встречается в задачах классификации текстов, наивный байесовский классификатор почти никогда не является лучшим классификатором. В API базы данных, некоторые расширения стандартного наивного байесовского классификатора используются только для простых задач, таких как определение языка. Для более сложных задач классификации текста необходимы более продвинутые методы, такие как классификатор Max Entropy.
Если вы используете реализацию в интересном проекте Напишите нам и мы опубликуем ваш проект в нашем блоге. Также, если вам понравилась статья, пожалуйста, найдите минутку и поделитесь ею в Twitter или Facebook. 🙂