机器学习&&深度学习——NLP实战(情感分析模型——数据集)
- 引入
- 读取数据集
- 预处理数据集
- 创建数据迭代器
- 整合代码
- 小结
引入
预训练文本表示可以通过不同模型架构,放入不同的下游自然语言处理任务。如下图所示:
我们的重点是如何应用深度语言表征学习来解决自然语言处理问题。现今有两种流行且具有代表性的下游自然语言处理任务: 情感分析和自然语言推断。这里先进行情感分析的模型构建和训练。
在给定预训练的文本表示的情况下,分析单个文本,从而探讨情感分析模型。
下面,我们从情感分析应用开始,分别解读基于循环神经网络和卷积神经网络的模型设计。
由于情感可以被分类为离散的极性或尺度(例如,积极的和消极的),我们可以将情感分析看作一项文本分类任务,它将可变长度的文本序列转换为固定长度的文本类别。
在这里,我们将使用斯坦福大学的large movie review dataset数据集来进行情感分析。它由一个训练集和一个测试集组成,其中包含25000个电影评论。在这两个数据集中,“积极”和“消极”标签的数量相同,表示不同的情感极性。
读取数据集
首先,下载并提取路径…/data/aclImdb中的IMDb评论数据集。(可能会下的很久)
#@save
d2l.DATA_HUB['aclImdb'] = (
'http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz',
'01ada507287d82875905620988597833ad4e0903')
data_dir = d2l.download_extract('aclImdb', 'aclImdb')
Downloading …\data\aclImdb_v1.tar.gz from http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz…
接下来,读取训练和测试数据集。每个样本都是一个评论及其标签: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, 'review:', x[0:60])
运行结果:
训练集数目: 25000
标签: 1 review: Bromwell High is a cartoon comedy. It ran at the same time a
标签: 1 review: Homelessness (or Houselessness as George Carlin stated) has
标签: 1 review: Brilliant over-acting by Lesley Ann Warren. Best dramatic ho
预处理数据集
将每个单词作为一个词元,过滤掉出现不到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('# tokens per review')
d2l.plt.ylabel('count')
d2l.plt.hist([len(line) for line in train_tokens], bins=range(0, 1000, 50));
d2l.plt.show()
运行结果:
显然,评论的长度各不相同。为了每次处理一小批量这样的评论,我们通过截断和填充将每个评论的长度设置为500。这和之前实现机器翻译时对数据集的预处理步骤类似。
num_steps = 500 # 序列长度
train_features = torch.tensor([d2l.truncate_pad(
vocab[line], num_steps, vocab['<pad>']) for line in train_tokens])
创建数据迭代器
现在我们可以创建数据迭代器了。在每次迭代中,都会返回一小批量样本。
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))
输出结果:
X: torch.Size([64, 500]) , y: torch.Size([64])
小批量数目: 391
整合代码
最后,我们将上述步骤封装到load_data_imdb函数中。它返回训练和测试数据迭代器以及IMDb评论数据集的词表。
#@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
小结
1、情感分析的目的是研究人们在文本中的情感,这是一个文本分类问题,它将可变长度的文本序列进行转换,转换成为固定长度的文本类别。
2、经过预处理后,我们可以使用词表将IMDb评论数据集加载到数据迭代器中。