基于word2vec的文档向量模型的应用

word2vec的原理以及训练过程具体细节就不介绍了,推荐两篇文档:《word2vec parameter learning explained》、和《word2vec中的数学》。

在《word2vec中的数学》中谈到了训练语言模型的一些方法:比如n-gram和神经网络。在使用神经网络训练语言模型时得到的"副产物",就是word2vec词向量。基于神经网络训练语言模型有2种方案:cbow和skip-gram,它们是在这篇文章《A neural probabilistic language model》基础上对训练过程提出的改进方案。这里简单讲一下cbow的训练过程:

训练过程

  • 输入层:将词w的上下文的2c个词的词向量作为输入:\(v(context(w)_1),v(context(w)_2),...v(context(w)_{2c})\)

    随机初始化这2c个词的词向量

  • 投影层:将输入层的2c 个词向量累加求和

    投影层对词向量累加求和,这丢失了词的顺序信息。比如说:“我 爱 你们” 和“你们 爱 我” 这三个词的词向量累加求和得到的词向量是相同的。

  • 输出层:赫夫曼树

    基于Huffman树进行二分类,构造目标函数,并采用梯度算法最优化目标函数得到模型参数



训练语料与训练参数

训练语料需要预先分词。所有的词组成的集合,称为词库。赫夫曼树的每个叶子结点就代表词库中的一个词。训练的话,可采用gensim或者其他工具(比如HanLP word2vec)。注意几个训练参数:

  • size 生成的词向量的维度,比如300维、100维等等,不需要太大。因为word2vec词向量并不是 one-hot representation 而是distribution representation。
  • window 参与训练的上下文词的个数(Set max skip length between words)。其实就是上面提到的 c
  • iter 迭代次数
  • min_count 训练过程会根据词出现的频率构造Huffman树,对于那些低频词(小于min_count),不参与构造Huffman树,从而减少了Huffman树的高度。This will discard words that appear less than min_count times
  • cbow 采用cbow模型训练

训练完成后,词库中每个词,都对应着一个相同维度的float数值向量。计算两个词的相似度,就是计算两个词所对应的数值向量夹角的余弦。

句向量DocVectorModel

在实际应用场景中,用户输入并不是一个个的词,而是句子(若干个词)。比如一个用户资料下的个人说明,就是一句自我介绍的话;用户的一段评论,也是一句话…

如果要计算两个句子的相似度,那怎么办呢?这个需要根据实际需求场景了。比如对句子进行关键词提取,采用word2vec计算关键词的相似度作为句子的相似度。

或者再简单一点(HanLP中的DocVectorModel实现),直接对句子分词,得到若干个词,然后对每个词的词向量累加,作为整个句子的"句向量",然后计算2个句向量的余弦相似度即可。比如计算这2个句子的相似度:docVectorModel.similarity("我爱你们", "你们爱我")

    public Vector query(String content)
{
if (content == null || content.length() == 0) return null;\
//对句子进行分词,我爱你们--->["我"、"爱"、"你们"]
List<Term> termList = NotionalTokenizer.segment(content);
Vector result = new Vector(dimension());
int n = 0;
for (Term term : termList)
{
//从word2vec词典中查出这个词的 词向量
Vector vector = wordVectorModel.vector(term.word);
if (vector == null)
{
//如果这是一个oov词,则直接忽略
continue;
}
++n;
//将 句子分词后的每个词 的词向量 相加
result.addToSelf(vector);
}
if (n == 0)
{
return null;
}
//归一化
result.normalize();
//句子--->分词--->查询词向量--->词向量相加作为"句向量"
return result;
}

值得注意的是,word2vec中存在的OOV问题,有没有其他更好的处理方案?参考:HanLP github issue 上的一个疑问

得到句子(文档)的向量表示后,计算余弦相似度,就能比较两个句子了。

    /**
* 文档相似度计算
* @param what
* @param with
* @return
*/
public float similarity(String what, String with)
{
//what 文档的 向量
Vector A = query(what);
if (A == null) return -1f;
//to 文档的 向量
Vector B = query(with);
if (B == null) return -1f;
//计算余弦相似度
return A.cosineForUnitVector(B);
}

应用

在基于ElasticSearch的文本搜索中,文档的相关性得分计算主要是基于TF-IDF或者BM25实现的:有时为了capture 查询字符串与文档之间的一些语义信息,以提高搜索的召回率,那就可以采用 DocVectorModel 来额外召回一些文档。

这里需要考虑的是:是否要训练自己的word2vec模型?还是直接采用第三方提供的(开源的基于维基百科训练的)?在把文档index到ES中去时,将文档的"句向量"计算好,存储到Mapping字段中。查询时,可基于script_score来做二次评分(对搜索的响应时间的影响?),总之算是一个尝试吧。

基于word2vec的文档向量模型的应用的更多相关文章

  1. 基于slate构建文档编辑器

    基于slate构建文档编辑器 slate.js是一个完全可定制的框架,用于构建富文本编辑器,在这里我们使用slate.js构建专注于文档编辑的富文本编辑器. 描述 Github | Editor DE ...

  2. 基于hash的文档判重——simhash

    本文环境: python3.5 ubuntu 16.04 第三方库: jieba 文件寄于github: https://github.com/w392807287/angelo_tools.git ...

  3. arclistsg文档独立模型标签

    [标签名称] arclistsg [标签简介] 单表独立模型的文档列表调用标记 [功能说明] 用于调用单表模型的内容,在V5.3系统以上版本中加入了单表模型的概念,脱离了以前的主从表的数据表关联结构, ...

  4. 多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)

    老有人觉得MSComm通讯控件很土,更有人大声疾呼:忘了它吧.确实当我们对串口编程有了一定的了解后,应该用API函数写一个属于自己的串口程序,由于编程者对程序了解,对程序修改自如.但我一直没有停止过用 ...

  5. MFC中 创建基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

  6. 基于Zabbix API文档二次开发与java接口封装

    (继续贴一篇之前工作期间写的经验案例) 一.           案例背景 我负责开发过一个平台的监控报警模块,基于zabbix实现,需要对zabbix进行二次开发. Zabbix官方提供了Rest ...

  7. 如何优雅的写UI——(2)MFC下基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

  8. 基于FlashPaper的文档播放器

    本文主要讨论.描述了使用Adobe公司的Flex与FlashPaper产品完成对发布到网上的文档资料进行只读控制,也就是说只允许浏览操作.对下载.打印进行控制. FlashPaper FlashPap ...

  9. rabbitmq 3.7.8基于centos7部署文档

    rabbitmq 3.7.8部署文档 安装erlang 安装依赖环境 yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel ope ...

随机推荐

  1. Android App自动化测试实战(基于Python)(三)

    1.Native App自动化测试及Appuim框架介绍 android平台提供了一个基于java语言的测试框架uiautomator,它一个测试的Java库,包含了创建UI测试的各种API和执行自动 ...

  2. Python常用代码,置顶备用!

    1.jupyter notebook 设置全部行输出: # 设置全部行输出 from IPython.core.interactiveshell import InteractiveShellInte ...

  3. LeeCode——Combine Two Tables

    Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...

  4. 百度云部署SSL证书

    查找中间证书 为了确保兼容到所有浏览器,我们必须在阿里云上部署中间证书,如果不部署证书,虽然安装过程可以完全也不会报错,但可能导致Android系统,Chrome 和 Firefox等浏览器无法识别. ...

  5. Swagger从入门到放弃

    如何编写基于OpenAPI规范的API文档 简介 Swagger Swagger是一个简单但功能强大的API表达工具.支持的语言种类繁多 使用Swagger生成API,我们可以得到交互式文档,自动生成 ...

  6. 【MySQL高可用架构设计】(一)-- mysql复制功能介绍

    一. 介绍 Mysql的复制功能是构建基于SQL数据库的大规模高性能应用的基础,主要用于分担主数据库的读负载,同时也为高可用.灾难恢复.备份等工作提供了更多的选择. 二.为什么要使用mysql复制功能 ...

  7. git使用笔记(第一次)

    背景:公司基于微服务的架构,前端的服务web只有一个.在并行完成不同需求的测试任务时,该服务会拉出不同分支,此时会碰到sit环境与其他测试小伙伴部署冲突的问题.解释下.需求1对应的服务web的A分支, ...

  8. C语言之++和--

    #include<stdio.h> int main(void) { int a; a = ; printf("a++ = %d\n", a++); printf(&q ...

  9. 6-剑指offer: 和为S的连续正数序列

    题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...

  10. 免费音乐播放器-airplay(网上收集,仅供学习与研究,支持正版)

    AirPlay媒体播放器无需安装,并不会修改注册表,生成桌面快捷方式,加入启动菜单及快速启动. 因此,您只需要下载本软件,保存在任何地方即可使用.使用方便,界面酷炫. 自动下载和显示歌词.专辑封面.汇 ...