Skip to content

情感分析及数据集

一、什么是情感分析

情感分析就是研究文本里 “隐藏” 的情绪,比如我们看电影评论、产品评价的时候,想知道这个评论是好评还是差评,这就是情感分析要解决的问题。它属于文本分类任务,把可变长度的文本序列(比如一段评论)转换成固定的类别,比如 “积极” 或者 “消极”。

情感分析的应用场景很多:

  • 政治领域:分析公众对政策的情绪,了解大家对政策的支持度

  • 金融领域:分析市场情绪,判断股票市场的走势

  • 营销领域:分析用户对产品的评价,做产品研究和品牌管理

二、IMDb 电影评论数据集

我们用的是斯坦福大学的大型电影评论数据集(IMDb),这个数据集是从 IMDb 网站下载的电影评论,分成训练集和测试集,各有 25000 条评论,其中 “积极” 和 “消极” 的评论各占一半,刚好可以用来做二分类的情感分析任务。

三、读取数据集

首先我们需要下载并读取这个数据集,用 Python 代码实现:

python
import os
import d2l

# 下载并解压数据集
d2l.DATA_HUB['aclImdb'] = (
    'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz',
    '01ada507287d82875905620988597833ad4e0903'
)
data_dir = d2l.download_extract('aclImdb', 'aclImdb')

# 读取数据集的函数
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)
                # 给标签:积极是1,消极是0
                labels.append(1 if label == 'pos' else 0)
    return data, labels

# 读取训练集和测试集
train_data = read_imdb(data_dir, is_train=True)
test_data = read_imdb(data_dir, is_train=False)

# 查看训练集的数量和样例
print('训练集数目:', len(train_data[0]))
for x, y in zip(train_data[0][:3], train_data[1][:3]):
    print('标签:', y, '评论内容:', x[:60])

运行结果会显示:

Plain
训练集数目: 25000
标签: 1 评论内容: Zentropa has much in common with The Third Man, another noir
标签: 1 评论内容: Zentropa is the most original movie I've seen in years. If y
标签: 1 评论内容: Lars Von Trier is never backward in trying out new technique

四、预处理数据集

计算机没法直接处理文本,我们需要把文本转换成数字,这一步就是预处理:

1. 词元化

把每个评论拆成一个个单词,也就是 “词元化”:

python
# 把评论拆成单词
train_tokens = d2l.tokenize(train_data[0], token='word')

2. 创建词表

把所有出现的单词做成一个 “字典”,给每个单词一个编号,同时过滤掉出现次数少于 5 次的稀有单词,避免这些单词影响模型训练:

python
# 创建词表,过滤出现次数少于5次的单词
vocab = d2l.Vocab(train_tokens, min_freq=5, reserved_tokens=['<pad>'])

3. 处理评论长度

每个评论的长度不一样,有的短有的长,我们用直方图看看评论的长度分布:

python
d2l.set_figsize()
d2l.plt.xlabel('每条评论的词元数量')
d2l.plt.ylabel('评论数量')
d2l.plt.hist([len(line) for line in train_tokens], bins=range(0, 1000, 50))
d2l.plt.show()

从直方图可以看到,大部分评论的词元数量在 500 以内,所以我们把每个评论都截断或填充到 500 长度,这样每个评论的长度就一样了,方便后续训练:

python
import numpy as np

# 把每个评论截断或填充到500长度
train_features = np.array([d2l.truncate_pad(vocab[line], 500, vocab['<pad>']) for line in train_tokens])
test_features = np.array([d2l.truncate_pad(vocab[line], 500, vocab['<pad>']) for line in test_tokens])

五、创建数据迭代器

最后我们把预处理好的数据转换成小批量的迭代器,这样训练模型的时候可以一次处理一批数据,提高效率:

python
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

# 测试函数
train_iter, test_iter, vocab = load_data_imdb(batch_size=32)
print('词表大小:', len(vocab))
print('训练迭代器的一个批次形状:', next(iter(train_iter))[0].shape)

运行结果会显示词表大小(大概 4 万多),还有训练批次的形状是(32, 500),也就是每个批次 32 条评论,每条评论 500 个词元。

六、小结

  1. 情感分析是文本分类任务,把文本转换成积极 / 消极这样的固定类别,应用场景很广。

  2. IMDb 电影评论数据集是常用的情感分析数据集,训练集和测试集各 25000 条评论,正负标签各占一半。

  3. 预处理数据集的步骤是:词元化(拆成单词)、创建词表(过滤稀有词)、处理评论长度(统一成固定长度),最后转换成数据迭代器方便训练。

(注:文档部分内容可能由 AI 生成) 源地址

京ICP备2024093538号-1