自然语言处理 |收藏!使用Python代码的4种句嵌入技术

Posted 数艺学苑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自然语言处理 |收藏!使用Python代码的4种句嵌入技术相关的知识,希望对你有一定的参考价值。

人类理解语言细微差别的能力是非常强大的——我们敏锐的大脑可以在一句话里轻易地感受到幽默、讽刺、负面情绪等,但发挥这个“超能力”的前提是,我们必须知道话语所使用的语言。
 
例如,如果有小伙伴用日文在底部写评论,大部分人应该看不懂他写的是什么吧,自然也不敢轻易回复。所以,为了实现有效沟通,我们需要用彼此能理解的语言进行互动。
 
而对于机器来说,为了让机器可以处理和理解任意文本,我们必须用机器能够理解的语言来表示文本。那么它最懂哪种语言呢?
 
答案是 数字(numbers ——无论我们提供给机器什么数据:视频、音频、图像或文本,机器都只会与数字打交道,这也就是为什么将文本表示为数字或嵌入文本(embedding text)是自然语言处理中最热门的话题之一。

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


这篇文章,我们将介绍Python代码中最常用的4种句嵌入技术并且概述它们的体系结构以及如何用Python实现这些技术,包括如下内容:

一、什么是词嵌入(Word Embedding)
二、什么是句嵌入(Sentence Embedding
三、四种句嵌入技术:
Doc2Vec
SentenceBERT
InferSent
Universal Sentence Encoder

  • 一、什么是词嵌入?


最初的嵌入技术只处理单词,即给定一组单词,而该技术就是把集合中的每个单词生成一个嵌入。最原始的方法是对单词序列进行热编码,如此一来,集合中的单词就由1表示,其他单词由0表示。
 
虽然这种方法在表示单词和其他简单的文本处理任务上很有效,但面对更复杂的任务(查找相似单词)时却没什么用了。比如,我们需要查询:“北京最好的日料店”,我们希望得到与“日料”、“北京餐厅”和“最好”相对应的搜索结果,若我们得到的结果是“北京的顶级日本料理“,那么用原始方法就无法检测出“最好”和“顶级”,或“料理”和“店”之间的相似性了。

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

词嵌入技术图示

这个词关联问题让词嵌入技术得以开发和发展,与传统的热编码相比,词嵌入技术转换的不仅是单词,还能识别出该词的语义和语法以构建该信息的向量。

目前常用的词嵌入技术有:
Word2VecGloVeELMoFastText等
 
词嵌入的基本原理就是使用与该词相邻的词的信息。随着词嵌入技术的发展,技术人员已经找到了更好的方法来表达更多的信息,由此扩展到了句子和段落。
 
  • 二、什么是句嵌入?


如果我们直接处理句子呢?要知道,在大文本的情况下,很大程度上我们的分析会被从词嵌入中提取的信息所限制。
 
假设,我们读到一个句子“我不喜欢拥挤的地方”,接着,我们又读到“然而,我喜欢世界上最繁忙的城市之一,纽约”。我们怎样才能让机器明白“拥挤的地方”和“繁忙的城市”之间的关联呢?
 
显然,词嵌入技术在这里是不够的,我们需要用到句嵌入技术了。句嵌入是将整个句子及其语义信息表示为向量,让机器能理解上下文、用意和其他潜藏在文本中的细微差别。
 
接下来我们将用Python代码实例,直观地给大家介绍目前最受欢迎的4中句嵌入技术:
Doc2VecSentenceBERTInferSentUniversal Sentence Encoder
 
那我们一起来建立基本语料库并定义句子列表吧!

Step 1:  
首先,导入库并下载punkt

import nltknltk.download('punkt')from nltk.tokenize import word_tokenizeimport numpy as np

Step 2:
然后,我们来定义句子列表。当然,你也可以使用一个更大的列表(最好只使用一个句子列表以便更容易地处理每个句子)

sentences = ["I ate dinner.", "We had a three-course meal.", "Brad came to dinner with us.", "He loves fish tacos.", "In the end, we all felt like we ate too much.",       "We all agreed; it was a magnificent evening."]
 
Step 3:
我们再保留一份这些句子的标记版

# Tokenization of each documenttokenized_sent = []for s in sentences: tokenized_sent.append(word_tokenize(s.lower()))tokenized_sent


自然语言处理 |收藏!使用Python代码的4种句嵌入技术


Step 4:
最后,我们定义一个函数,让它返回两个向量间的余弦相似度(cosine similarity
 
def cosine(u, v): return np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v)) 

好了!接下来,我们就用这个句子列表来学习这4个句嵌入技术吧!

  • 三、(1)Doc2Vec


作为Word2Vec的扩展,Doc2Vec是当下最流行的句嵌入技术之一。该算法于2014年引入,是一种无监督算法,主要原理是将一个“段落向量”添加到Word2Vec模型中,而其中,添加方法两个:
 
1) PVDM(分布式存储版本的段落向量):
在分配一个段落向量句的同时给所有句子共享词向量。然后通过平均或连接(段落向量和单词向量)来得到最后的句关联。其实,它是Word2Vec连续词袋法的扩展——在词袋中,我们根据一组单词预测下一个单词。在PVDM中,我们是根据一组句子预测下一个句子。


自然语言处理 |收藏!使用Python代码的4种句嵌入技术

PVDM图示

2) PVDOBW(分布式包词版本的段落向量):
PVDM一样, PVDOBW也是Word2Vec的另一扩展,但与PVDM不同的是,我们只在句子中随机抽取单词,然后让模型去预测它来自哪个句子(可以理解成是一个分类任务)

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

Step 1:
我们将使用Gensim来演示如何使用Doc2Vec。首先要导入模型、语料库和其他库,然后构建一个带标记的语料库。每个句子都被表示为一个TaggedDocument,其中包含单词列表和与之关联的标记。
 
from gensim.models.doc2vec import Doc2Vec, TaggedDocumenttagged_data = [TaggedDocument(d, [i]) for i, d in enumerate(tokenized_sent)]tagged_data 

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


Step 2:
接着,我们将用以下参数对模型进行训练:
 
model = Doc2Vec(tagged_data, vector_size = 20, window = 2, min_count = 1, epochs = 100)
'''vector_size = Dimensionality of the feature vectors.window = The maximum distance between the current and predicted word within a sentence.min_count = Ignores all words with total frequency lower than this.alpha = The initial learning rate.'''
model.wv.vocab

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

Step 3:
我们现在来挑一个句子来测试吧,让模型去从数据中找出与其最相似的5个句子,并按相似度降序显示。其中,infer_vector方法返回测试句子的向量化形式(包括段落向量)most_similar方法返回相似的句子。
 
test_doc = word_tokenize("I had pizza and pasta".lower())test_doc_vector = model.infer_vector(test_doc)model.docvecs.most_similar(positive = [test_doc_vector])positive = List of sentences that contribute positively.

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

成功找到了!

  • 三、(2)SentenceBERT


SentenceBERT2018年一经推出就立即在句嵌入测试中受到热捧。这个基于BERT模型的技术有4个关键概念:
 
1.Attention
2.Transformer
3.BERT
4.孪生神经网络(Siamese Network)
 
SentenceBERT使用孪生神经网络结构,使用2个句子作为输入。这2个句子会被传递给BERT模型,然后使用pooling层来生成它们的嵌入。最后使用句子对的嵌入作为输入来计算余弦相似度。
 

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

              孪生神经网络图示(左)                  
SentenceBERT技术图示(右)

Step 1:
加载预训练的BERT模型。sentence-transformers里还有许多其他开源的预训练模型,可以在此处找到模型的完整列表。
 
!pip install sentence-transformers
from sentence_transformers import SentenceTransformersbert_model = SentenceTransformer('bert-base-nli-mean-tokens')
 
Step 2:
对句子进行编码并显示句子向量:
 
sentence_embeddings = model.encode(sentences)
#print('Sample BERT embedding vector - length', len(sentence_embeddings[0]))#print('Sample BERT embedding vector - note includes negative values', sentence_embeddings[0])
 
Step 3:
定义一个测试查询并对其进行编码:
 
query = "I had pizza and pasta"query_vec = model.encode([query])[0]

Step 4:
使用scipy计算余弦相似度,然后检索句子和测试查询间的相似度

for sent in sentences: sim = cosine(query_vec, model.encode([sent])[0]) print("Sentence = ", sent, "; similarity = ", sim):


自然语言处理 |收藏!使用Python代码的4种句嵌入技术


我们获得文本中的句子与测试句之间的相似性了!实例使用的是已经预训练的BERT模型,如果小伙伴想从头训练SentenceBERT,它的运行速度将会变得异常慢hhh
 
  • 三、(3)InferSent

 
InferSentFacebook人工智能研究所在2018年推出的一项有监督的句嵌入技术。该模型最大的特点是它是在自然语言推理(NLI)数据集里训练的,更具体地说,就是SNLI (Stanford自然语言推理)数据集。该数据集由57万对人类生成的英语句子组成,而这些句子已经被人工标记为隐含、矛盾或中性了。
 
SentenceBERT一样,InferSent也是使用一对句子并对它们进行编码以生成实际的句子嵌入:

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


输出向量进入分类器,分类器会将向量分类到3个定义类别之一中(concatenationelement-wise productabsolute element-wise difference
 
让我们看看句子相似度任务是如何使用推理的。我们将使用PyTorch进行此操作:
 
Step 1:
首先,下载推断模型和已经预训练的单词向量。为此,请从这里保存model .py文件并将其存储到工作目录中。
 
我们还需要保存训练好的模型和预训练好的GLoVe词向量。所以,我们的工作目录应该有一个“encoders”文件夹和一个名为“GLoVe”的文件夹。encoders文件夹将有我们的模型,而GloVe文件夹应该有词向量:
 
! mkdir encoder! curl -Lo encoder/infersent2.pkl https://dl.fbaipublicfiles.com/infersent/infersent2.pkl
! mkdir GloVe! curl -Lo GloVe/glove.840B.300d.zip http://nlp.stanford.edu/data/glove.840B.300d.zip! unzip GloVe/glove.840B.300d.zip -d GloVe/

加载模型和词向量:
 
from models import InferSentimport torch
V = 2MODEL_PATH = 'encoder/infersent%s.pkl' % Vparams_model = {'bsize': 64, 'word_emb_dim': 300, 'enc_lstm_dim': 2048, 'pool_type': 'max', 'dpout_model': 0.0, 'version': V}model = InferSent(params_model)model.load_state_dict(torch.load(MODEL_PATH))
W2V_PATH = '/content/GloVe/glove.840B.300d.txt'model.set_w2v_path(W2V_PATH)

Step 2:
从最开始准备好的句子列表中构建词汇表:
 
model.build_vocab(sentences, tokenize=True)

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

Step 3:
测试——使用InferSent对该测试查询进行编码并生成嵌入:
 
query = "I had pizza and pasta"query_vec = model.encode(query)[0]query_vec


自然语言处理 |收藏!使用Python代码的4种句嵌入技术


Step 4:
计算此查询与文本中每个句子的余弦相似度:
 
similarity = []for sent in sentences: sim = cosine(query_vec, model.encode([sent])[0]) print("Sentence = ", sent, "; similarity = ", sim)


自然语言处理 |收藏!使用Python代码的4种句嵌入技术


  • 三、(4)Universal Sentence Encoder


目前性能最好的句嵌入技术应该就是Universal Sentence Encoder了,是我们可以用它来进行多任务学习。
 
这意味着我们生成的句嵌入可以用于多种任务,如情绪分析、文本分类、句子相似度等,这些请求的结果会反馈到模型中,从而得到比之前更好的句向量。
 
Universal Sentence Encoder是基于两种编码器的模型:TransformerDeep Averaging NetworkDAN)这两种模型都能够将一个单词或句子作为输入,并为其生成嵌入。基本流程如下:
 
1.将句子转换为小写字母后将其标记
2.根据编码器的类型,句子被转换为512维向量
3.如果我们使用Transformer,它类似于transformer模块的架构,会使用自注意机制。
4.使用DAN则会首先计算unigrambigram嵌入,然后对它们进行平均以得到单个嵌入。然后,它被传递到深度神经网络,以得到512维的句嵌入。
5.这些句嵌入然后用于各种非监督和监督任务,如Skipthoughts, NLI等,然后再次重用训练好的模型,生成新的512维句子嵌入。

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


首先下载TensorFlow and TensorFlow hub:
 
!pip3 install --upgrade tensorflow-gpu# Install TF-Hub.!pip3 install tensorflow-hub

Step 1:
导入需要的库:
 
import tensorflow as tfimport tensorflow_hub as hubimport numpy as np

Step 2:
通过TFHub使用该模型:
 
module_url = "https://tfhub.dev/google/universal-sentence-encoder/4"model = hub.load(module_url)print ("module %s loaded" % module_url)


自然语言处理 |收藏!使用Python代码的4种句嵌入技术


Step 3:
为句子列表和查询生成嵌入:
 
sentence_embeddings = model(sentences)query = "I had pizza and pasta"query_vec = model([query])[0]
 
Step 4:
计算测试查询与句子列表之间的相似度:
 
for sent in sentences: sim = cosine(query_vec, model([sent])[0]) print("Sentence = ", sent, "; similarity = ", sim)

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


  • 四、小结


今天给大家介绍了自然语言处理中最常用的4种句嵌入技术以及用于查找文本相似度的基本代码。这里小苑建议大家使用更大的数据集来尝试这些模型。此外,这里只提供了计算句子相似度的基本代码。对于其他适合的模型,大家需要先对这些句子进行预处理,然后将它们转换为嵌入。
 
此外,小苑这里并没有说没有其他流行的模式(包括FastSent, Skip-thought, Quick-thought, Word Movers Embedding等)
 
如果你已经尝试过这些或任何其他模式,请在评论中与我们分享


作者简介:

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

自然语言处理 |收藏!使用Python代码的4种句嵌入技术

自然语言处理 |收藏!使用Python代码的4种句嵌入技术


        指导老师:



参考文献:

https://www.analyticsvidhya.com/blog/2020/08/top-4-sentence-embedding-techniques-using-python/

 

https://www.analyticsvidhya.com/blog/2020/10/reinforcement-learning-stock-price-prediction/

 

以上是关于自然语言处理 |收藏!使用Python代码的4种句嵌入技术的主要内容,如果未能解决你的问题,请参考以下文章

深度盘点:30个用于深度学习自然语言处理和计算机视觉的顶级 Python 库

10个常用的Python图像处理工具,建议收藏!

经常进行数据处理?这6个 Python 代码块值得收藏

2023最新整理!全网最全Python标准库总结(学习宝典,建议收藏)

Python之NLP(转)

Python 运算符收藏