Недавно я решила попробовать реализовать задачу анализа эмоциональной окраски отзывов с Кинопоиска. Я бы хотела поделиться своим опытом и описать шаги, которые использовала для реализации стоящей передо мною задачей.
Итак, в самом начале у меня был только датасет и опорный план для дальнейшей реализации всего этого дела, приступим :)
Шаг 1: получение данных | main.py + reviews_data.zip
Скачиваем json-файлы с отзывами и затем читаем данные из файла. Добавляем полученные отзывы в общий список.
import json
with open("reviews_data.json", "r") as read_file:
load_reviews = json.load(read_file)
reviews = []
reviews += load_reviews['good']
reviews += load_reviews['bad']
reviews += load_reviews['neutral']
Шаг 2: предобработка данных | Preprocessing.py
На этом этапе удаляем все ненужные символы, такие как цифры, знаки препинания и английские буквы.
import re
from nltk.corpus import stopwords
def delete_symbols(review):
new_review = []
for word in review:
reg_sumbols = re.sub('[^\w\s]+|[\d]+', ' ', word)
reg_eng_symbols = re.sub('[a-zA-Z\s]+', ' ', reg_sumbols)
new_review.append(reg_eng_symbols.split())
return new_review
delete_symbols(review)
: функция удаляет ненужные символы из текстовых данных, включая неалфавитно-цифровые символы и цифры. Она возвращает список слов, которые были разделены из исходного отзыва.
Дальше используем библиотеку NLTK для удаления стоп-слов из текста. Это поможет получить более точные результаты анализа.
def delete_stop_words(review_words):
stop_words = list(stopwords.words('russian'))
deleted_stop_words = []
for w in review_words:
word = w.lower()
if word not in stop_words and word != "\n":
deleted_stop_words.append(word)
return deleted_stop_words
delete_stop_words(review_words)
: функция удаляет стоп-слова из списка слов, переданного ей. Стоп-слова - это распространенные слова в языке (такие как "и", "в", "на" и т.д.), которые не несут много смысла и обычно удаляются из текстовых данных. Эта функция использует модуль stopwords
из Natural Language Toolkit (NLTK), чтобы получить список стоп-слов для русского языка.
Приводим все слова в отзывах к нижнему регистру.
def lower_review(review_words):
lower_reviews = []
for rev in review_words:
deleted_stop_words = delete_stop_words(rev)
lower_reviews.append(deleted_stop_words)
return lower_reviews
lower_review(review_words)
: функция приводит все слова в текстовых данных к нижнему регистру. Это делается, чтобы гарантировать, что слова, которые появляются в разных регистрах, рассматриваются как одно и то же слово. Функция берет список слов, который был обработан функцией delete_stop_words()
, и возвращает список списков, где каждый внутренний список содержит слова одного отзыва в нижнем регистре.
Шаг 3: векторизация | Vectorization.py
Преобразовываем полученные слова в векторы при помощи модели FastText.
import json
import fasttext
ft = fasttext.load_model('cc.ru.300.bin')
def get_vector(review):
sentence = "".join(s + " " for s in review)
sentence_vector = ft.get_sentence_vector(sentence)
return sentence_vector
Функция get_vector(review)
использует модель fasttext
для получения векторного представления отзыва. Поочередно происходит векторизация отзывов из списков good
, bad
и neutral
в файле reviews_data.json
. Векторизованные отзывы записываются в новый файл vectorized.json
.
def vectorization_reviews(lower_reviews):
with open("reviews_data.json", "r") as read_file:
reviews = json.load(read_file)
for i in range(1000):
reviews['good'][i] = get_vector(lower_reviews[i]).tolist()
for i in range(1000):
reviews['bad'][i] = get_vector(lower_reviews[i + 1000]).tolist()
for i in range(1000):
reviews['neutral'][i] = get_vector(lower_reviews[i + 2000]).tolist()
with open('vectorized.json', 'w') as outfile:
json.dump(reviews, outfile)
Функция vectorization_reviews(lower_reviews)
вызывает функцию get_vector(review)
и производит векторизацию всех отзывов.
Шаг 4: KDTree | KDTree_vec.py
Используем KDTree(K-d-дерево) для нахождения наиболее похожих отзывов на введенный пользователем отзыв.
from scipy import spatial
def find_similar(vec_reviews, user_review):
treee = spatial.KDTree(vec_reviews)
similar_review = treee.query(user_review, 10)
print()
return similar_review[1]
Функция find_similar
, использует библиотеку scipy
для поиска наиболее похожих векторов на заданный вектор.
vec_reviews
: матрица векторов отзывовuser_review
: вектор, который нужно найти в матрице
Для этого функция создает объект KDTree
из библиотеки scipy
. Затем функция использует метод query
, чтобы найти 10 наиболее похожих векторов на заданный вектор. Результатом работы функции является массив индексов 10 наиболее похожих векторов в матрице vec_reviews
.
Шаг 5: завершение | main
Используем классификационную модель, чтобы определить эмоциональную окраску полученных отзывов. Работаем с методом опорных векторов (SVM) для классификации отзывов на положительные, отрицательные и нейтральные.
Подведём итоги :)
В процессе написания данной статьи мы рассмотрели шаги для реализации анализа эмоциональной окраски отзывов с помощью методов машинного обучения. Мы использовали библиотеки для предобработки текста, векторизации и поиска ближайших соседей.
Надеюсь, что материал был полезен и поможет Вам создать собственный анализатор эмоциональной окраски текстов.