词嵌入:探索、解释和利用(含Python代码)

2025年3月6日 | 阅读11分钟

引言

自然语言处理(NLP)极大地改变了机器与人类语言交互的方式。NLP技术是我们日常使用的许多应用的核心,无论是文本的自动翻译,还是社交媒体或其他平台上的公众舆论的判断。这些进步的核心是一种称为词嵌入的方法——将词语转换为密集向量空间中向量的方法。它促进了机器以高效率生成人类语言的方式来学习语言

词嵌入现在是大多数NLP领域分析的中心;它们使机器能够理解词语的含义,依靠高维空间中的特征,其中相似的词语彼此靠近。这种方法与早期编码方式(如独热编码)截然不同,独热编码稀疏且无法捕捉词语之间的交互。

本文将首先定义词嵌入,然后讨论根据应用需求可以利用词嵌入的途径和方式。我们将提供词嵌入的理论背景,讨论如何使用Python语言实现它们,并演示如何使用它们来解决一些现实生活中的情况。阅读本文后,读者将能够掌握词嵌入的概念及其实现,并认识到词嵌入在NLP不同过程中的用途。

探索:理解词嵌入

什么是词嵌入?

词向量是词语特征的密集表示。同样,意义相近的词语被放置在相同的向量空间中,但处于连续且可微分的空间中。这种方法使模型能够区分词语的含义,例如,相似词语之间的关系、类比和共现。

例如,假设“国王”、“女王”、“男人”和“女人”是特征空间中的四个向量。要求“国王”和“女王”的特征向量之差与“男人”和“女人”向量的特征空间之差非常相似,或者一般来说,与向量算术相似。

历史背景:从独热编码到密集向量

在使用词嵌入之前,词语是通过独热编码方法进行编码的,该方法有其自身的缺点。独热编码使用编码向量,其中词汇表中的每个词都等于一个长度为词汇表大小的0和1的向量。向量在该词对应的位置上只有一个“1”;所有其他位置都是“0”。

然而,独热编码有几个局限性:

  • 稀疏性:向量是高维且稀疏的,这通过降低计算成本来帮助。
  • 缺乏语义含义:独热向量会丢失任何两个词语之间的相对语义信息。例如,“猫”和“狗”将是两个向量,它们彼此完全不同,但它们在语义上是相关的。

词嵌入通过将词语映射到高维度的实数向量空间来解决这些问题。这些向量是低维的,因此计算上很容易处理,并且与词语之间的语义关系非常相关。

流行的词嵌入技术

生成词嵌入有几种方法。主要的方法是Word2Vec(由Mikolov等人[12]开发)、GloVe(由Pennington等人[14]开发)和FastText(由Joulin等人[6]开发)。接下来将简要分析上述每种技术,包括它们的优缺点。

1. Word2Vec

Word2Vec由Google的Mikolov等人提出,是最常用的词嵌入方法之一。它有两种形式:连续词袋模型(CBOW)和Skip-gram模型。

  • 连续词袋模型(CBOW):它们从上下文词语预测目标词语。上下文词语用于预测目标词语,然后对其频率取平均。
  • Skip-gram:该模型反向操作,即给定目标词语预测上下文词语。这种方法仅适用于少量数据,并且被认为是首选。

2. GloVe

GloVe由斯坦福大学的Pennington、Smithend和Socher设计;它代表Global Vectors for Word Representation(词表示的全局向量)。Word2Vec在学习嵌入时依赖于局部上下文。相比之下,GloVe在学习嵌入时,是基于语料库的全局词语共现统计的结果。概念是词语一起出现的概率应该传达语义信息,而这正是嵌入的目标。

3. FastText

该模型是Facebook开发的Word2Vec模型的扩展,称为FastText。FastText能更有效地学习词向量,因为它不为整个词语学习向量,而是为“n-gram”学习向量。执行相同的操作很有用,因为它能够更有效地处理词汇表中未出现的词,因为新词的嵌入可以从子词嵌入中派生出来。

解释:在Python中使用词嵌入

如上所述,我们现在有了词嵌入的理论背景,这使我们能够进入实践。首先,对于Word2Vec嵌入,我们将使用Python中的Gensim库,然后研究预训练GloVe嵌入的细节。

安装必需的库

在开始编码之前,让我们安装必要的库。

训练Word2Vec嵌入

作为热身,我们将从使用小型文本语料库训练Word2Vec模型开始,其大小对模型来说并不重要。Gensim使这个过程变得容易。

输出

 
[ 0.00765647  0.00171521 -0.00943224  0.00718394  0.00831698 -0.00709062
  0.00467283 -0.00783045 -0.00896769 -0.00422929 -0.00108115  0.00304883
  0.00876332 -0.00983494 -0.00326822 -0.00449258 -0.00747072 -0.00518299
  0.00567512 -0.00852403 -0.00369456 -0.00712544 -0.00489777  0.00424892
  0.00591239  0.00069563 -0.00313559 -0.00915095 -0.00943353  0.00184728
 -0.00647396 -0.00428071  0.00522386 -0.00674524 -0.00489522  0.00183748
 -0.00824755  0.00414997  0.00280534  0.00675074 -0.00939749 -0.00561745
  0.00446288  0.00862263 -0.00230841  0.00692879  0.0046679   0.00951745
 -0.00261154  0.00598421]   

说明

  • 代码首先导入Word2Vec模型所需的Gensim库以及用于文本分词的NLTK。
  • 描述了一个示例文语料库——它很小,包含4个样本;所有样本都被认为与自然语言处理相关。
  • 对于语料库,将应用NLTK的'word_tokenize'来分词,并将每个文本转换为一个列表,其中字符串实际上由小写单词组成。
  • 使用以下参数在分词语料库上训练Word2Vec模型:
  • 'vector_size=50':每个词的字符数为50,每个词都有一个50维的相应向量。
  • 'window=2':上下文窗口大小为2,这意味着模型包含目标词之前2个词和之后2个词。
  • 'min_count=1':在任何情况下,只有语料库列表中存在的词才会在模型中使用,或者至少在模型中使用的词属于语料库列表。
  • 'workers=4':能够使用4个中央处理单元核心来训练模型。
  • 然后将这个训练好的Word2Vec模型存储在一个名为'word2vec.model'的文件中。
  • 然后打印出'love'在50维空间中的系数,这就是模型形成这个词的方式。

探索预训练GloVe嵌入

然而,通常在需要更频繁地训练嵌入时,尤其是在处理大型语料库时:在这种情况下,预训练的嵌入效果更好。GloVe嵌入被频繁使用,并且有许多预训练的嵌入选择。

可以从该工具的官方网站直接下载预训练的GloVe嵌入,并且是该项目中使用的选项,无需从源下载。以下是如何加载和使用它们的示例:

输出

 
[ 0.51895  0.42425 -0.34174 -0.02522  0.01265  0.43894  0.71951 -0.51261
 -0.55819  0.3688   0.57391  0.16774  0.24249 -0.65402  0.03224 -0.34158
  0.52374 -0.2776  -0.5508  -0.21965  0.24052  0.34793  0.47645  0.32499
 -0.32833  1.4773   0.12035 -0.12845 -0.10456  0.0428   1.0577  -0.0873
 -0.38275 -0.25789 -0.60523  0.45259 -0.28269  0.1884  -0.50379 -0.07928
 -0.35584  0.46026  0.29064  0.36497 -0.53152 -0.31896  0.00528 -0.07153
  0.34042  0.14777]   

说明

  • 然后代码要求导入'numpy',其中包含词向量的数值数据。
  • 程序逐行打开并读取'GloVe'文件。预处理移除了空格和换行符,并通过将所有向量加1来完成,以避免错误。
  • 在每一行中,词语后面是嵌入值序列,从头到尾,不包括词语本身。
  • 该词是字典模型中的键,对应的值将存储为浮点数的numpy数组。
  • 最后,所有行都经过相同的处理,并向最终用户显示一条消息,告知他们模型已加载的词语数量。
  • 通过调用'load_glove_model'函数加载'glove_model',该函数使用'glove.6B.50d.txt'文件路径,该文件包含50维的GloVe向量。
  • 最后,从'glove_model'字典中获取单词“love”的向量并打印出来。

应用:词嵌入的一些用途

因此,在接下来的材料中,我们将基于词嵌入的概念,解释如何解决现实世界的NLP问题。我们将涵盖三个常见应用:情感分析、文档聚类和词语匹配。

词嵌入在情感分析中的应用

这是将给定文本分类为积极、消极、中性或其他相关类别的过程。词嵌入可用于获取文本的向量表示,然后可以将这些向量再次馈送到机器学习模型中进行分类。

输出

 
Sentiment: Positive   

说明

  1. 导入
    • numpy用于任何与数字相关的数学计算。
    • Keras的Sequential、Dense、LSTM和Embedding用于构建和训练神经网络模型。
    • 对于文本数据预处理,Keras提供了'Tokenizer'和'pad_sequences'。
  2. 样本数据
    • 文本列表包含四个示例文本,以及代表积极情感为“1”和消极情感为“0”的“标签”。
  3. 分词
    • Tokenizer将文本数据转换为整数序列,每个整数指向词汇表中的一个词。
    • 'pad_sequences'用于用零填充最短序列,以便所有序列长度相等。
  4. GloVe嵌入
    • 使用上面代码中定义的“load_glove_model”函数加载GloVe嵌入。
    • 为此,创建了“embedding_matrix”,使每一行唯一地对应于词汇表中某个词的GloVe向量。有些词不在GloVe模型中,对于未见过的词将分配一个零向量。
  5. 模型构建
    • 构建了一个Sequential模型。
    • “Embedding”层预先填充了GloVe向量,并且设置为非训练状态。
    • 然后,加入一个包含50个节点的“LSTM”层,目的是捕捉文本的顺序性。
    • 最后,使用具有Sigmoid激活函数的Dense输出层,用于二元分类。
    • 分类。
  6. 模型编译
    • 该模型使用Adam进行训练,Adam是深度学习的一种高效优化器。使用的损失函数是二元交叉熵,因为这种类型的损失函数适用于具有二元分类结果的模型。
  7. 模型训练
    • 模型在填充序列“X”和相应的标签“y”上训练10个epoch。
  8. 预报
    • 一个新句子被分词,如果令牌数量少于指定令牌化句子的长度,则进行填充。
    • 然后模型对当前新文本的情感进行预测。
    • 如果预测概率大于0.5,则打印预测结果为“Positive”,否则为“Negative”。

文档相似性

词嵌入还可以用于模拟文档之间的距离。它们尝试计算文档中每个词的词向量的平均值,然后使用余弦相似度计算所得向量之间的相似度。

这是一个示例

输出

 
Document similarity: [[0.7910344]]   

说明

  • 它们使用“sklearn.metrics.Pairwise”包中的“cosine_similarity”函数来计算向量相似度。
  • “document_vector”函数
  • 在文档中,读取单词列表和预训练的GloVe模型作为参数。
  • 删除文档中所有不在GloVe模型中的词。
  • 它还计算文档中单词的GloVe向量的平均值,从而仅得到一个文档向量。
  • 然后代码处理两个示例文档:
  • 在“doc1”中,关键词“我爱自然语言处理。”
  • doc2是“词嵌入很有趣”。
  • 文档向量函数“document_vector()”为文档创建向量:vec1代表文档1,vec2代表文档2。
  • 'cosine_similarity([vec1], [vec2])'给出两个文档向量的余弦相似度。
  • 打印相似度得分,该得分根据GloVe向量指示两个文档在语义上的相似程度。

结论

词嵌入通过以新的方式表示NLP数据,改变了NLP领域。该技术将词语映射到高维的量化空间。这些表示对于编码语义含义和促进机器处理人类语言至关重要。在本文中,我们学习了词嵌入,如何在Python中使用它们,以及在自然语言处理中的一些用例场景。

这只是一个提醒,随着您在词嵌入方面做得更深入,嵌入词语的方式以及所选模型将在您的NLP应用中发挥更重要的作用。因此,无论您是在进行情感分析还是为其创建内容,比较文档或进行词语类比,词嵌入都是多功能且强大的工具。