『壹』 word2vec需要做哪些文本预处理
1.相似词查找 2.词的特征扩充 在term weight 里很有用 3.关系挖掘 4.序列点击数据的分析 5.相关词挖掘 用在品牌词和品牌相似词挖掘中 7.作为系列的初始化输入特征 8,模型简单,效率高,易调参。
『贰』 word2vec有什么应用
我觉得word2vec在工业上或者是网络上还是有很多应用的。
理解这种学术工具,重要的是搞懂它背后的道理和设计哲学。
很多人对word2vec不是了解,不知道word2vec是什么,其实word2vec是一个将单词转换成向量形式的工具,通过转换,可以把文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,这在实际应用中就有很大的价值。
word2vec在多方面的应用上还是很多的。
『叁』 如何使用word2vec批处理多个文本
string为你需要获取向量的词,
double[]
array
=
vec.getWordVector(string);
array是这个词的向量。
首先在创建vec的时候要保证.minWordFrequency(1),否则有些词你是得不到向量的,这个方法是设置词的最小
使用频率
。
『肆』 Word2Vec原理详解
自然语言是一套用来表达含义的复杂系统。在这套系统中,词是表义的基本单元。顾名思义,词向量是用来表示词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌入(word embedding)。近年来,词嵌入已逐渐成为自然语言处理的基础知识。
跳字模型假设基于某个词来生成它在文本序列周围的词。举个例子,假设文本序列是“the” “man” “loves” “his” “son”。以“loves”作为中心词,设背景窗口大小为2。如图1所示,跳字模型所关心的是,给定中心词“loves”,生成与它距离不超过2个词的背景词“the” “man” “his” “son”的条件概率,即
假设给定中心词的情况下,背景词的生成是相互独立的,那么上式可以改写成
虽然开篇说了one-hot不行,但是我们不要忽略一个事实,计算机没办法识别“字符”,所有的数据必须转化成二进制的编码形式。
大家已经注意到,我们已经到了Hidden Layer到Output Layer这一层了,简单来看就是隐藏层和输出层进行全连接,然后是一个softmax,输出概率。过程比较简单,一个Forward Propagation,一个Backward Propagation。
在跳字模型中,每个词被表示成两个 维向量,用来计算条件概率。假设这个词在词典中索引为 ,当它为中心词时向量表示为 ,而为背景词时向量表示为 。设中心词 在词典中索引为 ,背景词 ,在词典中索引为 ,给定中心词生成背景词的条件概率可以通过对向量内积做softmax运算而得到:
其中词典索引集 。假设给定一个长度为 的文本序列,设时间步 的词为 。假设给定中心词的情况下背景词的生成相互独立,当背景窗口大小为 时,跳字模型的似然函数即给定任一中心词生成所有背景词的概率
这里小于1和大于 的时间步可以忽略。
这样就可以计算出每个中心词推断背景词的概率,而我们在输入的时候给出了背景词的向量,此时只需要最大化背景词的输出概率即可。 基于这样的想法,我们会想到极大化似然估计的方式。但是一个函数的最大值往往不容易计算,因此,我们可以通过对函数进行变换,从而改变函数的增减性,以便优化。这等价于最小化以下损失函数:
最小化损失函数,我们最容易想到的就是梯度下降法。在使用梯度下降法之前,我们要把我们的损失函数定义出来,毕竟上面的式子是一个概率,下面把softmax的计算结果带入得到:
损失函数已经得到了,我们的目标就是最小化它,优化它之前我们要搞清楚我们的参数是谁?每错,我们的参数是中心词和背景词,那对于这样的一个函数显然是非凸函数,因此,我们要做一个假设,假设在对中心词权重更新时,背景词的权重是固定的,然后在以同样的方式来更新背景词的权重。
这里就计算出来了中心词的梯度,可以根据这个梯度进行迭代更新。对于背景词的更新是同样的方法,
当 时,即通过中心词 我们可以正确预测上下文词 时,不需要调整 ,反之,则相应调整 。
但是要注意背景词的个数不是唯一的,所以更新的时候要逐个更新,幅图辅助理解。
连续词袋模型与跳字模型类似。与跳字模型最大的不同在于,连续词袋模型假设基于某中心词在文本序列前后的背景词来生成中心词。在同样的文本序列“the” “man” “loves” “his” “son”里,以“loves”作为中心词,且背景窗口大小为2时,连续词袋模型关心的是,给定背景词“the” “man” “his” “son”生成中心词“loves”的条件概率(如图2所示),也就是
因为连续词袋模型的背景词有多个,我们将这些背景词向量取平均,然后使用和跳字模型一样的方法来计算条件概率。设 和 分别表示词典中索引为 的词作为背景词和中心词的向量(注意符号的含义与跳字模型中的相反,假设输入向量为 ,输出向量为 )。设中心词 在词典中索引为 ,背景词 在词典中索引为 ,那么给定背景词生成中心词的条件概率
为了让符号更加简单,我们记 ,且 ,那么上式可以简写成
给定一个长度为 的文本序列,设时间步t的词为 ,背景窗口大小为 。连续词袋模型的似然函数是由背景词生成任一中心词的概率
训练连续词袋模型同训练跳字模型基本一致。连续词袋模型的最大似然估计等价于最小化损失函数
注意到
通过微分,我们可以计算出上式中条件概率的对数有关任一背景词向量 的梯度
中心词的梯度同理可得,
同跳字模型不一样的一点在于,我们一般使用连续词袋模型的背景词向量作为词的表征向量。
『伍』 word2vector是什么与传统one-hot向量比起来好在那里
z=x + y i
x=2t
y=1
即直线方程为: y=1
这就是复数平面上的路径C对应的直线方程.
z=(1-t)i + t(2+i),
这种表述方法, 除了可以用前面的方法解释, 还有特殊的含义.
由于直线通过点 z1=i和 z1 = 2+i
z必定是关于某个参数(此处可设为t)的线性表达式.
可设 z=i(a+bt) + (2+i)(c+dt)
令t=0时, z=z1. 则 ia + (2+i)c=i => c=0, a=1
令t=1时, z=z2, 则i(a+b)+(2+i)(c+d)=i(1+b)+(2+i)d=2d+(1+b+d)i=2+i
=> d=1, b=-1
z=(1-t)i + (2+i)t
这刚好就是原题中的公式.
『陆』 推荐算法简介
写在最前面:本文内容主要来自于书籍《推荐系统实践》和《推荐系统与深度学习》。
推荐系统是目前互联网世界最常见的智能产品形式。从电子商务、音乐视频网站,到作为互联网经济支柱的在线广告和新颖的在线应用推荐,到处都有推荐系统的身影。推荐算法是推荐系统的核心,其本质是通过一定的方式将用户和物品联系起来,而不同的推荐系统利用了不同的方式。
推荐系统的主要功能是以个性化的方式帮助用户从极大的搜索空间中快速找到感兴趣的对象。因此,目前所用的推荐系统多为个性化推荐系统。个性化推荐的成功应用需要两个条件:
在推荐系统的众多算法中,基于协同的推荐和基于内容的推荐在实践中得到了最广泛的应用。本文也将从这两种算法开始,结合时间、地点上下文环境以及社交环境,对常见的推荐算法做一个简单的介绍。
基于内容的算法的本质是对物品内容进行分析,从中提取特征,然后基于用户对何种特征感兴趣来推荐含有用户感兴趣特征的物品。因此,基于内容的推荐算法有两个最基本的要求:
下面我们以一个简单的电影推荐来介绍基于内容的推荐算法。
现在有两个用户A、B和他们看过的电影以及打分情况如下:
其中问好(?)表示用户未看过。用户A对《银河护卫队 》《变形金刚》《星际迷航》三部科幻电影都有评分,平均分为 4 .7 分 ( (5+4+5 ) / 3=4.7 );对《三生三世》《美人鱼》《北京遇上西雅图》三部爱情电影评分平均分为 2.3 分 ( ( 3十2+2 ) /3=2.3 )。现在需要给A推荐电影,很明显A更倾向于科幻电影,因此推荐系统会给A推荐独立日。而对于用户B,通过简单的计算我们可以知道更喜欢爱情电影,因此给其推荐《三生三世》。当然,在实际推荐系统中,预测打分比这更加复杂些,但是其原理是一样的。
现在,我们可以将基于内容的推荐归纳为以下四个步骤:
通过上面四步就能快速构建一个简单的推荐系统。基于内容的推荐系统通常简单有效,可解释性好,没有物品冷启动问题。但他也有两个明显的缺点:
最后,顺便提一下特征提取方法:对于某些特征较为明确的物品,一般可以直接对其打标签,如电影类别。而对于文本类别的特征,则主要是其主题情感等,则些可以通过tf-idf或LDA等方法得到。
基于协同的算法在很多地方也叫基于邻域的算法,主要可分为两种:基于用户的协同算法和基于物品的协同算法。
啤酒和尿布的故事在数据挖掘领域十分有名,该故事讲述了美国沃尔玛超市统计发现啤酒和尿布一起被购买的次数非常多,因此将啤酒和尿布摆在了一起,最后啤酒和尿布的销量双双增加了。这便是一个典型的物品协同过滤的例子。
基于物品的协同过滤指基于物品的行为相似度(如啤酒尿布被同时购买)来进行物品推荐。该算法认为,物品A和物品B具有很大相似度是因为喜欢物品A的用户大都也喜欢物品B。
基于物品的协同过滤算法主要分为两步:
基于物品的协同过滤算法中计算物品相似度的方法有以下几种:
(1)基于共同喜欢物品的用户列表计算。
此外,John S. Breese再其论文中还提及了IUF(Inverse User Frequence,逆用户活跃度)的参数,其认为活跃用户对物品相似度的贡献应该小于不活跃的用户,应该增加IUF参数来修正物品相似度的公式:
上面的公式只是对活跃用户做了一种软性的惩罚, 但对于很多过于活跃的用户, 比如某位买了当当网80%图书的用户, 为了避免相似度矩阵过于稠密, 我们在实际计算中一般直接忽略他的兴趣列表, 而不将其纳入到相似度计算的数据集中。
(2)基于余弦相似度计算。
(3)热门物品的惩罚。
从上面(1)的相似度计算公式中,我们可以发现当物品 i 被更多人购买时,分子中的 N(i) ∩ N(j) 和分母中的 N(i) 都会增长。对于热门物品,分子 N(i) ∩ N(j) 的增长速度往往高于 N(i),这就会使得物品 i 和很多其他的物品相似度都偏高,这就是 ItemCF 中的物品热门问题。推荐结果过于热门,会使得个性化感知下降。以歌曲相似度为例,大部分用户都会收藏《小苹果》这些热门歌曲,从而导致《小苹果》出现在很多的相似歌曲中。为了解决这个问题,我们对于物品 i 进行惩罚,例如下式, 当α∈(0, 0.5) 时,N(i) 越小,惩罚得越厉害,从而使热门物品相关性分数下降( 博主注:这部分未充分理解 ):
此外,Kary pis在研究中发现如果将ItemCF的相似度矩阵按最大值归一化, 可以提高推荐的准确率。 其研究表明, 如果已经得到了物品相似度矩阵w, 那么可以用如下公式得到归一化之后的相似度矩阵w':
归一化的好处不仅仅在于增加推荐的准确度,它还可以提高推荐的覆盖率和多样性。一般来说,物品总是属于很多不同的类,每一类中的物品联系比较紧密。假设物品分为两类——A和B, A类物品之间的相似度为0.5, B类物品之间的相似度为0.6, 而A类物品和B类物品之间的相似度是0.2。 在这种情况下, 如果一个用户喜欢了5个A类物品和5个B类物品, 用ItemCF给他进行推荐, 推荐的就都是B类物品, 因为B类物品之间的相似度大。 但如果归一化之后, A类物品之间的相似度变成了1, B类物品之间的相似度也是1, 那么这种情况下, 用户如果喜欢5个A类物品和5个B类物品, 那么他的推荐列表中A类物品和B类物品的数目也应该是大致相等的。 从这个例子可以看出, 相似度的归一化可以提高推荐的多样性。
那么,对于两个不同的类,什么样的类其类内物品之间的相似度高,什么样的类其类内物品相似度低呢?一般来说,热门的类其类内物品相似度一般比较大。如果不进行归一化,就会推荐比较热门的类里面的物品,而这些物品也是比较热门的。因此,推荐的覆盖率就比较低。相反,如果进行相似度的归一化,则可以提高推荐系统的覆盖率。
最后,利用物品相似度矩阵和用户打过分的物品记录就可以对一个用户进行推荐评分:
基于用户的协同算法与基于物品的协同算法原理类似,只不过基于物品的协同是用户U购买了A物品,会计算经常有哪些物品与A一起购买(也即相似度),然后推荐给用户U这些与A相似的物品。而基于用户的协同则是先计算用户的相似性(通过计算这些用户购买过的相同的物品),然后将这些相似用户购买过的物品推荐给用户U。
基于用户的协同过滤算法主要包括两个步骤:
步骤(1)的关键是计算用户的兴趣相似度,主要是利用用户的行为相似度计算用户相似度。给定用户 u 和 v,N(u) 表示用户u曾经有过正反馈(譬如购买)的物品集合,N(v) 表示用户 v 曾经有过正反馈的物品集合。那么我们可以通过如下的 Jaccard 公式简单的计算 u 和 v 的相似度:
或通过余弦相似度:
得到用户之间的相似度之后,UserCF算法会给用户推荐和他兴趣最相似的K个用户喜欢的物品。如下的公式度量了UserCF算法中用户 u 对物品 i 的感兴趣程度:
首先回顾一下UserCF算法和ItemCF算法的推荐原理:UserCF给用户推荐那些和他有共同兴趣爱好的用户喜欢的物品, 而ItemCF给用户推荐那些和他之前喜欢的物品具有类似行为的物品。
(1)从推荐场景考虑
首先从场景来看,如果用户数量远远超过物品数量,如购物网站淘宝,那么可以考虑ItemCF,因为维护一个非常大的用户关系网是不容易的。其次,物品数据一般较为稳定,因此物品相似度矩阵不必频繁更新,维护代价较小。
UserCF的推荐结果着重于反应和用户兴趣相似的小群体的热点,而ItemCF的推荐结果着重于维系用户的历史兴趣。换句话说,UserCF的推荐更社会化,反应了用户所在小型兴趣群体中物品的热门程度,而ItemCF的推荐更加个性化,反应了用户自己的个性传承。因此UserCF更适合新闻、微博或微内容的推荐,而且新闻内容更新频率非常高,想要维护这样一个非常大而且更新频繁的表无疑是非常难的。
在新闻类网站中,用户的兴趣爱好往往比较粗粒度,很少会有用户说只看某个话题的新闻,而且往往某个话题也不是每天都会有新闻。 个性化新闻推荐更强调新闻热点,热门程度和时效性是个性化新闻推荐的重点,个性化是补充,所以 UserCF 给用户推荐和他有相同兴趣爱好的人关注的新闻,这样在保证了热点和时效性的同时,兼顾了个性化。
(2)从系统多样性(也称覆盖率,指一个推荐系统能否给用户提供多种选择)方面来看,ItemCF的多样性要远远好于UserCF,因为UserCF更倾向于推荐热门物品。而ItemCF具有较好的新颖性,能够发现长尾物品。所以大多数情况下,ItemCF在精度上较小于UserCF,但其在覆盖率和新颖性上面却比UserCF要好很多。
在介绍本节基于矩阵分解的隐语义模型之前,让我们先来回顾一下传统的矩阵分解方法SVD在推荐系统的应用吧。
基于SVD矩阵分解在推荐中的应用可分为如下几步:
SVD在计算前会先把评分矩阵 A 缺失值补全,补全之后稀疏矩阵 A 表示成稠密矩阵,然后将分解成 A' = U∑V T 。但是这种方法有两个缺点:(1)补成稠密矩阵后需要耗费巨大的储存空间,对这样巨大的稠密矩阵进行储存是不现实的;(2)SVD的计算复杂度很高,对这样大的稠密矩阵中进行计算式不现实的。因此,隐语义模型就被发明了出来。
更详细的SVD在推荐系统的应用可参考 奇异值分解SVD简介及其在推荐系统中的简单应用 。
隐语义模型(Latent Factor Model)最早在文本挖掘领域被提出,用于找到文本的隐含语义。相关的算法有LSI,pLSA,LDA和Topic Model。本节将对隐语义模型在Top-N推荐中的应用进行详细介绍,并通过实际的数据评测该模型。
隐语义模型的核心思想是通过隐含特征联系用户兴趣和物品。让我们通过一个例子来理解一下这个模型。
现有两个用户,用户A的兴趣涉及侦探小说、科普图书以及一些计算机技术书,而用户B的兴趣比较集中在数学和机器学习方面。那么如何给A和B推荐图书呢?
我们可以对书和物品的兴趣进行分类。对于某个用户,首先得到他的兴趣分类,然后从分类中挑选他可能喜欢的物品。简言之,这个基于兴趣分类的方法大概需要解决3个问题:
对于第一个问题的简单解决方案是找相关专业人员给物品分类。以图书为例,每本书出版时,编辑都会给出一个分类。但是,即使有很系统的分类体系,编辑给出的分类仍然具有以下缺点:(1)编辑的意见不能代表各种用户的意见;(2)编辑很难控制分类的细粒度;(3)编辑很难给一个物品多个分类;(4)编辑很难给一个物品多个分类;(5)编辑很难给出多个维度的分类;(6)编辑很难决定一个物品在某一个类别中的权重。
为了解决上述问题,研究员提出可以从数据出发,自动找到那些分类,然后进行个性化推荐。隐语义模型由于采用基于用户行为统计的自动聚类,较好地解决了上面提出的5个问题。
LFM将矩阵分解成2个而不是3个:
推荐系统中用户和物品的交互数据分为显性反馈和隐性反馈数据。隐式模型中多了一个置信参数,具体涉及到ALS(交替最小二乘法,Alternating Least Squares)中对于隐式反馈模型的处理方式——有的文章称为“加权的正则化矩阵分解”:
一个小细节:在隐性反馈数据集中,只有正样本(正反馈)没有负反馈(负样本),因此如何给用户生成负样本来进行训练是一个重要的问题。Rong Pan在其文章中对此进行了探讨,对比了如下几种方法:
用户行为很容易用二分图表示,因此很多图算法都可以应用到推荐系统中。基于图的模型(graph-based model)是推荐系统中的重要内容。很多研究人员把基于领域的模型也称为基于图的模型,因为可以把基于领域的模型看作基于图的模型的简单形式。
在研究基于图的模型之前,需要将用户行为数据表示成图的形式。本节的数据是由一系列用户物品二元组 (u, i) 组成的,其中 u 表示用户对物品 i 产生过行为。
令 G(V, E) 表示用户物品二分图,其中 V=V U UV I 由用户顶点 V U 和物品节点 V I 组成。对于数据集中每一个二元组 (u, i) ,图中都有一套对应的边 e(v u , v i ),其中 v u ∈V U 是用户对应的顶点,v i ∈V I 是物品i对应的顶点。如下图是一个简单的物品二分图,其中圆形节点代表用户,方形节点代表物品,用户物品的直接连线代表用户对物品产生过行为。比如下图中的用户A对物品a、b、d产生过行为。
度量图中两个顶点之间相关性的方法很多,但一般来说图中顶点的相关性主要取决于下面3个因素:
而相关性高的一对顶点一般具有如下特征:
举个例子,如下图,用户A和物品c、e没有边直连,但A可通过一条长度为3的路径到达c,而Ae之间有两条长度为3的路径。那么A和e的相关性要高于顶点A和c,因而物品e在用户A的推荐列表中应该排在物品c之前,因为Ae之间有两条路径。其中,(A,b,C,e)路径经过的顶点的出度为(3,2,2,2),而 (A,d,D,e) 路径经过了一个出度比较大的顶点D,所以 (A,d,D,e) 对顶点A与e之间相关性的贡献要小于(A,b,C,e)。
基于上面3个主要因素,研究人员设计了很多计算图中顶点相关性的方法,本节将介绍一种基于随机游走的PersonalRank算法。
假设要给用户u进行个性化推荐,可以从用户u对应的节点 v u 开始在用户物品二分图上进行随机游走。游走到任一节点时,首先按照概率α决定是继续游走还是停止这次游走并从 v u 节点重新开始游走。若决定继续游走,则从当前节点指向的节点中按照均匀分布随机选择一个节点作为游走下次经过的节点。这样,经过很多次随机游走后,每个物品被访问到的概率会收敛到一个数。最终的推荐列表中物品的权重就是物品节点的访问概率。
上述算法可以表示成下面的公式:
虽然通过随机游走可以很好地在理论上解释PersonalRank算法,但是该算法在时间复杂度上有明显的缺点。因为在为每个用户进行推荐时,都需要在整个用户物品二分图上进行迭代,知道所有顶点的PR值都收敛。这一过程的时间复杂度非常高,不仅无法在线进行实时推荐,离线计算也是非常耗时的。
有两种方法可以解决上面PersonalRank时间复杂度高的问题:
(1)减少迭代次数,在收敛之前停止迭代。但是这样会影响最终的精度。
(2)从矩阵论出发,重新涉及算法。另M为用户物品二分图的转移概率矩阵,即:
网络社交是当今社会非常重要甚至可以说是必不可少的社交方式,用户在互联网上的时间有相当大的一部分都用在了社交网络上。
当前国外最著名的社交网站是Facebook和Twitter,国内的代表则是微信/QQ和微博。这些社交网站可以分为两类:
需要指出的是,任何一个社交网站都不是单纯的社交图谱或兴趣图谱。如QQ上有些兴趣爱好群可以认识不同的陌生人,而微博中的好友也可以是现实中认识的。
社交网络定义了用户之间的联系,因此可以用图定义社交网络。我们用图 G(V,E,w) 定义一个社交网络,其中V是顶点集合,每个顶点代表一个用户,E是边集合,如果用户va和vb有社交网络关系,那么就有一条边 e(v a , v b ) 连接这两个用户,而 w(v a , v b )定义了边的权重。一般来说,有三种不同的社交网络数据:
和一般购物网站中的用户活跃度分布和物品流行度分布类似,社交网络中用户的入度(in degree,表示有多少人关注)和出度(out degree,表示关注多少人)的分布也是满足长尾分布的。即大部分人关注的人都很少,被关注很多的人也很少。
给定一个社交网络和一份用户行为数据集。其中社交网络定义了用户之间的好友关系,而用户行为数据集定义了不同用户的历史行为和兴趣数据。那么最简单的算法就是给用户推荐好友喜欢的物品集合。即用户u对物品i的兴趣 p ui 可以通过如下公式计算。
用户u和用户v的熟悉程度描述了用户u和用户在现实社会中的熟悉程度。一般来说,用户更加相信自己熟悉的好友的推荐,因此我们需要考虑用户之间的熟悉度。下面介绍3中衡量用户熟悉程度的方法。
(1)对于用户u和用户v,可以使用共同好友比例来计算他们的相似度:
上式中 out(u) 可以理解为用户u关注的用户合集,因此 out(u) ∩ out(v) 定义了用户u、v共同关注的用户集合。
(2)使用被关注的用户数量来计算用户之间的相似度,只要将公式中的 out(u) 修改为 in(u):
in(u) 是指关注用户u的集合。在无向社交网络中,in(u)和out(u)是相同的,而在微博这种有向社交网络中,这两个集合的含义就不痛了。一般来说,本方法适合用来计算微博大V之间的相似度,因为大v往往被关注的人数比较多;而方法(1)适用于计算普通用户之间的相似度,因为普通用户往往关注行为比较丰富。
(3)除此之外,还可以定义第三种有向的相似度:这个相似度的含义是用户u关注的用户中,有多大比例也关注了用户v:
这个相似度有一个缺点,就是在该相似度下所有人都和大v有很大的相似度,这是因为公式中的分母并没有考虑 in(v) 的大小,所以可以把 in(v) 加入到上面公式的分母,来降低大v与其他用户的相似度:
上面介绍了3种计算用户之间相似度(或称熟悉度)的计算方法。除了熟悉程度,还需要考虑用户之间的兴趣相似度。我们和父母很熟悉,但很多时候我们和父母的兴趣确不相似,因此也不会喜欢他们喜欢的物品。因此,在度量用户相似度时,还需要考虑兴趣相似度,而兴趣相似度可以通过和UserCF类似的方法度量,即如果两个用户喜欢的物品集合重合度很高,两个用户的兴趣相似度很高。
最后,我们可以通过加权的形式将两种权重合并起来,便得到了各个好有用户的权重了。
有了权重,我们便可以针对用户u挑选k个最相似的用户,把他们购买过的物品中,u未购买过的物品推荐给用户u即可。打分公式如下:
其中 w' 是合并后的权重,score是用户v对物品的打分。
node2vec的整体思路分为两个步骤:第一个步骤是随机游走(random walk),即通过一定规则随机抽取一些点的序列;第二个步骤是将点的序列输入至word2vec模型从而得到每个点的embedding向量。
随机游走在前面基于图的模型中已经介绍过,其主要分为两步:(1)选择起始节点;(2)选择下一节点。起始节点选择有两种方法:按一定规则抽取一定量的节点或者以图中所有节点作为起始节点。一般来说会选择后一种方法以保证所有节点都会被选取到。
在选择下一节点方法上,最简单的是按边的权重来选择,但在实际应用中需要通过广度优先还是深度优先的方法来控制游走范围。一般来说,深度优先发现能力更强,广度优先更能使社区内(较相似)的节点出现在一个路径里。
斯坦福大学Jure Leskovec教授给出了一种可以控制广度优先或者深度优先的方法。
以上图为例,假设第一步是从t随机游走到v,这时候我们要确定下一步的邻接节点。本例中,作者定义了p和q两个参数变量来调节游走,首先计算其邻居节点与上一节点t的距离d,根据下面的公式得到α:
一般从每个节点开始游走5~10次,步长则根据点的数量N游走根号N步。如此便可通过random walk生成点的序列样本。
得到序列之后,便可以通过word2vec的方式训练得到各个用户的特征向量,通过余弦相似度便可以计算各个用户的相似度了。有了相似度,便可以使用基于用户的推荐算法了。
推荐系统需要根据用户的历史行为和兴趣预测用户未来的行为和兴趣,因此大量的用户行为数据就成为推荐系统的重要组成部分和先决条件。如何在没有大量用户数据的情况下设计个性化推荐系统并且让用户对推荐结果满意从而愿意使用推荐系统,就是冷启动问题。
冷启动问题主要分为三类:
针对用户冷启动,下面给出一些简要的方案:
(1)有效利用账户信息。利用用户注册时提供的年龄、性别等数据做粗粒度的个性化;
(2)利用用户的社交网络账号登录(需要用户授权),导入用户在社交网站上的好友信息,然后给用户推荐其好友喜欢的物品;
(3)要求用户在登录时对一些物品进行反馈,手机用户对这些物品的兴趣信息,然后给用推荐那些和这些物品相似的物品;
(4)提供非个性化推荐。非个性化推荐的最简单例子就是热门排行榜,我们可以给用户推荐热门排行榜,然后等到用户数据收集到一定的时候,在切换为个性化推荐。
对于物品冷启动,可以利用新加入物品的内容信息,将它们推荐给喜欢过和他们相似的物品的用户。
对于系统冷启动,可以引入专家知识,通过一定高效的方式快速建立起物品的相关度表。
在上面介绍了一些推荐系统的基础算法知识,这些算法大都是比较经典且现在还在使用的。但是需要注意的是,在实践中,任何一种推荐算法都不是单独使用的,而是将多种推荐算法结合起来,也就是混合推荐系统,但是在这里并不准备介绍,感兴趣的可以查阅《推荐系统》或《推荐系统与深度学习》等书籍。此外,在推荐中非常重要的点击率模型以及基于矩阵的一些排序算法在这里并没有提及,感兴趣的也可自行学习。
虽然现在用的很多算法都是基于深度学习的,但是这些经典算法能够让我们对推荐系统的发展有一个比较好的理解,同时,更重要的一点——“推陈出新”,只有掌握了这些经典的算法,才能提出或理解现在的一些更好地算法。
『柒』 Word2vec原理详细解读
Softmax函数:
哈夫曼树(Huffman Tree)
从图1可以看出Skip-gram就是用当前中心词 (banking)预测附近的词,图1中将窗口大小设为2,即需要预测左边的2个词和右边的2个词。
对于每个位置 ,预测窗口大小为 的上下文,设当前中心词为 ,那么目标为最大化:
(1)
其中 为模型的参数。
为了将最大化转为最小化,可对 取负数,为了简化计算,可取对数:
(2)
现在问题的关键是如何计算 ,我们使用两个向量表示: 为中心词的表示, 为上下文词的表示。那么,计算中心词 c 和上下文词 o 的出现概率为:
(3)
其中,V为整个词表大小, 为中心词向量表示。其实式3就是softmax函数。
图2展示了Skip-gram的计算过程,从图中可以看出Skip-gram预测的是 , , ,由于只预测前后两个单词,因此窗口大小为2。
输入层到隐藏层 :输入层的中心词 用one-hot向量表示(维度为V*1,V为整个词表大小),输入层到隐藏层的权重矩阵为中心词矩阵W(维度为V*d,d为词向量维度),设隐含向量为 (维度为d*1),那么:
(4)
隐藏层到输出层: 隐藏层到输出层的上下文权重矩阵为U(维度为d*V),输出层为y(维度为V*1),那么:
(5)
注意 ,输出层的向量 y 与输出层的向量 虽然维度一样,但是 y 并不是one-hot向量,并且向量 y 的每一个元素都是有意义的。如,假设训练样本只有一句话”I like to eat apple”,此时我们正在使用eat去预测to,输出层结果如图3所示。
向量y中的每个元素表示用 I、like、eat、apple 四个词预测出来的词是对应的词的概率,比如是like的概率为0.05,是to的概率是0.80。由于我们想让模型预测出来的词是to,那么我们就要尽量让to的概率尽可能的大,所以我们将式子(1)作为最大化函数。
Continuous Bag-of-Words(CBOW),的计算示意图如图4所示。从图中可以看出,CBOW模型预测的是 ,由于目标词 只取前后的两个词,因此窗口大小为2。假设目标词 前后各取 个词,即窗口大小为 ,那么CBOW模型为:
(6)
输入层到隐藏层: 如图4所示,输入层为4个词的one-hot向量表示,分别为 , , , (维度都为V*1,V为整个词表大小),记输入层到隐藏层的上下文词的权重矩阵为W(维度为V*d,d是词向量维度),隐藏层的向量h(维度为d*1),那么:
(7)
这里就是把各个上下文词的向量查找出来,再进行简单的加和平均。
隐藏层到输出层: 记隐藏层到输出层的中心词权重矩阵为U(维度d*V),输出层的向量y(维度V*1),那么:
(8)
注意 ,输出层的向量 与输入层的 虽然维度一样,但是 并不是one-hot向量,并且向量 的每个元素都是有意义的。CBOW的目标是最大化函数:
(9)
由于softmax的分母部分计算代价很大,在实际应用时,一般采用层次softmax或者负采样替换掉输出层,降低计算复杂度。
层次softmax(Hierarchical Softmax)是一棵哈夫曼树,树的叶子节点是训练文本中所有的词,非叶子节点是一个逻辑回归二分类器,每个逻辑回归分类器的参数都不同,分别用 表示,假定分类器的输入为向量h,记逻辑回归分类器输出的结果为 将向量h传递给节点的左孩子概率为 ,否则传递给节点的右孩子概率为 。重复这个传递流程直到叶子节点。
从图5和图6可以看出,我们就是将隐藏层的向量h直接传递到了层次softmax,层次softmax的复杂度为O(log(V)),层次softmax采样到每个词的概率如下:
对于CBOW或者skip-gram模型,如果要预测的词是to,那么我们就让 尽量大,所以我们将任务转换成训练V-1个逻辑分类器。CBOW模型和skip-gram模型训练目标函数和之前形式一样,为:
(10)
(11)
负采样实际上是采样负例来帮助训练的手段,其目的与层次softmax一样,是用来提升模型的训练速度。我们知道,模型对正例的预测概率是越大越好,模型对负例的预测概率是越小越好。负采样的思路就是根据某种负采样的策略随机挑选一些负例,然后保证挑选的这部分负例的预测概率尽可能小。所以,负采样策略是对模型的效果影响很大,word2vec常用的负采样策略有均匀负采样、按词频率采样等等。
以“I like to eat apple”为例子,假设窗口的大小是2,当中心词为like时,即我们会用 I to 来预测like,所以在这里我们就认为(I,like)和(to,like)都是正例,而(I,apple)、(to,apple)就是负例,因为(I,apple)、(to,apple)不出现在当前正例中。用NEG(w)表示负样本,有:
(12)
(13)
这里的 是词*的中心词向量表示,h为隐藏层的输出向量。我们只需要最大化目标函数:
(14)
这个损失函数的含义就是让正例概率更大,负例的概率更小。
以“I like to eat apple”为例子,假设窗口的大小是1,即我们会用 like 来预测 I to,所以在这里我们就认为(like,I)和(like,to)都是正例,而(like,apple)就是负例,因为(like,apple)不会出现在正例中。那么,对于给定的正样本(w,context(w))和采样出的负样本(w,NEG(w)),有:
(15)
(16)
这里的 是词*的中心词向量表示,h为隐藏层的输出向量。我们只需要最大化目标函数:
(17)
word2vec常用的负采样策略有均匀负采样、按词频率采样等等。比较常用的采样方法是一元分布模型的3/4次幂。该方法中,一个词被采样的概率,取决于这个词在语料中的词频 ,其满足一元分布模型(Unigram Model).
(18)
其中V为整个词表大小, 为词 的词频。
至于为什么选择3/4呢?其实是由论文作者的经验所决定的。
假设由三个词,,”我“,”和平“,”觊觎“ 权重分别为 0.9 ,0.01,0.003;经过3/4幂后:
我: 0.9^3/4 = 0.92
和平:0.01^3/4 = 0.03
觊觎:0.003^3/4 = 0.012
对于”觊觎“而言,权重增加了4倍;”和平“增加3倍;”我“只有轻微增加。
可以认为:在保证高频词容易被抽到的大方向下,通过权重3/4次幂的方式, 适当提升低频词、罕见词被抽到的概率 。如果不这么做,低频词,罕见词很难被抽到,以至于不被更新到对应的Embedding。
Question&Answer
Question1: 如图7中,skip-gram模型中,从隐藏层到输出层,因为使用权值共享,所以会导致输出的几个上下文词向量总是完全一样,但网络的目的是要去预测上下文会出现的词,而实际中给定中心词的情况下上下文的词会五花八门。怎么解释skip gram的这种输出形式?
Answer1: 网络的目的不是要预测上下文会出现啥词,这只是一个fake task。实际上这个loss就是降不下来的,所以本来就不能用于真正预测上下文,而初衷也不是用于预测上下文,只是利用上下文信息去实现嵌入。
如果你的100W个句子都是”I really love machine learning and deep learning“,加上权值共享,结果就是给定machine以后,它输出really,love,learning,and这四个词的概率完全相同,这就意味着这四个词的词向量也是差不多的。正因为这样,语义相近的词,他们在空间上的映射才会接近。
Question2 : Word2Vec哪个矩阵是词向量?
Answer2: 如图7所示,中心词矩阵W,上下文矩阵W' 可以任意选一个作为词向量矩阵。但是,如果采用优化后(层次softmax)的模型,那么将不存在W',这种情况下只能选矩阵W。
三千多字,码字不易,如果大家发现我有地方写得不对或者有疑问的,麻烦评论, 我会回复并改正 。对于重要问题,我会持续更新至 Question&Answer。
参考:
[1] skip-gram的关键术语与详细解释
[2] 一篇浅显易懂的word2vec原理讲解
[3] CS224n:深度学习的自然语言处理(2017年冬季)1080p
[4] Stanford CS224N: NLP with Deep Learning | Winter 2019 | Lecture 2 – Word Vectors and
Word Senses
[5] 关于skip gram的输出?
[6] Le, Quoc V , and T. Mikolov . "Distributed Representationsof Sentences and Documents." (2014).
[7] Mikolov, T. . "Distributed Representations of Words andPhrases and their Compositionality." Advances in Neural InformationProcessing Systems 26(2013):3111-3119.
[8] Mikolov, Tomas , et al."Efficient Estimation of Word Representations in Vector Space." Computerence (2013).
[9] Goldberg, Yoav , and O. Levy . "word2vec Explained:deriving Mikolov et al.'s negative-sampling word-embedding method." arXiv(2014).
『捌』 word2vec模型之Skip-Gram Model
本文介绍一种基于神经网络结构的Word2Vec模型,Word2Vec是目前NLP领域的基础知识,这里仅对Word2Vec模型中的Skip-Gram模型进行详细介绍。
Skip-Gram神经网络模型是一种非常简单的神经网络结构,是一个仅有一个Hidden Layer的神经网络结构。Skip-Gram模型的训练过程可以视作一个“Fake Task(伪任务)”,为何称之为“Fake Task”?是因为训练该模型的目的并不是将训练好的模型用于任何的分类任务,而是为了学习得到隐层的权重矩阵,而通过这些矩阵我们会得到想要的单词的特征向量,总体框架入下图所示。下面详细介绍这个Skip-Gram模型的训练过程。
给定一个特定的word作为输入,我们从该word的附近随机挑选一个word,该网络模型会告诉我们词汇表中的每个单词出现在“附近”的概率。这里的“附近”指的是在特定window size范围内。输出概率与在输入词附近找到每个单词的可能性有关。这里,我们使用文本中指定window size内的word pair(inputword,outputword)来训练神经网络模型。word pairs的获取方式如下图所示。
这里详细介绍一下Skip-Gram模型的训练过程。首先,神经网络模型只接受数值型的输入,故不能直接将每个单词直接输入到一个神经网络中,故而需要一种针对神经网络模型的单词表示方式,为此需要针对训练集中的所有不同的单词构建一个词汇表(vocabulary),然后将词汇表中的每个单词以 One-Hot编码 的方式进行表示。比如,现在有一个大小为10000的词汇表,我们需要为每个单词构建一个One-Hot向量,要求每个单词对应的当前单词的位置为1,其他所有位置为0,因此我们会得到10000个长度为10000的向量,其中每个向量都只有一个位置为1。神经网络的输出是一个10000维的向量,表示针对输入单词,词汇表中所有的单词出现在输入单词附近的预测概率。如下图所示:
上述的神经网络结构隐层中的神经元没有激活函数,但输出层的每个神经元使用了softmax函数。训练的过程使用word pair(inputword,outputword),输入是一个One-Hot的向量,输出的也是一个表示输出单词的One-Hot的向量。但是当在一个输入词在训练好的网络上计算时,输出的向量实际上是一个概率分布,并不是一个One-Hot向量。因为每个输出的单元使用了 Softmax ,且没有激活函数。
同样的针对上述问题,有10000个单词,假设需要为每个单词学习一个300维的向量,那么隐层可以由一个10000*300的矩阵来表示(300个神经元,每个神经元都有一个10000维的权重向量),如下图所示。
竖着看这个隐层的权重矩阵,每一列对应一个神经元中的参数向量,而如果横着看这个权重矩阵,每一行就是一个300维的向量,而这这就是我们需要通过学习得来的词向量!也就是说,10000个单词的向量表示就是这个10000*300的矩阵,每行对应一个单词的向量表示。那么Skip-Gram最终的目的就是学习这个隐层的权重矩阵。而为什么针对词汇表里的单词要进行One-Hot编码,这里解释一下。如下图所示,如果我们用一个One-Hot向量乘以这个权重矩阵,那么得出的向量结果就是对应单词的特征表示。这意味着这个模型的隐层实际上只是作为一个查找表,而隐层的输出则是输入的单词的“词向量(word vector)”。
输出层为softmax回归分类器,每个输出神经元(词汇表中的每个单词都有一个对应的输出神经元)将产生0到1之间的输出,所有这些输出值的总和将等于1。具体来说,每个输出神经元都有一个权重向量,它将权重向量与隐层中的向量相乘,然后将指数函数应用于结果。最后,为了使输出之和达到1,我们将这个结果除以来自所有10,000个输出节点的结果之和。如下图所示:
如果两个不同的单词有非常相似的“上下文”(也就是说,它们周围可能出现什么单词),那么该模型应当为这两个单词输出非常相似的结果。网络输出这两个单词相似上下文预测的一种表达形式就是这两个单词的单词向量相似。换言之,如果两个单词有相似的上下文,那么该网络就有能力为这两个单词出学习相似的单词向量!
以上部分介绍了Skip-Gram模型的具体实现思路,接下来会针对Skip-Gram在实际训练中的一些问题进行优化。通过分析上述的Skip-Gram神经网络模型,可以发现一个问题,由于需要为每个单词学习一个固定长度的向量表示,因此以上面的例子为例,当需要训练10000个单词的300维的向量表示时,我们需要计算出300万个权重值。而在更大的数据集上,这样的训练过程是十分缓慢的,基本上不可行,因此Skip-Gram的作者针对这个问题提出了几种解决方案。常用的方案有Subsampling frequent words和Negative Sampling,接下来会详细介绍这两种解决方案。
Subsampling主要目的是通过削减训练集的训练样本数来降低训练代价。由于在文本中,许多单词出现的频率很高,这就导致了这个单词对应的word pair (inputword,outputword)在训练集中的数量会非常多,因此需要针对这些高频词进行二次采样以降低这些高频词在训练集中的规模。具体采样策略如下:
假设 w i 表示词汇表中的第 i 个单词, z(w i ) 表示该词在语料库中出现的频率。例如一个单词 w i 在大小为10000的语料库中出现的次数为100,那么 z(w i ) =0.01。知道了每个单词在语料库中的出现频率之后,那么对于每个单词 w i 的subsampling采样率如下:
该函数有一些有趣的点:
Subsampling虽然能明显地缩小训练神经网络模型时的训练集大小,但是并不能从根本上解决隐层矩阵规模大而带来的计算问题。也就是说,对于训练集中的每个样本,每次训练都需要更新隐层中的所有参数,因此Skip-Gram模型的作者又提出了另外一种方式来优化计算问题。
由于训练神经网络模型为了达到更高的精度,需要通过训练样本中每次细微地调整每个神经元的权重参数,因此每个训练每个训练样本都会微调神经网络中的所有参数。由于SubSampling在极限情况下,对训练集的削减程度不会低于原规模的3.3%,然而 ,这种程度的削减对于一个字典特别大的训练场景的影响是微弱的。为此作者又提出了一种Negative Sampling的方式。
Negative Sampling通过让每个训练样本只修改一小部分权重(而不是网络中的全部权重)来解决计算量特别大的问题。接下来可以看一下Negative Sampling的工作原理。
正常情况下,我们对每个单词语料训练神经网络模型,模型的输出是一个one-hot的向量。在Negative Sampling时,我们随机选择若干个(假设5个)negative word去更新对应的权重,(这里Negative word 对应的时One-Hot向量中值为0的单词,而我们的目标单词可以理解为Positive word,即对应One-Hot向量中值为1的单词)。
回想一下,我们的模型输出层有个300×10000的权重矩阵,如果每个训练样本只更新5个negative word和当前的positive word对应的权重,那么每次训练对应输出层只需要更新6*300个权重,此时更新比例只有6/10000=0.06%。
上面提到了,针对不同的数据集,Negative Sampling会选择2-20个negative word,下面介绍一下如何挑选这个Negative word。首先针对一个语料库,每次Negative Sampling挑选出的样本的可能性取决于该样本在语料库中出现的频数。
其中 f ( w i )表示单词 w i 在语料库中出现的频数。作者在他们的论文中指出,他们尝试了这个公式的一些变体,其中表现最好的是将每个单词出现的频数提高到3/4次方。如下所示:
处理一些样本之后会发现,与简单的公式相比,这个公式有增加不太频繁单词的概率和减少更频繁单词的概率的趋势。以上就是对Negative Sampling的一些简单描述。
Word Pairs and “Phrases”的主要思想是将经常成对出现或者某个短语当成一个Word,以此来降低整个训练过程中的计算复杂度。该方法在自然语言处理中有很大的应用场景。
参考:
1. http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/
2. http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/
『玖』 word2vec 之 skip-gram
Word2vec 主要有两种形式,CBOW 和Skip-gram,其中CBOW是通过上下文context来预测当前位置词,SKip-gram则是通过当前词来预测上下文
Fake Task
word2vec 实际上分为两部分,1,建立模型,2,通过模型获取词的嵌入向量(隐层参数)。整个过程与自编码器的思想类似,即基于训练数据训练一个神经网络,模型训练好后,并不会用这个模型处理后续的任务,真正需要的是这个模型学到的参数,如隐层的权重矩阵,基于训练数据建模的过程叫“Fake Task”,意味着建模并不是我们最终的目的。
Train
如何训练我们的神经网络模型?假如我们有一个句子“ The dog barked at the mailman”。
首先,我们选择句子中一个词作为我们的input word, 如 dog
然后,我们需要定义一个skip_window参数,来指定上下文的大小,即input word 一侧选取词的数量,假如skip_window=2,那将从dog出发向左右两个方向取最近的两个word,即(the, dog,barked,at),此时的span = skip_window * 2 + 1 = 5
另一个需要定义的参数是num_skips,即从上下文中选取多少个word来作为output word,这个参数应该小于等于2 * skip_window,即最多将所有上下文都作为output,但是不能重复。如设置num_skips = 2,此时从上下文选取2个词作为output,如(the, barked),最终我们将得到两组训练数据(dog, the) (dog, barked)
神经网络将基于这些训练数据输出一个概率分布,这个概率分布代表着在输入数据下,词典中每个词是output的概率。如拿数据(dog, barked)来训练,则模型将会告诉我们每个单词是’barked’的概率大小。
模型的输出概率代表着词典中每个单词有多大可能性跟input word同时出现。举个栗子,如果我们向神经网络模型中输入一个单词“Soviet“,那么最终模型的输出概率中,像“Union”, ”Russia“这种相关词的概率将远高于像”watermelon“,”kangaroo“非相关词的概率。因为”Union“,”Russia“在文本中更大可能在”Soviet“的窗口中出现。
我们将通过给神经网络输入文本中成对的单词来训练它完成上面所说的概率计算。下面的图中给出了一些我们的训练样本的例子。我们选定句子“The quick brown fox jumps over lazy dog”,设定我们的窗口大小为2(window_size = 2),也就是说我们仅选输入词前后各两个词和输入词进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。
模型将会从每队单词出现的次数中习得统计结果,模型可能会得到更多的(’soviet’, ‘union’)样本对,而(soviet, dog)这样的组合看到的很少。因此,当模型训练完成后,给定一个单词 soviet,输出结果中union 或者russia会比dog有更高的概率。
输入
常用做法是用训练文档构建词汇表,然后再对单词进行0ne-hot编码。
编码后的向量,形如dog = [0, 0, 1, 0, …0], 如果词汇表大小为10000, 那这个向量包含了10000的概率,即为当前词为输入的概率
下图是神经网络结构:
我们基于成对的单词来对神经网络进行训练, 训练样本是(input word, output word)这样的单词对,input word 和 output word都是one-hot编码的向量,最终的模型输出是一个概率分布。
隐层
如果我们想要用300个特征来表示一个词(即每个词是300维的向量),即隐层有300个神经元,隐层的权重为10000 * 300的矩阵,下图中的左右两个图代表了不同角度看隐层权重,左图中每列代表一个10000维的词向量与隐层单个神经元的连接权重,右图每行代表了一个单词的词向量。
我们最终的目标就是学习这个隐层权重矩阵。
输入被one-hot编码后,实际上只有一个位置不为0,所以这个向量相当稀疏,那如果我们将1 10000的向量与10000 300的矩阵相乘,相当消耗计算资源,为了高效计算,仅仅会选择矩阵中对应的向量中纬度为1的索引行
即实际不会进行矩阵乘法计算,而是根据输入向量中不为0 的维度去索引。这样模型中的隐层权重矩阵便成了一个查找表(lookup table),输出就是输入单词的嵌入词向量
输出层
隐层的输出是一个1*300的向量,而输出层是一个softmax回归分类器,他的每个结点将会输出一个0-1之间的值(概率),而结点的概率之和为1.
我们会发现Word2Vec模型是一个超级大的神经网络(权重矩阵规模非常大)。
举个栗子,我们拥有10000个单词的词汇表,我们如果想嵌入300维的词向量,那么我们的输入-隐层权重矩阵和隐层-输出层的权重矩阵都会有 10000 x 300 = 300万个权重,在如此庞大的神经网络中进行梯度下降是相当慢的。更糟糕的是,你需要大量的训练数据来调整这些权重并且避免过拟合。百万数量级的权重矩阵和亿万数量级的训练样本意味着训练这个模型将会是个灾难(太凶残了)。
Word2Vec的作者在它的第二篇论文中强调了这些问题,下面是作者在第二篇论文中的三个创新:
事实证明,对常用词抽样并且对优化目标采用“negative sampling”不仅降低了训练过程中的计算负担,还提高了训练的词向量的质量。
word pairs and phases
一些单词组合的含义和拆开以后具有完全不同的意义,比如 New York,单独的New 和York无法表达这个词组的含义。因此,应该把New York作为一个单独的词组来生成其词向量。
对高频词抽样
对于高频词,如 the ,按上面的处理方式会有两个问题:
如果直接删除掉这些高频词,会有两个问题
1.删除后,the这个单词永远也不会出现在我们的上下文窗口
2.训练样本会减少
所以word2vec 采用抽样的方式来解决这种高频词问题。他的基本思想是:对于我们在训练原始文本中遇到的每一个单词,他们都有一定概率被我们从文本中删除掉,而这个被删除的概率与单词的频率有关。
wi 是一个单词,Z(wi)是这个单词在所有预料中出现的频次。P(wi)是被保留的概率。
负采样
训练一个神经网络意味着要输入训练样本并且不断的调整神经元的权重,不断提高对目标的准确预测。而vocabulary的大小决定了skip-gram神经网络将拥有大规模的权重矩阵,所有的这些权重需要通过我们数以亿计的样本来训练调整,非常消耗计算资源,并且实际中会非常慢。
负采样解决了这个问题,不同于原本每个训练样本更新所有权重,负采样每次让一个训练样本仅仅更新一部分权重,减小计算量。
对于训练样本(fox,quick),都是经过one-hot编码的,当vocabulary的大小为10000时,我们期望输出对应的quick单词的那个神经元的输出是1,其余9999个都是0,这9999个输出为0的神经元所对应的单词称为negative word
隐层-输出层拥有300 10000的权重,而负采样时,我们仅仅更新quick 和我们选择的其他5个negative word的结点对应的权重,共6个神经元,300 6 = 1800 个权重,相当于只计算了0.06%的权重,计算效率大大提高。
其中f(wi)代表每个单词出现的频次,p(wi)代表被选中的概率。
负采样的C语言实现非常的有趣。unigram table有一个包含了一亿个元素的数组,这个数组是由词汇表中每个单词的索引号填充的,并且这个数组中有重复,也就是说有些单词会出现多次。那么每个单词的索引在这个数组中出现的次数该如何决定呢,由公式P(wi) * table_size,也就是说计算出的负采样概率*1亿=单词在表中出现的次数。
有了这张表以后,每次去我们进行负采样时,只需要在0-1亿范围内生成一个随机数,然后选择表中索引号为这个随机数的那个单词作为我们的negative word即可。一个单词的负采样概率越大,那么它在这个表中出现的次数就越多,它被选中的概率就越大。