Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

15.1 Анализ тональности и набор данных

С быстрым развитием социальных сетей и платформ отзывов накапливается огромное количество отзывов. Эти данные обладают большим потенциалом для поддержки принятия решений. Анализ тональности (sentiment analysis) изучает «скрытые» в тексте настроения людей — в отзывах о товарах, комментариях в блогах, обсуждениях на форумах и т. д. Он широко применяется в политике (например, анализ отношения общества к государственным решениям), финансах (например, анализ рыночных настроений) и маркетинге (например, исследование продуктов и управление брендом).

Поскольку тональность можно классифицировать по дискретным полярностям или шкалам (например, положительная и отрицательная), анализ тональности можно рассматривать как задачу классификации текстов, которая преобразует текстовую последовательность переменной длины в категорию текста фиксированной длины. В этом разделе мы будем использовать для анализа тональности большой набор данных рецензий на фильмы (large movie review dataset) Стэнфордского университета. Он состоит из обучающей и тестовой частей и содержит по 25 000 рецензий на фильмы, загруженных с IMDb. В обеих частях поровну «положительных» и «отрицательных» меток, обозначающих разные полярности тональности.

MXNet:

from d2l import mxnet as d2l
from mxnet import np, npx
import os
npx.set_np()

PyTorch:

from d2l import torch as d2l
import torch
from torch import nn
import os

PaddlePaddle:

from d2l import paddle as d2l
import warnings
warnings.filterwarnings("ignore")
import paddle
from paddle import nn
import os

15.1.1 Чтение набора данных

Сначала скачаем и распакуем набор данных рецензий IMDb в каталог ../data/aclImdb.

#@save
d2l.DATA_HUB['aclImdb'] = (
    'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz',
    '01ada507287d82875905620988597833ad4e0903')

data_dir = d2l.download_extract('aclImdb', 'aclImdb')

Затем прочитаем обучающий и тестовый наборы данных. Каждый пример — рецензия с меткой: 1 означает «положительная», 0 — «отрицательная».

#@save
def read_imdb(data_dir, is_train):
    """Читает текстовые последовательности и метки набора рецензий IMDb"""
    data, labels = [], []
    for label in ('pos', 'neg'):
        folder_name = os.path.join(data_dir, 'train' if is_train else 'test',
                                   label)
        for file in os.listdir(folder_name):
            with open(os.path.join(folder_name, file), 'rb') as f:
                review = f.read().decode('utf-8').replace('\n', '')
                data.append(review)
                labels.append(1 if label == 'pos' else 0)
    return data, labels

train_data = read_imdb(data_dir, is_train=True)
print('число обучающих примеров:', len(train_data[0]))
for x, y in zip(train_data[0][:3], train_data[1][:3]):
    print('метка:', y, 'рецензия:', x[0:60])

15.1.2 Предобработка набора данных

Считая каждое слово токеном и отфильтровывая слова, встречающиеся меньше 5 раз, создадим словарь по обучающему набору данных.

train_tokens = d2l.tokenize(train_data[0], token='word')
vocab = d2l.Vocab(train_tokens, min_freq=5, reserved_tokens=['<pad>'])

После токенизации построим гистограмму длин рецензий в токенах.

d2l.set_figsize()
d2l.plt.xlabel('# токенов в рецензии')
d2l.plt.ylabel('количество')
d2l.plt.hist([len(line) for line in train_tokens], bins=range(0, 1000, 50));

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

num_steps = 500  # Длина последовательности
train_features = d2l.tensor([d2l.truncate_pad(
    vocab[line], num_steps, vocab['<pad>']) for line in train_tokens])
print(train_features.shape)

15.1.3 Создание итераторов данных

Теперь можно создать итераторы данных. На каждой итерации возвращается минибатч примеров.

MXNet:

train_iter = d2l.load_array((train_features, train_data[1]), 64)

for X, y in train_iter:
    print('X:', X.shape, ', y:', y.shape)
    break
print('число минибатчей:', len(train_iter))

PyTorch:

train_iter = d2l.load_array((train_features, 
    torch.tensor(train_data[1])), 64)

for X, y in train_iter:
    print('X:', X.shape, ', y:', y.shape)
    break
print('число минибатчей:', len(train_iter))

PaddlePaddle:

train_iter = d2l.load_array((train_features,
    d2l.tensor(train_data[1])), 64)

for X, y in train_iter:
    print('X:', X.shape, ', y:', y.shape)
    break
print('число минибатчей:', len(train_iter))

15.1.4 Сборка кода

Наконец, мы упаковываем описанные шаги в функцию load_data_imdb. Она возвращает итераторы обучающих и тестовых данных и словарь набора рецензий IMDb.

MXNet:

#@save
def load_data_imdb(batch_size, num_steps=500):
    """Возвращает итераторы данных и словарь набора рецензий IMDb"""
    data_dir = d2l.download_extract('aclImdb', 'aclImdb')
    train_data = read_imdb(data_dir, True)
    test_data = read_imdb(data_dir, False)
    train_tokens = d2l.tokenize(train_data[0], token='word')
    test_tokens = d2l.tokenize(test_data[0], token='word')
    vocab = d2l.Vocab(train_tokens, min_freq=5)
    train_features = np.array([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in train_tokens])
    test_features = np.array([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in test_tokens])
    train_iter = d2l.load_array((train_features, train_data[1]), batch_size)
    test_iter = d2l.load_array((test_features, test_data[1]), batch_size,
                               is_train=False)
    return train_iter, test_iter, vocab

PyTorch:

#@save
def load_data_imdb(batch_size, num_steps=500):
    """Возвращает итераторы данных и словарь набора рецензий IMDb"""
    data_dir = d2l.download_extract('aclImdb', 'aclImdb')
    train_data = read_imdb(data_dir, True)
    test_data = read_imdb(data_dir, False)
    train_tokens = d2l.tokenize(train_data[0], token='word')
    test_tokens = d2l.tokenize(test_data[0], token='word')
    vocab = d2l.Vocab(train_tokens, min_freq=5)
    train_features = torch.tensor([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in train_tokens])
    test_features = torch.tensor([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in test_tokens])
    train_iter = d2l.load_array((train_features, torch.tensor(train_data[1])),
                                batch_size)
    test_iter = d2l.load_array((test_features, torch.tensor(test_data[1])),
                               batch_size,
                               is_train=False)
    return train_iter, test_iter, vocab

PaddlePaddle:

#@save
def load_data_imdb(batch_size, num_steps=500):
    """Возвращает итераторы данных и словарь набора рецензий IMDb"""
    data_dir = d2l.download_extract('aclImdb', 'aclImdb')
    train_data = read_imdb(data_dir, True)
    test_data = read_imdb(data_dir, False)
    train_tokens = d2l.tokenize(train_data[0], token='word')
    test_tokens = d2l.tokenize(test_data[0], token='word')
    vocab = d2l.Vocab(train_tokens, min_freq=5)
    train_features = d2l.tensor([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in train_tokens])
    test_features = d2l.tensor([d2l.truncate_pad(
        vocab[line], num_steps, vocab['<pad>']) for line in test_tokens])
    train_iter = d2l.load_array((train_features, d2l.tensor(train_data[1])),
                                batch_size)
    test_iter = d2l.load_array((test_features, d2l.tensor(test_data[1])),
                               batch_size,
                               is_train=False)
    return train_iter, test_iter, vocab

Резюме

  • Анализ тональности изучает настроения людей в тексте; он рассматривается как задача классификации текстов, преобразующая текстовую последовательность переменной длины в категорию текста фиксированной длины.
  • После предобработки с помощью словаря можно загрузить набор рецензий IMDb в итераторы данных.

Упражнения

  1. Какие гиперпараметры из этого раздела можно изменить, чтобы ускорить обучение модели анализа тональности?
  2. Реализуйте функцию загрузки набора данных отзывов Amazon в итераторы данных для анализа тональности.

MXNet: Обсуждение

PyTorch: Обсуждение

PaddlePaddle: Обсуждение