(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)

《文本嵌入式表示方法实战》系列文章是基于2017年我于研一下半学期做的两场长时间的组会汇报ppt上形成的文章(学习和实验长达3个月,因为当时主要以上课为主,实验都是课余时间做的。。),由于当时我正处于入门阶段,理解和表述定有不当之处,还请各位同学老师批评指教。。。

《文本嵌入式表示方法实战》系列文章全部链接如下:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)

(二)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)

(三)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)


1 前言

文本特征提取和表示方法历来是自然语言处理的核心问题之一,因为文本是符号数据,只要两个词只要构成的字不同或者构成的字相同就难以刻画他们之间的关系(例如“麦克风”和“话筒”这样的同义词,从字面上看不出两者含义相同)。

自然语言处理与图像处理和语音处理不同的地方是文本是符号数据,图像和语音的处理对象都是信号数据。信号数据可以很方便的从数学上进行刻画和描述,可以直接作为特征输入到深度学习模型中,而这也是深度学习能够在图像处理和语音处理取得重大突破的重要原因之一。

目前主要流行的文本表示方法是词嵌入(词向量)分布式表示方法,目前已经被广泛应用于各项自然语言处理任务中。分布式表示方法主要基于分布式假说(distributional hypothesis,上下文相似的词,其语义也相似。该假说由 Harris 在 1954 年提出,并由 Firth 在 1957 年进一步明确和完善)。

接下来需要界定几个概念:(参考来斯惟博士的毕业论文)

分布表示(distributional representation):分布(distributional)描述的是上下文的概率分布,因此用上下文描述语义的表示方法(基于分布假说的方法)都可以称作分布表示。与之相对的是形式语义表示。

分布式表示(distributed representation):分布式(distributed)描述的是把信息分布式地存储在向量的各个维度中,与之相对的是局部表示(local representation),如词的独热表示(one-hot representation),在高维向量中只有一个维度描述了词的语义。一般来说,通过矩阵降维或神经网络降维可以将语义分散存储到向量的各个维度中,因此,这类方法得到的低维向量一般都可以称作分布式表示。

本文主要从原理介绍结合实验实践来介绍目前主流的Word2VecGloVeParagraph2vecFastTextDSSM五种文本嵌入式方法(分布式表示方法),这几种方法分别从不同的文本粒度(子词、词、句、段落)探索了文本嵌入式表示方法。

2 相关工作

2.1 基于矩阵的分布表示

较为经典的方法是基于矩阵的分布表示方法。基于矩阵的分布表示通常又称为分布语义模型,这类方法需要构建一个“词-上下文”矩阵,从矩阵中获取词的表示。这类方法具体可以分为三个步骤:

一、选取上下文。最常见的有三种方法:

n    第一种,将词所在的文档作为上下文,形成“词-文档”矩阵;

n    第二种,将词附近上下文中的各个词(如上下文窗口中的 5 个词)作为上下文,形成“词-词”矩阵;

n    第三种,将词附近上下文各词组成的 n 元词组(n-gram)作为上下文。在这三种方法中,“词-文档”矩阵非常稀疏,而“词-词”矩阵相对较为稠密,效果一般好于前者。“词-n 元词组”相对“词-词”矩阵保留了词序信息,建模更精确,但由于比前者更稀疏,实际效果不一定能超越前者。

二、确定矩阵中各元素的值。“词-上下文”共现矩阵根据其定义,里面各元素的值应为词与对应的上下文的共现次数。然而直接使用原始共现次数作为矩阵的值在大多数情况下效果并不好,因此研究人员提出了多种加权和平滑方法,最常用的有 tf-idf(词频-逆文档频)、 PMI (点互信息)和直接取 log。

三、矩阵分解(可选)。在原始的“词-上下文”矩阵中,每个词表示为一个非常高维(维度是不同上下文的总个数)且非常稀疏的向量,使用降维技术可以将这一高维稀疏向量压缩成低维稠密向量。降维技术可以减少噪声带来的影响,但也可能损失一部分信息。最常用的分解技术包括奇异值分解(SVD)、非负矩阵分解(NMF)、典型关联分析(Canonical Correlation Analysis, CCA)、Hellinger PCA(HPCA)。

基于矩阵的分布表示在这些步骤的基础上,衍生出了若干不同方法,如经典的 LSA 就是使用“词-文档”矩阵, tf-idf 作为矩阵元素的值,并使用 SVD分解,得到词的低维向量表示。在这类方法中,最新的GloVe 模型就是借鉴了这种词共现矩阵的思想,后面会介绍该模型。 举一个“词-上下文矩阵”简单的例子。假设我们的语料库由三句话构成:

1→ I like deep learning.

2→ I like NLP.

3→ I enjoy flying.

然后设置统计窗口大小为1,并采用对称窗口(考虑词左侧和右侧,非对称窗口则考虑一侧),可以得到矩阵如图1所示:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第1张图片 图1

n接下来,每行都可以作为一个单词的词向量了,或者更进一步用矩阵分解等的方法,得到词向量。

2.2 基于聚类的分布表示

基于聚类的分布表示又称作分布聚类(distributional clustering),这类方法通过聚类手段构建词与其上下文之间的关系。其中最经典的方法是布朗聚类(Brown clustering)。布朗聚类是一种层级聚类方法,聚类结果为每个词的多层类别体系。因此可以根据两个词的公共类别判断这两个词的语义相似度。 具体而言,布朗聚类需要最大化以下似然,其中 ci 为词 wi 对应的类别:

布朗聚类只考虑了相邻词之间的关系,也就是说,每个词只使用它的上一个词,作为上下文信息。除了布朗聚类以外,还有若干基于聚类的表示方法。由于这类方法不是本文关注的重点,在此不再赘述。

2.3 基于神经网络的分布式表示

基于神经网络的分布表示一般称为词向量、词嵌入(word embedding)或分布式表示(distributed representation)。该方法主要通过神经网络技术对上下文,以及上下文与目标词之间的关系进行建模。由于神经网络较为灵活,这类方法的最大优势在于可以表示复杂的上下文。

相较于基于矩阵的分布表示方法中,最常用的上下文是词。如果使用包含词序信息的 n-gram 作为上下文,当 n 增加时, n-gram 的总数会呈指数级增长,此时会遇到维数灾难问题。而神经网络在表示 n-gram 时,可以通过一些组合方式对 n 个词进行组合,参数个数仅以线性速度增长。

神经网络词向量模型与其它分布表示方法一样,均基于分布假说,核心依然是上下文的表示以及上下文与目标词之间的关系的建模。构建上下文与目标词之间的关系,最自然的一种思路就是使用语言模型。从历史上看,早期的词向量只是神经网络语言模型的副产品。如bengio03年提出的nnlm,mikolov当年提出rnnlm,当时提出语言模型是对语言更好的建模,结果在训练的同时还得到了词向量,接着mikolov等人在词向量对于词的语义的表示进行了研究,如在2013的一篇文章中研究词向量空间中语义的表示,并发现了有趣的现象。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第2张图片 图2

如图2所示,通过Word2Vec学习得到的词向量在降维到二维平面上可以发现:man和woman在语义空间的相对位置与uncle和aunt、king和queen的相对位置是一致的,并且词的复数形式如kings和king的相对位置与queens和queen的相对位置是一致的。

同时mikolov在13年另一篇文章对不同语言词向量的可视化发现通过词向量表示,不同语言相同语义的词在词向量空间中处于的位置差不多,从而进一步说明了词向量刻画词语义的合理性与有效性。图3所示为英语(左边)和西班牙语(右边)分别通过Word2Vec训练得到的词向量在二维平面上的映射,分别选取了从1到5、猫狗等单词。可以看到不同语言,但是相同语义的单词在词向量空间中所处的相对位置极为相似。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第3张图片 图3

3 Word2Vec学习与实验

Word2Vec是一种基于神经网络的分布式表示方法(词向量,虽然模型只有一层,勉强算神经网络吧)。可以说Word2vec是mikolov等人在rnnlm的基础上探索词向量,从而设计的一个专门生成词向量的模型。值得注意的是,word2vec用到的模型都是lbl(log-bilinear language model)的。word2vec方法主要包括四个内容:cbow(continuous bag-of-words)模型、skip-gram(continuous skip-gram)模型,以及输出层的两种处理方法层次softmax(hs、hierarchical softmax)、以及负抽样(ng、negative sample)。

Word2Vec这部分的原理学习,推荐学习peghoty大神的《Word2Vec中的数学原理》一文。

3.1 CBOW和Skip-gram模型

如图4所示,左边是cbow右边是skip-gram,一句话,cbow是依据目标词周围单词猜测目标词,skip-gram是依据当前词猜测周围有啥词,很好理解。虽然表面上word2vec与矩阵的算法不同,但这种对上下文环境的预测,本质上也是一种对共现矩阵统计特征的学习,如后面介绍glove时,来斯惟等人在论文中证明了glove的损失函数实际上与SG(skip-gram)的是一样的。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第4张图片 图4

Cbow训练过程就是将一个窗口内的所有单词向量叠加(后期的算法将叠加后取了平均),输出到映射层(不要紧张,映射层意思就是中间层,离神经网络的隐藏层还差点意思),映射层再依据层次softmax或者负抽样获得输出,然后是求残差传播blabla。。。

Skip-gram训练过程就是将当前单词直接输出到映射层,然后再依据层次softmax或者负抽样得到输出,再求残差传播blabla。。。

这时候小伙伴们可能要问了,这也是我很长时间不理解的地方,直到看别人解析源代码时提到参数初始化时,才彻底理解了这个问题。一开始word2vec汇总统计语料中出现的所有单词,做了一个词汇表,然后给每个单词随机赋予初始值向量(每个维度值在一个指定范围内,其实获得词向量的这个过程有点像我们整理玩具箱里的玩具一样,先端起来把所有玩具撒在地摊上,这时每个玩具所在的位置都是随机的,然后再将玩具放到玩具箱中它应该放置的位置上)。

3.2 层次Softmax

然后就是理解一下层次softmax,如图5所示。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第5张图片 图5

我们看到从映射层到输出有一颗二叉树,他的根节点就是映射层对应的输出,叶子节点就是该语料所有的单词,依据单词出现的频率以及一个计算公式,为每个单词赋一个权重,然后构成哈夫曼树。

从映射层出来的向量从根节点开始,利用该节点的参数θ,以及sigmoid的想法确定接下来往左节点走,还是往右节点走,上图所示红色路径即为一次路径的行走。但其实层次softmax要计算所有节点,一直计算到叶子节点,这时候来一个softmax,便可得到每个单词的概率。

当然要使我们目标单词的概率最大啊,所以就可以计算残差,传播,balabala。。。

3.3 负抽样(Negative Sampling)

负抽样不采用复杂的Huffman树,而是利用相对简单的随机负采样,能大幅提高性能,因而可以作为层次Softmax的一种替代。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第6张图片

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第7张图片

Word2Vec这部分的原理学习,推荐学习peghoty大神的《Word2Vec中的数学原理》一文。

3.4 目标函数

CBOW

Skip-gram

计算:

sigmoid:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第8张图片

例如:

然后:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第9张图片

Word2Vec这部分的原理学习,推荐学习peghoty大神的《Word2Vec中的数学原理》一文。

3.5 实验

接下来就是实验部分。Word2vec的实现除了google官方的c写的,还有其他语言版本的实现,比较好的有python版的gensim。本实验分别对c实现的,和python实现的Word2Vec进行了实验。在c上使用的是英文语料,在python上使用了中文语料。可以从google官网上下载c的源码,地址:http://word2vec.googlecode.com/svn/trunk/(需要科学上网)。gensim是其他人依据原理实现的python版word2vec,当然目前gensim已经不止这一个功能,已经成为一个强大的nlp语义分析的软件包,里面集成了很多有意思的API,大家可以到这里来看:http://radimrehurek.com/gensim/apiref.html。

3.5.1 C实现的Word2Vec实验

如图6所示是从google上下载下来的c实现的Word2Vec的所有文件,可以看到里面有几个demo脚本可以用来演示。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第10张图片 图6

首先得在源码所在文件中make编译。

      

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第11张图片 图7

里面有许多警告如图7所示,先不管。

图8所示是跑了一个Word2Vec自带的简单的demo。进入到word2vec的trunk目录下,输入./demo-word.sh。经过短暂的训练后,要求输入一个单词或句子,我输入了cat,然后反回了cosine距离最相近的单词,可以看到结果还是不错的。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第12张图片 图8

如图9和图10所示为demo-word.sh内的不同参数设置的代码,可以看到由三部分组成,第一部分是下载text8英文语料,第二步是训练词向量,第三部是计算词向量距离。各个参数的定义如下:

-tran text8 //输入文件(训练语料)为text8

-output vectors.bin //输出文件为vectors.bin

-cbow 1 //使用cbow模型,默认为skip-gram

-size 200 //每个单词的向量维度是200

-window 8 //训练窗口大小,前有8个单词,后有8个单词

-negative 25 -hs 0 //如果使用neg负抽样方法,neg的数字代表应该抽多少样,抽25000

-sample 1e-4 //采样阈值,如果一个词在训练样本中出现的频率越大,就越会被采样

-threads 20 //线程数

-binary 1 //二进制存储,如果是0就是普通存储,普通存储可以用文本编辑器打开直接看到向量

-iter 15 //迭代次数

另外几个参数也是可以加入和设置的:

-alpha //设置学习率,默认为0.025

-min-count //设置最低单词频次,默认是5,低于这个数值即丢弃

【注】对于参数选择,提几个众所周知的事实:

    架构:skip-gram(训练速度超级慢、对罕见字效果更好) vs CBOW(速度快)

    训练算法:hs(层次softmax,对罕见字效果好) vs  ng(负抽样,对常见词和低维向量有利)

    采样阈值:可以提高结果的准确性和速度(适用范围1e-3到1e-5)

    窗大小:skip-gram在10左右,CBOW在5附近

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第13张图片 图9

接下来使用我自己设置的参数训练新的词向量,并计算单词的cosine距离,找到相似单词。首先新建一个文件,后缀为.sh。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第14张图片

参数的设置如下:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第15张图片 图10

然后添加执行权限,就成了一个可执行的.sh文件。

运行该脚本文件。我输入了cat和fuck两个单词进行了测试,结果如图11和图12所示。可以看到效果还不错。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第16张图片 图11
(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第17张图片 图12

图13所示为我的参数设置下,训练出来的词向量(-biary 0,100维的向量)。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第18张图片 图13

 

以上只是其中的一个demo方式,w2v还有很多其他的分析工具和demo,具体的可以通过demo中或者从官网上的使用手册学习。

ps:skip-gram的训练真的是非常慢,简直是龟速。

3.5.2 gensim上的实验

本节在gensim上进行了中文语料的词向量实验。中文需要分词,所以首先将gensim和jieba分词安装好。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第19张图片

从网上下载的《三生三世十里桃花》小说txt文件作为语料。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第20张图片 图14

中文语料下载下来后,通过python打开经常会发生乱码问题(主要原因是中文文本有事编码按照gbk,而英文主要用utf-8),所以先要解决乱码的问题,图14是解决好之后正常显示的文本。

按照以下三个方法,分别改变vim读取文本的编码、及文本本身的编码方式的方法:

1 在vim中查看文件编码,如图15所示,在vim中直接输入

:set fileencoding

可以查看编码格式

:set fileencoding=cp936

可以直接将vim编码格式转为cp936(或者输入其他格式转为其他格式读取文本)

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第21张图片 图15

    如图15做下角所示(fineencoding=latin1),由于vim找不到合适的编码(默认用utf-8打开所有文本),就用latin-1(ASCII)编码打开该文件了。接下来解决vim打开中文文本乱码的问题。

    直接在vim中输入

:version(不行的话就去掉空格)

可以查看本机vim的vimrc所在的路径,例如图16所示。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第22张图片 图16

然后修改vimrc,需要有root权限,找到vimrc所在路径

sudo vim vimrc

如果想要解决vim查看文件编码格式的问题,那么在vimrc配置文件中添加

set encoding=utf-8 fieencodings=usc-bom,utf-8,cp936

便可以让vim自动识别文件编码,按照fileencoding提供的列表进行尝试,如果还是没有找到,那么vim还是会用latin-1打开文件。

然后再用vim查看文件时,已不乱码,如图17左下角所示,编码方式已变为cp936。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第23张图片 图17

2 enca查看文件编码格式,非常迅速准确

无论如何建议输入文本都是utf-8,所以都需要对文本本身的编码进行修改。首先使用enca查看文件编码格式。如图18所示,该文本是以GB2312编码的。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第24张图片 图18

3 文本文件的编码格式的转换

在vim中直接:set fileencoding=utf-8,然后:wq保存退出

再看文件格式

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第25张图片 图19

也可以使用iconv命令转换

iconv -f UTF-8 -t GBK file1 -o file2 (file1是input,file2是转换后的output)

关于使用python设置读取文件格式的问题:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第26张图片 图20

encoding参数设置可以正常加入,不加入默认是utf-8编码。在中文语料还没有从gbk转换到utf-8时我做了一个实验,python读取文件的代码没有加encoding参数设置时,

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第27张图片

加了encoding参数设置时

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第28张图片

可以看到在这里gbk也可以读入中文语料。读入中文语料接下来就是对语料的中文分词和去掉不需要字符、停用词和不正常字符的预处理了。去掉一些字符这里使用的是正则表达式,这块我学了好久,不过还是学会使用re.sub使用正则表达式进行替换了。

我写了一个demo.py,如图21所示,当时截图的时候像素 比较渣。。。原文件也找不到了。。将就着看吧。(早期代码忘了替换停用词表和不正常字符了。。。那时候还不懂)

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第29张图片 图21

最终整体代码如 图22所示。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第30张图片 图22

关于gensim对于word2vec模型训练的参数设置官网上都有描述,截图如下:

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第31张图片

接下来对几个词进行了测试,结果如图23所示,除了浅浅还看得过去。。其他几个效果好像没有那么好。。。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第32张图片 图23

但是在单独计算相似度时,发现“白浅”和“浅浅”相似度要比上面列出来的第一个“位”的相似度高,经过分析后我才发现是我代码里写的函数搞错了。。。这个函数是计算类似于positive=x,y,negative=z,计算与x+y-z相似的单词的。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第33张图片

而且不太准确的原因有可能是语料太小的原因,以及这是一篇网络小说,文本格式上不太规范,jieba分词有许多失误(最近有好多新的分词方法,大家不妨一试)。

4 GloVe

glove是斯坦福大学提出的一种新的词矩阵的生成的方法,综合运用词的全局统计信息和局部统计信息来生成语言模型和词向量。利用global word co-occurrence信息提升词向量学习效果。项目主页在:http://nlp.stanford.edu/projects/glove/。

4.1 原理解析

glove全称是用于词表征的全局向量(Global Vectors for Word Representation ),单词的词-词共现矩阵是一个很重要的信息也很容易统计出来的信息,但之前人们都不知道该如何利用这一宝贵的信息(如word2vec,缺乏对统计信息的利用,但这种方法对词义之间的关系把握很好;矩阵的方法优缺点与word2vec这样的方法正好相反),所以glove就利用了这个信息。

共现矩阵每个元素xij代表的是i单词在语境中与j单词共现的次数,xi就是i出现的次数,这个条件概率如表1所示。

(一)文本嵌入式表示方法实战(词、句和段落向量:Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)_第34张图片 表1

该论文的作者认为词向量学习的合适起点应该是共现概率的比例,而非概率本身。

例如:对于与冰相关,但与蒸汽不相关,比如固体,我们期望这个比率会大。再比方说,对于与蒸汽相关与冰无关,比如气体,这个比率应该会减小。都不相关或都相关则比率接近1。

这种比率的方法更好的区分相关的词及不相关的词,而且很好的区分两个相关的词。

作者从这种比率的重要性作为切入角度,成功的设计了glove的目标公式。

(。。。。。。未完结。。。。。。)

 

你可能感兴趣的:(自然语言处理,深度学习,人工智能,机器学习,python人生,linux,Word2Vec,GloVe,Paragraph2vec,FastText,DSSM)