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

Не стесняйтесь опробовать его здесь.

О модели и данных

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

Использованные данные представляют собой корпус из 5000 обзоров фильмов - 2500 положительных и 2500 отрицательных. Модель имеет точность ~ 90% и, вероятно, лучше работает с текстом, аналогичным обзору, потому что ей больше нравятся данные обучения. Более подробное обсуждение данных можно найти здесь.

import pandas as pd
data = pd.read_csv('resources/Reviews.csv')
print("Number of positive and negative reviews", '\n', data["sentiment"].value_counts())
test_data.head()
...
Number of positive and negative reviews 
1    25000
0    25000
      
                                           review sentiment
My family and I normally do not watch local mo...         1
Believe it or not, this was at one time the wo...         0
After some internet surfing, I found the "Home...          0
One of the most unheralded great works of anim...         1
It was the Sixties, and anyone with long hair ...         0

Обработка текстовых данных

Сначала я разделил данные на тестовую последовательность 70/30, а затем векторизовал текст обзора. Векторизация означает преобразование текста в стандартизованный формат, который может обрабатывать модель. Это необходимо сделать для обучающих данных и любых новых входных данных, поэтому позже они будут использоваться в облачной функции. Я использовал векторизатор TFIDF от sklearn, инициализированный стандартными настройками векторизатора TFIDF.

from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
x_train, x_test, y_train, y_test = train_test_split(
    test_data["review"],
    test_data["sentiment"],
    test_size=0.3,
    random_state=42
)
vectorizer = TfidfVectorizer(max_df=0.9, min_df=0.0005,
    ngram_range=(1,2)).fit(x_train)

Раньше я пробовал предварительно обработать данные вручную перед их загрузкой в ​​TFID Vectorizor, это повлекло за собой удаление стоп-слов, знаков препинания, контрактов и применение лемматизации. Но этот дополнительный шаг не привел к более высокой точности - вероятно, потому, что векторизатор имеет аналогичные встроенные шаги предварительной обработки. С тех пор я удалил свою настраиваемую предварительную обработку.

Обучение модели

Следующим шагом было приспособление модели к обучающим данным. Для приведенных тестовых данных эта модель достигла точности ~ 90%.

from sklearn.linear_model import LogisticRegression
x_train = vectorizer.transform(x_train)
x_test = vectorizer.transform(x_test)
model = LogisticRegression(solver='lbfgs')
model.fit(x_train, y_train)

Код для обучения модели можно найти ЗДЕСЬ.

Развертывание этой модели машинного обучения в облачной функции Google

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

Сохранение предварительно обученной модели и векторизатора

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

После обучения модели и подгонки векторизатора к заданным данным я сериализовал их с помощью библиотеки pickle.

pickle.dump(model,
    open('serialized/trained_model.sav', 'wb'))
pickle.dump(vectorizer, 
    open('serialized/trained_vectorizer.sav', 'wb'))

Распаковка модели и векторизатора в Google Cloud

Для функции Google Cloud я создал корзину Google Storage, в которую загружаю файлы training_model.sav и training_vectorizer.sav. В облачной функции я добавляю эти имена файлов и имя сегмента как переменные среды.

BUCKET = os.environ['BUCKET']
VECTORIZER_FILENAME = os.environ['VECTORIZER_FILENAME']
MODEL_FILENAME = os.environ['MODEL_FILENAME']

Затем я подключаюсь к корзине с помощью библиотеки хранилища Google Cloud.

from google.cloud import storage
client = storage.Client()
bucket = client.get_bucket(BUCKET)

Теперь, когда я подключился к ведру, я могу загрузить сериализованную модель и вектор и десериализовать их с помощью pickle (та же библиотека, что использовалась ранее).

vectorizer_blob = bucket.get_blob(VECTORIZER_FILENAME)
model_blob = bucket.get_blob(MODEL_FILENAME)
vectorizer = pickle.loads(vectorizer_blob.download_as_string())
model = pickle.loads(model_blob.download_as_string())

На этом этапе модель и векторизатор готовы к использованию в обычном режиме.

vectorized_text = vectorizer.transform([input])
result = model.predict_proba(vectorized_text)

Распаковка векторизатора и модели - самые тяжелые операции в этом процессе, в особенности векторизатор, потому что его сериализованная форма составляет около 43 МБ, а модель - 483 КБ. Вероятно, это связано с тем, что векторизатор сохраняет каждое слово в обучающих данных, чтобы сопоставить его с вектором. Для этой функции Google Cloud мне пришлось выделить 512 МБ данных, и выполнение запроса может занять до 10 секунд.

Код функции можно найти ЗДЕСЬ.