大家好,又见面了,我是你们的朋友全栈君。
最近公司项目中涉及到给每个用户推荐app,而在app数据相关处理的过程中,将app变为了一个向量,最后再转变到一个用户用一个向量来表示,而这其中用到的关键技术就是Word2Vec!之前只是大概听过,现在系统性的总结一波~
首先来看看维基百科定义:
Word2vec:为一群用来产生词向量的相关模型。这些模型为浅层双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。 训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系。该向量为神经网络之隐藏层[1]。 Word2vec依赖skip-grams或连续词袋(CBOW)来建立神经词嵌入。Word2vec为托马斯·米科洛夫(Tomas Mikolov)在Google带领的研究团队创造。该算法渐渐被其他人所分析和解释[2][3]。
结合上述定义我们可以看到:
这时候不禁就会问一句,为什么要搞一个词向量?词汇为啥要表示成向量呢?
在下面介绍文本向量化的时候会涉及到分词,首先介绍下分词的基本原理。
文本无法直接参与建模进行后续分析,而转化成向量之后就可以进行!所以如何将文本变为向量就是一个大学问~
但归纳起来,可以理解为两种方式:
方式1:基于频数(词袋模型,BoW)的向量化表示
可以结合下面结果知道,这种方法本质还是one-hot,只不过这时候的1表示为频数!而不仅仅是表示有没有出现!
Python实现:
from sklearn.feature_extraction.text import CountVectorizer
vectorizer=CountVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
print (vectorizer.fit_transform(corpus))
(0, 4) 1
(0, 15) 2
(0, 3) 1
(0, 16) 1
(1, 3) 1
(1, 14) 1
(1, 6) 1
(1, 2) 1
(1, 9) 1
(1, 5) 1
(2, 7) 1
(2, 12) 1
(2, 0) 1
(2, 1) 1
(3, 15) 1
(3, 6) 1
(3, 5) 1
(3, 13) 1
(3, 17) 1
(3, 18) 1
(3, 11) 1
(3, 8) 1
(3, 10) 1
按位置定义的所有词汇如下:
print (vectorizer.fit_transform(corpus).toarray())
print('词向量的维度为: ', len(vectorizer.fit_transform(corpus).toarray()[0]))
print (vectorizer.get_feature_names())
[[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0]
[0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
[1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]
词向量的维度为: 19
['and', 'apple', 'car', 'china', 'come', 'in', 'is', 'love', 'papers', 'polupar', 'science', 'some', 'tea', 'the', 'this', 'to', 'travel', 'work', 'write']
方式2:基于Hash Trick的向量化表示
什么叫Hash Trick呢?为什么要用Hash Trick?
对比基于词频的向量化+Hash Trick后的向量化:
基于词频的向量化应用场景:
基于Hash Trick的向量化应用场景:
Python实现:
将上述19维的转变为6维
from sklearn.feature_extraction.text import HashingVectorizer
vectorizer2=HashingVectorizer(n_features = 6,norm = None)
print (vectorizer2.fit_transform(corpus))
(0, 1) 2.0
(0, 2) -1.0
(0, 4) 1.0
(0, 5) -1.0
(1, 0) 1.0
(1, 1) 1.0
(1, 2) -1.0
(1, 5) -1.0
(2, 0) 2.0
(2, 5) -2.0
(3, 0) 0.0
(3, 1) 4.0
(3, 2) -1.0
(3, 3) 1.0
(3, 5) -1.0
print (vectorizer2.fit_transform(corpus).toarray())
print('词向量的维度为: ', len(vectorizer2.fit_transform(corpus).toarray()[0]))
[[ 0. 2. -1. 0. 1. -1.]
[ 1. 1. -1. 0. 0. -1.]
[ 2. 0. 0. 0. 0. -2.]
[ 0. 4. -1. 1. 0. -1.]]
词向量的维度为: 6
方式3:基于TF-IDF的向量化表示
首先TF-IDF在之前的博客中小编已经介绍过,详情可以戳:机器学习 | TF-IDF和TEXT-RANK的区别
在此处,大概流程和上述1很类似,就是将词频换成了该词汇的TF-IDF得分!
至于为什么基于频数进行优化也很好理解,比如有些话中to很多,词频会很大,但其意义可能并不大,TF-IDF就可以有效解决这个问题!
Python实现:
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2 = TfidfVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
re = tfidf2.fit_transform(corpus)
print (re)
(0, 16) 0.4424621378947393
(0, 3) 0.348842231691988
(0, 15) 0.697684463383976
(0, 4) 0.4424621378947393
(1, 5) 0.3574550433419527
(1, 9) 0.45338639737285463
(1, 2) 0.45338639737285463
(1, 6) 0.3574550433419527
(1, 14) 0.45338639737285463
(1, 3) 0.3574550433419527
(2, 1) 0.5
(2, 0) 0.5
(2, 12) 0.5
(2, 7) 0.5
(3, 10) 0.3565798233381452
(3, 8) 0.3565798233381452
(3, 11) 0.3565798233381452
(3, 18) 0.3565798233381452
(3, 17) 0.3565798233381452
(3, 13) 0.3565798233381452
(3, 5) 0.2811316284405006
(3, 6) 0.2811316284405006
(3, 15) 0.2811316284405006
向量维度以及各维度表示的含义为:
tfidf2.get_feature_names()
['and',
'apple',
'car',
'china',
'come',
'in',
'is',
'love',
'papers',
'polupar',
'science',
'some',
'tea',
'the',
'this',
'to',
'travel',
'work',
'write']
print('词向量的维度为: ', len(tfidf2.fit_transform(corpus).toarray()[0]))
tfidf2.fit_transform(corpus).toarray()
词向量的维度为: 19
array([[0. , 0. , 0. , 0.34884223, 0.44246214,
0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0.69768446, 0.44246214, 0. , 0. ],
[0. , 0. , 0.4533864 , 0.35745504, 0. ,
0.35745504, 0.35745504, 0. , 0. , 0.4533864 ,
0. , 0. , 0. , 0. , 0.4533864 ,
0. , 0. , 0. , 0. ],
[0.5 , 0.5 , 0. , 0. , 0. ,
0. , 0. , 0.5 , 0. , 0. ,
0. , 0. , 0.5 , 0. , 0. ,
0. , 0. , 0. , 0. ],
[0. , 0. , 0. , 0. , 0. ,
0.28113163, 0.28113163, 0. , 0.35657982, 0. ,
0.35657982, 0.35657982, 0. , 0.35657982, 0. ,
0.28113163, 0. , 0.35657982, 0.35657982]])
可以看到此时to就没有this重要,虽然频数大!
方式4:Word2vec
归结起来,Word2vec为2种模型+2种求解优化方法,故总共为4种方案,下面在数学原理篇将进行详细介绍!
首先在Word2vec之前已经有两种模型在做词向量的工作,那就是CBOW和Skip-Gram,而Word2vec就是在这个基础上加入了两种优化方法:Hierarchical Softmax和Negative Sampling,于是就产生了4种Word2vec模型:
模型作用:用来训练产生词向量
举例:
最后前向计算预测的时候,
最后前向计算预测的时候,
Word2vec数据结构是用霍夫曼树来代替隐藏层和输出层的神经元
优化1:对于从输入层到隐藏层的映射,没有采取神经网络的线性变换加激活函数的方法,而是采用
优化2:从隐藏层到输出的softmax层这里的计算量改进。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145420.html原文链接:https://javaforall.cn