Pull to refresh

Как я решила попробовать себя в ML: анализ эмоциональной окраски отзывов с Кинопоиска 2.0

Level of difficultyEasy
Reading time4 min
Views2.6K

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

Итак, в самом начале у меня был только датасет и опорный план для дальнейшей реализации всего этого дела, приступим :)

Шаг 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) для классификации отзывов на положительные, отрицательные и нейтральные.

Подведём итоги :)

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


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

Cсылочки: GitHub, Telegram

Tags:
Hubs:
+7
Comments2

Articles