Пишем простой классификатор текста на Python

Kate

Administrator
Команда форума
Многие хотят написать простой классификатор текста, но теряются в тоннах книг по машинному обучению, и сложных математических формулах. Сегодня я покажу вам относительно простой пример классификации на Python, который работает просто и понятно.

В общем случае схема работы машинного обучения такова:

  1. Создают программу используя специальные библиотеки
  2. Обучают программу на большом наборе данных, то есть дают ей набор данных, правильно размеченный человеком, чтобы программа обучилась и начала работать на других похожих наборах данных
  3. Сохраняют и используют обученную модель
Я в своем примере совместил обучение программы вместе с ее тестированием, поэтому при каждом запуске она сперва обучается (что занимает некоторое время, не думайте что программа зависла).

К тому же в моем примере я буду использовать очень маленький набор данных, в реальных проектах набор данных должен быть минимум из нескольких тысяч строк.

Итак, мы создадим программу которая пытается угадать какой тип контента нужно найти для пользователя, в ответ на его вопрос. Например, если юзер спросит "Кто такой Виктор Цой", программа должна ответить "Информация о личности". Она не будет отвечать на вопрос, просто классифицирует вопрос в определенную категорию. Обучающий набор данных очень маленький поэтому тестировать будем на более-менее похожих вопросах.

Создаём набор данных для обучения​

Сперва создадим набор данных для обучения. У меня это обычный текстовый файл в котором лежат строки, разделенные значком @. Назовите файл model.txt и киньте рядом со скриптом. Используйте кодировку UTF-8.

Что такое патока @ Информация о предмете
Где живут медведи @ Местоположение
Почему небо голубое @ Информация о предмете
Как сварить борщ @ Инструкция
Как научиться летать @ Инструкция
Как рано просыпаться @ Инструкция
Как обрести счастье @ Инструкция
Как убить таракана @ Инструкция
Сколько звезд на небе @ Количество
Какая высота у Эйфелевой башни @ Количество
Почему идет дождь @ Информация о предмете
В каких фильмах играл Ди Каприо @ Информация о предмете
Когда родился Эйнштейн @ Дата рождения
Когда началась Первая мировая война @ Дата
В каком году был построен Титаник @ Дата
Когда начал править Иван IV @ Дата
Когда была битва под Аустерлицем @ Дата
В каких годах была «Семилетняя война» @ Дата
Когда начал править Наполеон Бонапарт @ Дата
Когда закончилось правление Наполеона Бонапарта @ Дата
В каких годах правил князь Святослав @ Дата
В каком году умер Ярослав Мудрый @ Дата
В каком году появляется первое упоминание о Москве @ Дата
В каком году был основан Санкт-Петербург @ Дата
Когда было Ледовое побоище @ Дата
Когда была Куликовская битва @ Дата
В каком году начали печатать книги на Руси @ Дата
Когда была Полтавская битва @ Дата
В каком году закончилась Первая мировая война @ Дата
В каком году был заключен Тильзитский мир @ Дата
В каком году были написаны «Отцы и дети» @ Дата
Когда отмечается День Учителя @ Дата
Когда отмечается День Матери @ Дата
Когда отменили крепостное право @ Дата
Что произошло 12 июня 1812 @ Дата
Что произошло 20 ноября 1805 @ Дата
Что произошло 6 июня 1799 @ Дата
Что произошло 1 апреля 1809 @ Дата
Какой город начинает упоминатся с 1147 грода @ Дата
Кто такой Эйнштейн @ Информация о личности
Что такое «дождь» @ Информация о предмете
Кто основал Санкт-Петербург @ Имя
Кто такой Христофор Колумб @ Информация о личности
Как звали Колумба @ Имя
Кто написал произведение «Преступление и наказание» @ Имя
Кто написал стихотворение «Тройка» @ Имя
Какова средняя глубина Тихого океана @ Количество
Какова высота Биг Бена @ Количество
Где находится Сиднейская Опера @ Местоположение
Где находится самое большое озеро @ Местоположение
В какой стране столицей является город Москва @ Местоположение

Установка необходимых библиотек​

Нам понадобится библиотека PyStemmer. Установить её можно так

pip3 install pystemmer

Пишем программу​

Теперь покажу сам скрипт для классификации вопросов.

import sys
import numpy as np
import pickle
import re
from Stemmer import Stemmer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score

# очистка текста с помощью regexp приведение слов в инфинитив и нижний регистр, замена цифр

def text_cleaner(text):
text = text.lower() # приведение в lowercase
stemmer = Stemmer('russian')
text = ' '.join( stemmer.stemWords( text.split() ) )
text = re.sub( r'\b\d+\b', ' digit ', text ) # замена цифр
return text


# загрузка данных из файла model.txt

def load_data():
data = {'text':[],'tag':[]}
for line in open('model.txt'):
if not('#' in line):
row = line.split("@")
data['text'] += [row[0]]
data['tag'] += [row[1]]
return data

# Обучение

def train_test_split(data, validation_split = 0.1):
sz = len(data['text'])
indices = np.arange(sz)
np.random.shuffle(indices)

X = [data['text'] for i in indices]
Y = [data['tag'] for i in indices]
nb_validation_samples = int( validation_split * sz )

return {
'train': {'x': X[:-nb_validation_samples], 'y': Y[:-nb_validation_samples]},
'test': {'x': X[-nb_validation_samples:], 'y': Y[-nb_validation_samples:]}
}


# - - - -

def openai():
data = load_data()
D = train_test_split(data)
text_clf = Pipeline([
('tfidf', TfidfVectorizer()),
('clf', SGDClassifier(loss='hinge')),
])
text_clf.fit(D['train']['x'], D['train']['y'])
predicted = text_clf.predict( D['train']['x'] )

# Начало тестирования программы

z = input("Введите вопрос без знака вопроса на конце: ")
zz = []
zz.append(z)
predicted = text_clf.predict(zz)
print(predicted[0])

# - - - -
if __name__ == '__main__':
sys.exit(openai())

Давайте запустим нашу программу, подождем пока она обучится (пару минут) и предложит нам ввести вопрос. Введем вопрос которого нет в обучающем файле - "Кто придумал ракету". Писать нужно без знака вопроса на конце. В ответ программа выдаст "Имя", значит она определила что наш вопрос подразумевает ответ в котором должно быть чье-то имя. Заметьте, данного вопроса не было в файле model.txt но программа безошибочно определила что мы имеем ввиду, исходя из обучающей выборки.

Данный классификатор очень прост. Вы можете подать на вход в файл model.txt абсолютно любые данные которые нужно классифицировать, это не обязательно должны быть вопросы и их категории как в моем примере.

 
Сверху