word2vec是如何得到词向量的

转载知乎上分析挺好的一篇文章:https://www.zhihu.com/question/44832436


作者:crystalajj
链接:https://www.zhihu.com/question/44832436/answer/266068967
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

word2vec是如何得到词向量的?这个问题比较大。从头开始讲的话,首先有了文本语料库,你需要对语料库进行预处理,这个处理流程与你的语料库种类以及个人目的有关,比如,如果是英文语料库你可能需要大小写转换检查拼写错误等操作,如果是中文日语语料库你需要增加分词处理。这个过程其他的答案已经梳理过了不再赘述。得到你想要的processed corpus之后,将他们的one-hot向量作为word2vec的输入,通过word2vec训练低维词向量(word embedding)就ok了。不得不说word2vec是个很棒的工具,目前有两种训练模型(CBOW和Skip-gram),两种加速算法(Negative Sample与Hierarchical Softmax)。本答旨在阐述word2vec如何将corpus的one-hot向量(模型的输入)转换成低维词向量(模型的中间产物,更具体来说是输入权重矩阵),真真切切感受到向量的变化,不涉及加速算法。如果读者有要求有空再补上。

1 Word2Vec两种模型的大致印象

刚才也提到了,Word2Vec包含了两种词训练模型:CBOW模型和Skip-gram模型。

CBOW模型根据 中心词W(t)周围的词来预测中心词
Skip-gram模型则根据 中心词W(t)来预测周围词

抛开两个模型的优缺点不说,它们的结构仅仅是输入层和输出层不同。请看:

<img src="https://pic2.zhimg.com/50/v2-2a319bac1bb7fcae2f4395d2c38674ea_hd.jpg" data-size="normal" data-rawwidth="421" data-rawheight="414" class="origin_image zh-lightbox-thumb" width="421" data-original="https://pic2.zhimg.com/v2-2a319bac1bb7fcae2f4395d2c38674ea_r.jpg"> CBOW模型<img src="https://pic3.zhimg.com/50/v2-a54db7c984e6eaf9f06cf21178238fc6_hd.jpg" data-size="normal" data-rawwidth="462" data-rawheight="427" class="origin_image zh-lightbox-thumb" width="462" data-original="https://pic3.zhimg.com/v2-a54db7c984e6eaf9f06cf21178238fc6_r.jpg"> Skip-gram模型

这两张结构图其实是被简化了的,读者只需要对两个模型的区别有个大致的判断和认知就ok了。接下来我们具体分析一下CBOW模型的构造,以及词向量是如何产生的。理解了CBOW模型,Skip-gram模型也就不在话下啦。

2 CBOW模型的理解

其实数学基础及英文好的同学可以参照斯坦福大学Deep Learning for NLP课堂笔记

当然,懒省事儿的童鞋们就跟随我的脚步慢慢来吧。

先来看着这个结构图,用自然语言描述一下CBOW模型的流程:

<img src="https://pic2.zhimg.com/50/v2-0f439e1bb44c71c8e694cc65cb509263_hd.jpg" data-size="normal" data-rawwidth="313" data-rawheight="471" class="content_image" width="313"> CBOW模型结构图

NOTE:花括号内{}为解释内容.

  1. 输入层:上下文单词的onehot. {假设单词向量空间dim为V,上下文单词个数为C}
  2. 所有onehot分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W}
  3. 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1*N.
  4. 乘以输出权重矩阵W' {N*V}
  5. 得到向量 {1*V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
  6. 与true label的onehot做比较,误差越小越好
所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W'。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table(其实聪明的你已经看出来了,其实这个look up table就是 矩阵W自身),也就是说, 任何一个单词的onehot乘以这个矩阵都将得到自己的词向量(1*N维)。有了look up table就可以免去训练过程直接查表得到单词的词向量了。
其实看到这里就基本清楚了。

这回就能解释题主的疑问了!如果还是觉得我木有说明白,别着急!跟我来随着栗子走一趟CBOW模型的流程!

3 CBOW模型流程举例

假设我们现在的Corpus是这一个简单的只有四个单词的document:
{I drink coffee everyday}
我们选coffee作为中心词,window size设为2
也就是说,我们要根据单词"I","drink"和"everyday"来预测一个单词,并且我们希望这个单词是coffee。
<img src="https://pic4.zhimg.com/50/v2-3e75211b3b675f17a232f29fae0982bc_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1429" data-rawheight="736" class="origin_image zh-lightbox-thumb" width="1429" data-original="https://pic4.zhimg.com/v2-3e75211b3b675f17a232f29fae0982bc_r.jpg"> <img src="https://pic4.zhimg.com/50/v2-abd3c7d6bc76c01266e8ddd32acfe31a_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1514" data-rawheight="844" class="origin_image zh-lightbox-thumb" width="1514" data-original="https://pic4.zhimg.com/v2-abd3c7d6bc76c01266e8ddd32acfe31a_r.jpg"> <img src="https://pic1.zhimg.com/50/v2-66655880a87789eaba5dd6f5c5033e94_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1305" data-rawheight="755" class="origin_image zh-lightbox-thumb" width="1305" data-original="https://pic1.zhimg.com/v2-66655880a87789eaba5dd6f5c5033e94_r.jpg"> <img src="https://pic2.zhimg.com/50/v2-5325f4a5d1fbacefd93ccb138b706a69_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1304" data-rawheight="798" class="origin_image zh-lightbox-thumb" width="1304" data-original="https://pic2.zhimg.com/v2-5325f4a5d1fbacefd93ccb138b706a69_r.jpg"> <img src="https://pic4.zhimg.com/50/v2-1713450fa2a0f37c8cbcce4ffef04baa_hd.jpg" data-caption="" data-size="normal" data-rawwidth="1319" data-rawheight="736" class="origin_image zh-lightbox-thumb" width="1319" data-original="https://pic4.zhimg.com/v2-1713450fa2a0f37c8cbcce4ffef04baa_r.jpg">

假设我们此时得到的概率分布已经达到了设定的迭代次数,那么现在我们训练出来的look up table应该为矩阵W。即,任何一个单词的one-hot表示乘以这个矩阵都将得到自己的word embedding。

如有疑问欢迎提问。


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在训练中文词向量并进行可视化的过程中,可以按照以下步骤进行操作: 1. 准备数据:首先,需要准备一个包含大量中文文本的语料库作为训练数据。可以使用已有的中文语料库,或者自己收集相关的中文文本数据。 2. 数据预处理:对于中文文本数据,需要进行一些预处理操作,例如分词、去除停用词、去除标点符号等。可以使用分词工具(如jieba)来进行中文分词,并根据需要进行其他预处理操作。 3. 训练词向量模型:使用Word2Vec算法对预处理后的中文文本数据进行训练,得到词向量模型。可以使用Python中的gensim库来实现Word2Vec算法的训练。 4. 可视化词向量:将训练得到词向量进行可视化,可以使用t-SNE算法将高维词向量降维到二维或三维空间,并使用可视化工具(如matplotlib)进行展示。 下面是一个示例代码,演示了如何使用Word2Vec训练中文词向量并进行可视化: ```python import jieba from gensim.models import Word2Vec from sklearn.manifold import TSNE import matplotlib.pyplot as plt # 准备数据 corpus = [ "我喜欢吃苹果", "苹果是一种水果", "我喜欢吃香蕉", "香蕉是一种水果", "我喜欢吃橘子", "橘子是一种水果" ] # 数据预处理 sentences = [list(jieba.cut(sentence)) for sentence in corpus] # 训练词向量模型 model = Word2Vec(sentences, size=100, window=5, min_count=1, workers=4) # 可视化词向量 words = model.wv.index2word[:10] # 取前10个词 word_vectors = model.wv[words] tsne = TSNE(n_components=2) word_vectors_tsne = tsne.fit_transform(word_vectors) plt.figure(figsize=(10, 6)) for i, word in enumerate(words): x, y = word_vectors_tsne[i] plt.scatter(x, y) plt.annotate(word, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom') plt.show() ``` 这段代码首先准备了一个包含若干中文句子的语料库,然后使用jieba进行分词,接着使用Word2Vec算法训练词向量模型。最后,使用t-SNE算法将词向量降维到二维空间,并使用matplotlib进行可视化展示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值