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

Чего мы надеемся достичь

Мы хотим построить и обучить модель, которая может предсказать, имеет ли предложение положительные или отрицательные эмоции. Например, «Это ужасно, и я разочарован» следует прогнозировать как отрицательный, а «Я вполне доволен этим» - как положительный.

Обзор: шаги к классификации

  1. Получение набора данных с помеченными настроениями
  2. Установка соответствующих библиотек
  3. Чтение набора данных с помощью Pandas
  4. Разделение переменных X (предиктор) и Y (цель)
  5. Преобразование текста в векторы с помощью Sklearn TfidfVectorizer
  6. Создание и обучение нашей модели классификации
  7. Оценка нашей модели

Дополнительные шаги

  1. Сохранение модели с помощью pickle
  2. Экспериментируем с разными гиперпараметрами в TfidfVectorizer

Набор данных

Давайте воспользуемся простым и небольшим набором данных с пометкой по тональности - sentiment.csv. Здесь 0 означает негативное настроение, а 1 означает позитивное настроение.

Https://www.kaggle.com/zlliu246/simple-sentiment-analysis-reviews

Установка соответствующих библиотек

Введите это в свою командную строку / терминал, чтобы установить соответствующие библиотеки обработки данных и машинного обучения Python:

pip install numpy pandas sklearn
# MacOS users: replace 'pip' with 'pip3'

Я рекомендую использовать Jupyterlab для анализа данных любого типа, поскольку он избавляет нас от необходимости запускать один и тот же код снова и снова.

pip install jupyterlab
python -m jupyterlab
# this will open jupyterlab on your web browser

Чтение набора данных с помощью Pandas

import numpy as np
import pandas as pd
data = pd.read_csv("sentiment.csv")

Во-первых, нам нужно прочитать и загрузить sentiment.csv с помощью pandas. Переменная data теперь является объектом DataFrame pandas - вы можете думать о DataFrames как о двухмерной таблице, содержащей множество строк и столбцов данных.

Вот как выглядят наши данные DataFrame:

Разделение переменных X (предиктор) и Y (цель)

Для нашей модели предполагаемым входом будет связка документов, а предполагаемым выходом - список прогнозов настроений для каждого документа. Таким образом, нам нужно сначала разделить переменные X (предиктор) и переменные Y (целевые).

y = data["sentiment"]
xraw = data["review"]

Преобразование текста в векторы с помощью Sklearn TfidfVectorizer

На данный момент xraw содержит список строк документа. Наши модели машинного обучения не могут понять эти необработанные строки, поэтому сначала нам нужно преобразовать каждую строку в вектор. Вы можете думать о векторе как о списке чисел, которые компьютер может лучше понять.

Чтобы преобразовать необработанные документы в векторы, мы можем использовать TfidfVectorizer Sklearn.

from sklearn.feature_extraction.text import TfidfVectorizer
vec = TfidfVectorizer()
x = vec.fit_transform(xraw)

В настоящее время x - это разреженный вектор, который наша модель может не понять. Таким образом, нам нужно преобразовать его в обычный массив, чтобы наши модели могли их обрабатывать.

x = x.toarray()

Создание и обучение нашей модели классификации

На данный момент x содержит список векторов (одинаковой длины), и мы можем рассматривать x и y как обычные наборы данных машинного обучения. Во-первых, мы делаем простой тестовый разделитель, чтобы разделить x и y на данные обучения и тестирования.

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y)

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

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(x_train, y_train)

Мы можем просто импортировать класс LogisticRegression из sklearn, инициализировать его и использовать функцию fit для обучения нашей модели на x_train & y_train.

Оценка нашей модели

Чтобы проверить, насколько точна наша модель, мы передаем ей данные, которых она раньше не видела (x_test и y_test), и проверяем точность ее прогнозов. Мы можем сделать это, просто используя функцию model.score здесь:

score = model.score(x_test, y_test)
print(score)

Он возвращает точность 84,4%, что довольно неплохо, учитывая, что мы не выполняли дополнительную предварительную обработку данных! Мы можем проверить это дальше, введя наши собственные тестовые примеры. Обратите внимание, что сначала нам нужно преобразовать его в векторы, используя наш существующий объект TfidfVectorizer vec.

test = [
    "This is terrible and I am disappointed",
    "I am quite happy with this",
    "Never going to buy from this store ever again",
    "Works pretty well and functions as it should",
    "meh"
]
x_test = vec.transform(test)
predictions = model.predict(x_test.toarray())

Как мы видим здесь, настроения, предсказанные нашей моделью, в некоторой степени довольно точны!

Весь код в одном месте

Вот весь код в одном месте для вашего удобства.

import numpy as np
import pandas as pd
data = pd.read_csv("sentiment.csv")
y = data["sentiment"]
xraw = data["review"]
from sklearn.feature_extraction.text import TfidfVectorizer
vec = TfidfVectorizer()
x = vec.fit_transform(xraw)
x = x.toarray()
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(x_train, y_train)
score = model.score(x_test, y_test)
print(score)
test = [
    "This is terrible and I am disappointed",
    "I am quite happy with this",
    "Never going to buy from this store ever again",
    "Works pretty well and functions as it should",
    "meh"
]
x_test = vec.transform(test)
predictions = model.predict(x_test.toarray())
print(predictions)

Дополнительный шаг 1: Сохранение нашей модели (и векторизатора) с помощью Pickle

Pickle позволяет нам сохранять объекты Python в файлах. sav, чтобы мы могли загружать и использовать их где-нибудь еще. Если по какой-либо причине мы захотим повторно использовать эту обученную модель в другом месте, мы можем сохранить ее с помощью библиотеки pickle.

import pickle
pickle.dump((vec, model), open("filename.sav", "wb"))

Примечание: нам нужно сохранить как наш объект TfidfVectorizer, так и нашу модель, так как нам нужно, чтобы наш векторизатор сначала преобразовал текстовые данные в векторы, прежде чем они могут быть загружены в нашу модель.

Этот код ниже демонстрирует, как читать и загружать существующий файл .sav.

import pickle
vec, model = pickle.load(open("filename.sav", "rb"))

На этом этапе мы можем использовать сохраненные объекты vec и model, как обычно.

Дополнительный шаг 2: экспериментирование с различными гиперпараметрами в TfidfVectorizer

Ранее мы просто инициализировали класс TfidfVectorizer, не передавая никаких аргументов.

vec = TfidfVectorizer()

Однако поведение нашего векторизатора может варьироваться в зависимости от аргументов, которые мы передаем - иногда это улучшает нашу точность! Это может выглядеть примерно так:

vec = TfidfVectorizer(max_features=10000, stop_words="english")

max_features

Когда мы имеем дело с наборами текстовых данных немного большего размера, количество уникальных слов (функций) огромно и может составлять сотни или тысячи функций, что потенциально замедляет работу нашей программы. Аргумент max_features здесь заставляет TfidfVectorizer включать только верхние слова x, которые появляются во всех текстах, игнорируя те, которые находятся после, таким образом, возвращая нам меньший массив, который проще и быстрее тренировать.

stop_words

Стоп-слова - это общие слова, которые не добавляют особого значения, например «я», «я», «на», «к» и т. Д. Если мы добавим этот аргумент, наш TfidfVectorizer будет игнорировать стоп-слова.

ngram_range

Допустим, у нас есть предложение:

Быстрая коричневая лиса прыгает через ленивую собаку

Униграммы (1 грамм): «The», «quick», «brown», «fox» и так далее.

Биграммы (2 грамма) будут («The», «quick»), («quick», «коричневые»), («коричневые», «Лиса») и так далее.

Триграммы (3 грамма) будут («Быстрый», «коричневый»), («быстрый», «коричневый», «лисий»), («коричневый», «лиса», «прыгает») и так далее.

Включение нграмм в наш анализ текста часто дает нам дополнительное представление о тексте, поскольку позволяет нам захватывать группы слов и, следовательно, больше контекста. Включение аргумента ngram_range позволяет нашему TfidfVectorizer также вычислять nграммы в зависимости от того, какое значение n мы выберем.

Если мы установим наш ngram_range как (1,2), наш TfidfVectorizer будет включать 1 грамм и 2 грамма. Если мы установим наш ngram_range как (1,3), наш TfidfVectorizer будет включать в себя 1, 2 и 3 грамма.

Ссылка на документацию Sklearn



Есть еще много аргументов, с которыми вы можете поэкспериментировать, и их можно найти в документации по sklearn.

Вывод

Надеюсь, это помогло познакомить вас с миром классификации текстов и анализа тональности!

Если это принесло вам пользу, и вы хотите поддержать меня как писателя, рассмотрите возможность подписки на Medium-членство! Это 5 долларов в месяц, и вы получаете неограниченный доступ к историям на Medium. Если вы зарегистрируетесь по моей ссылке, я получу небольшую комиссию.

Вот ссылка на неограниченный доступ к каналу