Многие хотят написать простой классификатор текста, но теряются в тоннах книг по машинному обучению, и сложных математических формулах. Сегодня я покажу вам относительно простой пример классификации на Python, который работает просто и понятно.
В общем случае схема работы машинного обучения такова:
Создают программу используя специальные библиотеки
Обучают программу на большом наборе данных, то есть дают ей набор данных, правильно размеченный человеком, чтобы программа обучилась и начала работать на других похожих наборах данных
Сохраняют и используют обученную модель
Я в своем примере совместил обучение программы вместе с ее тестированием, поэтому при каждом запуске она сперва обучается (что занимает некоторое время, не думайте что программа зависла).
К тому же в моем примере я буду использовать очень маленький набор данных, в реальных проектах набор данных должен быть минимум из нескольких тысяч строк.
Итак, мы создадим программу которая пытается угадать какой тип контента нужно найти для пользователя, в ответ на его вопрос. Например, если юзер спросит "Кто такой Виктор Цой", программа должна ответить "Информация о личности". Она не будет отвечать на вопрос, просто классифицирует вопрос в определенную категорию. Обучающий набор данных очень маленький поэтому тестировать будем на более-менее похожих вопросах.
Создаём набор данных для обучения
Сперва создадим набор данных для обучения. У меня это обычный текстовый файл в котором лежат строки, разделенные значком @. Назовите файл 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'][i] for i in indices]
Y = [data['tag'][i] 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 абсолютно любые данные которые нужно классифицировать, это не обязательно должны быть вопросы и их категории как в моем примере.