【机器学习】word2vec学习笔记(一):word2vec源码解析

0. word2vec地址

1. word2vec算法原理

本模块主要介绍word2vec的算法原理。

word2vec用到了两个重要的模型:CBOW模型和Skip-gram模型,两个模型的结构都包含输入层、投影层和输出层。CBOW模型是根据上下文来预测中心词,Skip-gram模型则是根据中心词来预测上下文。

这里暂时不再过多的介绍word2vec原理细节了,网上的博客已经写的非常全面了,这里列出我在学习过程中,阅读的比较深入的几篇博客。

参考文献:

  1. word2vec 中的数学原理详解(作者:peghoty,网上有pdf版)
  2. word2vec是如何得到词向量的?(知乎的一篇回答)
  3. 全面理解word2vec(主要看CBOW/skip-gram的两种结构)
  4. Word2vec数学原理全家桶(主要看权重矩阵更新部分)
  5. 推荐系统的中 EMBEDDING 的应用实践(不只是word2vec,还包含了推荐系统的一些其他知识)
  6. 另外一个pdf文件:《Deep Learning实战之word2vec》
  7. 机器学习算法实现解析——word2vec源码解析
  8. word2vec原理(二) 基于Hierarchical Softmax的模型(刘建平)
  9. word2vec原理(三) 基于Negative Sampling的模型(刘建平)

2. 源码解析(一)

2.1 main函数流程

  • 输入参数与程序变量匹配
  • 预计算sigmod,保存到expTable[]中
  • 模型训练

2.2 模型训练流程

图1【转】:

 图2【转】:

这里写图片描述

2.3 预处理

预处理部分,首先完成的是参数的初始化,包括一些训练传入参数和静态参数等。同时也对训练中使用的一些指针进行了声明。

预处理部分的另外一个重要操作的提前将sigmoid的值计算出来并存储到一个数组expTable中,使用时直接在数组中查找即可。word2vec计算了[-6,6]区间的sigmoid的值,将MAX_EXP定义为6是因为sigmoid函数在区间[-6,6]以外的函数值基本不变。

// 申请EXP_TABLE_SIZE+1个空间,数组expTable存储预处理阶段计算好的sigmoid值
expTable = (real *) malloc((EXP_TABLE_SIZE + 1) * sizeof(real));  
for (i = 0; i < EXP_TABLE_SIZE; i++) {
    expTable[i] = exp((i / (real) EXP_TABLE_SIZE * 2 - 1) * MAX_EXP);  // Precompute the exp() table
    expTable[i] = expTable[i] / (expTable[i] + 1);  // Precompute f(x) = x / (x + 1)
}

2.4 构建词库

word2vec给出了两种构建词库的方法,从词汇表文件中加载ReadVocab()或者从训练文件中加载LearnVocabFromTrainFile()

ReadVocab()函数是从已有词汇表文件中直接读词并构建词表和hash表,由于词汇表中的词语不存在重复,因此与LearnVocabFromTrainFile相比没有做重复词汇的检测。LearnVocabFromTrainFile()函数是从训练文件中获取所有词并构建词表和hash表。

在处理词的过程中,保留了两个数组:存储词的vocab存储词的hash的vocab_hash。在vocab_hash中存储的是词在词汇表中的Index。在处理词的hash的过程中使用到了线性探测的开放定址法处理冲突。

ReadVocab()流程:

  1. ReadWord(word, fin):从文件中逐个字符读取单个单词到word,输入文件以空格' ',tab'\t',EOL'\n'为词的分界符;
  2. AddWordToVocab(word):strcpy(vocab[vocab_size].word, word) -> GetWordHash(word);
  3. SortVocab():根据词频排序,按照词频对词表中的项从大到小排序,把出现数量少的word排在vocab数组的后面,并删除一些词频小于阈值的词。

LearnVocabFromTrainFile()流程: 

  1. AddWordToVocab((char *)"</s>"):将</s>添加到vocab的第一个位置;
  2. ReadWord(word, fin):从文件中逐个字符读取单个单词到word,输入文件以空格' ',tab'\t',EOL'\n'为词的分界符;
  3. SearchVocab(word):GetWordHash(word) -> 根据hash返回一个词在词表中的位置,若不存在则返回-1;
  4. 词汇表中不存在这个词,进行AddWordToVocab(word),词汇表中存在这个词,进行词频累加;
  5. ReduceVocab():从词表中删除出现次数小于min_reduce的词;
  6. SortVocab():根据词频排序,按照词频对词表中的项从大到小排序,把出现数量少的word排在vocab数组的后面,并删除一些词频小于阈值的词。
// 词的结构体
struct vocab_word {
    long long cn;  // 词频,从训练集中计数得到或直接提供词频文件
    int *point;  // huffman树中从根节点到该词的路径,存放的是路径上每个节点的索引
    char *word, *code, codelen;  // word
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值