Используем DS для обработки отзывов клиентов с крупных сайтов

от автора

В кейсе мы использовали библиотеки языка Python, такие как: Selenium, BeautifulSoup. Получилось около 27 тысяч отзывов, начиная с 2018 года. В среднем каждый отзыв занимал 2 абзаца листа А4. В 70 % отзывов была проставлена оценка клиентами, в оставшихся 30% — оценка не была проставлена. Полученные данные, у которых были проставлены оценки, мы решили использовать как исходные данные для построения модели обучения с учителем. Модель в дальнейшем нам нужна была, чтобы определить оценку у оставшихся 30% отзывов.

Проставленные оценки были от 1 до 5, но нам нужно было узнать, каким отзыв являлся по качеству, т. е. положительный он или отрицательный. Использовали логику школьных оценок в России: оценки 1,2 — отрицательные, их преобразовали в 0; оценки 3,4,5 – положительные, их преобразовали в 1. Тем самым задача свелась к бинарной классификации.

dataframe.tail(5) 

Далее начали экспериментировать с моделью бинарной классификации.

Для первого прохода выбрали метод XGBoost для обучения с учителем. Учителем выступают оценки клиентов. В роли модели текста были взяты векторные представления слов Word2Vec, которые формируются в зависимости от контекста.

Предварительно провели предобработку текста, такую как: лемматизация, удаление стоп-слов, нормализация и его токенизация.

from nltk.tokenize import sent_tokenize from nltk.corpus import stopwords from nltk.tokenize import word_tokenize
def tokenize_ru(x):       tokens = x.lower()        tokens = re.sub(r'[^\w\s]+|[\d]',' ',tokens)        tokens = word_tokenize(tokens)        tokens = [i for i in tokens if (i not in string.punctuation)]        stop_words = stopwords.words('russian')        stop_words.extend(['что', 'это', 'так', 'вот', 'быть', 'как', 'в', '—', '–', 'к', 'на', '...'])        tokens = [i for i in tokens if (i not in stop_words)]        tokens = [i.replace("«", "").replace("»", "") for i in tokens]        return tokens

Перебирали лучшие параметры, используя метод GridSearch.

Оптимальные параметры по точности получились при глубине деревьев 8 (max_depth=8) и количество деревьев (n_estimators=88). По умолчанию в библиотеке XGBoost установлено: n_estimators=100, max_depth=3.

xgb_word2vec = Pipeline([               ("word2vec", MeanVect(w2v)),                ('model_fitting',  xgb)])   xgb_word2vec.fit(X_train2, y_train2)

для данных условий Confusion matrix (Матрица Путаницы) следующая:

import seaborn as sns import matplotlib.pylab as plt %matplotlib inline from matplotlib.pylab import rcParams rcParams['figure.figsize'] = 3, 3 plt.figure(figsize=(2,2)) sns.set(font_scale=1.5) ax = sns.heatmap((pd.crosstab(y_test2, pred2).apply(lambda r: r/r.sum()*100, axis=0)), cbar=None, annot=True, cmap="Blues") ax.set_ylabel("") ax.set_xlabel("") plt.yticks(rotation=0, size = 15) plt.xticks(rotation=0, size = 15) 

Далее пробовали использовать SGDClassifier и для векторов слов TF-IDF.

Ниже приведены различные сочетания вариантов и их Confusion matrix:

1. SGDClassifier + Word2Vec

2. SGDClassifier+ TF-IDF

3. XGBoost+ TF-IDF

Рассчитывается f-mera по формуле f-mera = 2*Precision*Recall/(Precision+Recall), где Precision(точность) и Recall(полнота) вычисляются из Confusion matrix, это гармоническое среднее между точностью и полнотой, для бинарной классификации этого вполне достаточно для оценки точности модели. Лучший результат получился при сочетании SGDClassifier + TF-IDF.

Далее, в уже выбранную модель, с лучшей точностью, подставили неактуальные оцененные отзывы, начиная с 2016 по 2018 годы, которые не участвовали в обучении, чтобы проверить правильность обучения и работы модели, в результате получили f-mera: 0.9326314212969897. Эту модель в дальнейшем можно использовать для классификации отзывов, чтобы не тратить время на поиск вручную отрицательных отзывов.

precision_recall_fscore_support(y_prov, predtest, average='macro')

Дальше использовали модель для оценки оставшихся не оцененных 30 процентов отзывов.
Вывод: Для обработки естественного языка (NLP) из нашего опыта, описанного выше, результаты лучше показала связка быстро сходящегося SGDClassifier с TF-IDF, но в свою очередь ключевая часть успеха лежит в предобработке данных.

ссылка на оригинал статьи https://habr.com/ru/post/507238/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *