失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【自然语言处理-2】word2vec词嵌入算法“男人”+“女人”=“爱情的坟墓”

【自然语言处理-2】word2vec词嵌入算法“男人”+“女人”=“爱情的坟墓”

时间:2019-05-30 14:29:47

相关推荐

【自然语言处理-2】word2vec词嵌入算法“男人”+“女人”=“爱情的坟墓”

词嵌入算法

通俗易懂的理解

词嵌入算法就是使用一个低维度的向量来表示一个词,并且距离相近的向量在实际的词含义上也是相近的。比如:

“男人”的向量与“女人”向量的距离,相比“男人”向量与“游戏”向量的距离,谁更近?

对我来说,“电子竞技不存在爱情”,所以后者的距离比前者更近。

* “ 男 人 词 向 量 ” + “ 女 人 词 向 量 ” ≈ “ 爱 情 的 坟 墓 ” “男人词向量”+“女人词向量”\approx“爱情的坟墓” “男人词向量”+“女人词向量”≈“爱情的坟墓”

这使得词向量具有数据运算功能。

独热编码

那么问题来了,词语怎么怎么转换成一个数学可运算的状态呢?

文本长度不确定;文本词语每次都不一样,很难有效的编码来表达文本意思

One hot独热编码:一位有效编码,其中每一位都用来存储一种状态。

假设数据有“男”“女”两个词,那我们的独热编码就一共两位

优点

将离散的文本数据都变成定长的数据,方便计算

缺点

过于稀疏,对一些新的语料的词可能,每个词向量为1位,其余全是零,长度很常见就上百万级。这就没有办法记录词与词之间的关系。

这样的话,对于数据的存储、运算都是相当困难。

分布式表示方法

分布式表示的方法来解决独热编码的问题

原理

通多对文本词的训练,将每个词都映射到比较短、稠密度高的向量上来。所有的词构成一个向量空间,通过统计学的方法来研究词之间的关系。

假设我们用以下几个维度来表示这几个人物的词。

通过上面的转换,就可以将稀疏的词向量转为稠密的向量。

把原本的词向量映射到这个相对低维空间的过程就称为词嵌入(Word Embedding)

上下文关系学习

我有一个沙雕室友王三爱学习

我有一个逗比室友李四爱学习

这两句可以看出王三和李四的词向量就很接近。这就叫上下文类似

算法原理

Word2Vec 的算法核心是神经网络算法

是包含一个隐藏层的浅层神经网络

输入层是我们去掉了某些部分的语料编码,在这里也就是 One Hot 编码,输出层的维度与输入层一样,所需要预测输出的是在输入层被去掉的部分。

所以这里有两种方案,第一个是去掉某个词,输入层是这个词的上下文,这种方法叫作CBOW(Continuous Bag Of Word),输出层也就是要去预测这个词;第二种方案是去掉上下文,用这个词作为输入层,这种方法叫作Skip-Gram,输出层需要预测上下文。

CBOW 模式

相当于填词游戏?

我今天____个狗

SKip-Gram模式

__ ___ 吃___

对于这个网络中,从输入层到隐藏层是没有激活函数的,也就是一个线性关系。这里需要注意的是 Word2Vec 所获得的模型并不是我们这个网络的最终结果,而是在训练完成之后,把隐藏层的权重矩阵获取出来,即形成了我们的 Word2Vec 算法的结果。

通过这个方法,我们语料中的每一个词都获得了一个预设维度的向量,由于隐藏层的维度要比 onehot 向量的维度小很多,这也起到了很好的降维作用。

优缺点

优点

估计准确,因为考虑了上下文,以及词语顺序成功降低了向量维度适配后续NPL任务,通用性强

缺点

不具有“渣男特质”,只能解决一对一词向量,对一词多义不好处理。

案例实战

import gensim #引入gensimimport osimport reimport sysimport multiprocessing #引入多线程操作from time import timeclass getSentence(object):#初始化,获取文件路径def __init__(self, dirname):self.dirname = dirname

# 构建一个迭代器def __iter__(self):for root, dirs, files in os.walk(self.dirname):for filename in files:file_path = root + '/' + filenamefor line in open(file_path):try:#清除异常数据,主要是去除空白符以及长度为0的内容s_line = line.strip()if s_line== "":continue#把句子拆成词word_line = [word for word in s_line.split( )]yield word_lineexcept Exception:print("catch exception")yield ""if __name__ == '__main__':begin = time()#记录一个起始时间#获取句子迭代器sentences = getSentence("traindata")#训练word2vec模型 使用句子迭代器作为语料的输入,设定的最终向量长度为200维;窗口长度为15;词的最小计数为10,词频少于10的词不会进行计算;使用并行处理model = gensim.models.Word2Vec(sentences,size=200,window=15,min_count=10, workersmeans=multiprocessing.cpu_count())#模型存储,这块记得先预先新建一个model路径,或者也可以增加一段代码来识别是否已经创建,如果没有则新建一个路径model.save("model/word2vec_gensim")model.wv.save_word2vec_format("model/word2vec_org","model/vocabulary",binary=False)end = time()#输出运算所用时间print("Total procesing time: %d seconds" % (end - begin))

如果觉得《【自然语言处理-2】word2vec词嵌入算法“男人”+“女人”=“爱情的坟墓”》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。