В этой короткой статье вы найдете базовый код для обучения модели классификации текста. Эта статья содержит только самый минимум кода, с которого можно начать - никаких сложных запутывающих приемов!
Чего мы надеемся достичь
Мы хотим построить и обучить модель, которая может предсказать, имеет ли предложение положительные или отрицательные эмоции. Например, «Это ужасно, и я разочарован» следует прогнозировать как отрицательный, а «Я вполне доволен этим» - как положительный.
Обзор: шаги к классификации
- Получение набора данных с помеченными настроениями
- Установка соответствующих библиотек
- Чтение набора данных с помощью Pandas
- Разделение переменных X (предиктор) и Y (цель)
- Преобразование текста в векторы с помощью Sklearn TfidfVectorizer
- Создание и обучение нашей модели классификации
- Оценка нашей модели
Дополнительные шаги
- Сохранение модели с помощью pickle
- Экспериментируем с разными гиперпараметрами в 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. Если вы зарегистрируетесь по моей ссылке, я получу небольшую комиссию.