用深度学习实现自然语言处理:word embedding,单词向量化

图灵汇官网

几年前,腾讯新闻发布了一篇引人注目的文章。文章本身并没有什么特别之处,但其独特之处在于作者——这并不是一个人,而是由人工智能编写的。通过分析大量的财经文章,AI学会了撰写财经报道的方法,并自动生成了一篇几乎与人类撰写的无异的文章。

从本节开始,我们将探讨如何利用神经网络构建一个能够理解和解析人类文本含义的智能程序。就像前一章节中描述的图像识别网络一样,神经网络实际上并不具备人类的视觉理解能力,而是通过对大量图片数据的学习,从中提取固定的规律。本章的目标是开发一个能够从大量文本数据中提取固定模式或规律的神经网络。

为了使网络能够处理文本,首先需要将文本数据化。这通常包括将文本拆分成词组,并将这些词组转换为向量。另一种方法是将文本拆分为字符序列,并将每个字符表示为向量。此外,还可以将多个词或字符组合成一组,然后将其转换为向量。无论采用哪种方法,我们都会将这些向量化的单元称为“token”,将整个过程称为“tokenization”。

举例来说,假设我们有一句英文句子:“The cat jump over the dog”。如果采用第一种方法,可以将句子拆分为多个单词:'The', 'cat', 'jump', 'over', 'the', 'dog'。然后通过算法为每个单词生成一个向量: - 'the' -> [0.0, 0.0, 0.4, 0.0, 1.0, 0.0] - 'cat' -> [0.5, 1.0, 0.5, 0.2, 0.5, 0.5, 0.0]

一种简单的将单词转换为向量的方法是使用one-hot-encoding。例如,假设句子中只有5个不同的单词,可以使用含有5个元素的向量来表示: - 'The' -> [1, 0, 0, 0, 0] - 'cat' -> [0, 1, 0, 0, 0] - 'jump' -> [0, 0, 1, 0, 0]

下面是一个将单词进行one-hot-encoding的示例代码:

```python import numpy as np

samples = ['The cat jump over the dog', 'The dog ate my homework']

tokenindex = {} for sample in samples: for word in sample.split(): if word not in tokenindex: tokenindex[word] = len(tokenindex) + 1

maxlength = 10 results = np.zeros((len(samples), maxlength, max(token_index.values()) + 1))

for i, sample in enumerate(samples): for j, word in list(enumerate(sample.split()))[: maxlength]: index = tokenindex.get(word) results[i, j, index] = 1. ```

Keras框架提供了许多便捷的工具,可以简化这一过程。以下是使用Keras实现相同功能的代码:

```python from keras.preprocessing.text import Tokenizer

samples = ['The cat jump over the dog', 'The dog ate my homework'] tokenizer = Tokenizer(numwords=1000) tokenizer.fitontexts(samples) sequences = tokenizer.textstosequences(samples) onehotvecs = tokenizer.textstomatrix(samples, mode='binary') wordindex = tokenizer.word_index

print("当前总共有 %d 个不同单词" % len(word_index)) ```

运行结果为:

[[1, 3, 4, 5, 1, 2], [1, 2, 6, 7, 8]] 当前总共有 8 个不同单词

接下来,我们将讨论自然语言处理中的一个重要概念——词嵌入(word embedding)。词嵌入是一种使用非零向量表示单词的方法。虽然one-hot-encoding是一种简单的表示方法,但它存在冗余过多和向量维度过高的问题。词嵌入将高维度的冗余向量转换为低维度的向量,使得向量的维度通常只有256到1024维。

词嵌入的一个重要目标是,语义相近的单词在向量空间中的距离应该较近。例如,“good”和“fine”都表示“好”,因此它们对应的向量在空间上应较为接近。

接下来,我们将通过一个实际的例子来展示如何使用词嵌入分析影评的情感。我们将使用IMDB数据集,提取每篇影评的前20个单词,并将其向量化。通过观察这些向量在空间中的分布,我们可以判断影评的情感倾向。

以下是构建情感分析模型的代码:

```python from keras.models import Sequential from keras.layers import Flatten, Dense from keras.layers import Embedding

model = Sequential() model.add(Embedding(10000, 8, inputlength=maxlen)) model.add(Flatten()) model.add(Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binarycrossentropy', metrics=['acc']) model.summary()

history = model.fit(xtrain, ytrain, epochs=10, batchsize=32, validationsplit=0.2) ```

运行上述代码后,我们可以绘制模型在训练数据和验证数据上的表现:

```python import matplotlib.pyplot as plt

acc = history.history['acc'] valacc = history.history['valacc'] loss = history.history['loss'] valloss = history.history['valloss']

epochs = range(1, len(acc) + 1)

plt.plot(epochs, acc, 'bo', label='training accuracy') plt.plot(epochs, val_acc, 'b', label='validation accuracy') plt.title('Training and validation accuracy') plt.legend() plt.show()

plt.figure() plt.plot(epochs, loss, 'bo', label='training loss') plt.plot(epochs, val_loss, 'b', label='validation loss') plt.title('Training and validation loss') plt.legend() plt.show() ```

从上图可以看出,即使没有进行任何优化,模型对验证数据的识别准确率也达到了约75%。

最后,我们注意到使用预训练的模型可以显著提高精度。例如,Word2Vec算法是由Google研究员Mikolov在2013年提出的,它通过分析大量文本数据为常用单词生成向量,并在网络上提供下载。另一个常用的单词向量数据库是GloVe,由斯坦福大学的研究人员开发。

在下一节中,我们将探讨如何使用预训练的词嵌入数据“GloVe”对文本进行分割、量化和有效分析。

本文来源: 图灵汇 文章作者: 钟焰艳