一.简单总结

  其实相似度计算方法也是老生常谈,比如常用的有:

  1.常规方法

    a.编辑距离

    b.Jaccard

    c.余弦距离

    d.曼哈顿距离

    e.欧氏距离

    f.皮尔逊相关系数

  2.语义方法

    a.LSA

    b.Doc2Vec

    c.DSSM

  ......

二.利用熵计算相似度

  关于什么是熵、相对熵、交叉熵的概念,网上有很多,这里就不总结了。本篇主要关注工程方面,即怎么用代码实现,参考的论文来自《Content-based relevance estimation on the web using inter-document similarities》(2012-CIKM)。

  利用熵计算query与文档相似度并排序的步骤分为召回和重排序,比如先从大规模文档中召回小部分子集再进行重排序。召回部分可以用一些简单的效率高的方法快速确定候选子集,再将这些子集进行重排序。本篇关注如何利用熵重排序相关文档。

  召回后的排序公式如下:

    

  说明:

  (1).H(d)表示文档d的熵

    

    其中=|w|/|d|,分子是词w个数,分母为文档d中的总词数

  (2).文档间的相似度

    

    

    其中表示query的top-k个相关文档;利用交叉熵计算文档间的相似度,这里面的文档去除了query中的词。

    表示语言模型Dirichlet-smoothed,常见的平滑方法如下:

    

    其中Dirichlet 方法:
    a.首先计算最基本的最大的似然估计w|d 单词在单个文档出现的频率(有可能为0,所以就需要平滑,将所有f(w|d1), f(w|d2)....f(w|dn) 的所有频率加总
    b.设定u值,根据实证研究: Dirichlet 方法的u值在100-200之间是最理想 ,但论文中给出的是1000,0为不使用平滑
    c. 计算P(w|C)的概率

    (3).sim(q,d)表示query与doc的相似度,可以使用其它方法计算,也可以使用如(2)中的方法计算

三.程序

  完整程序https://github.com/jiangnanboy/entropy_sim

  核心程序:

  1. /**
  2. * 结合交叉熵和狄里克雷平滑语言方法计算相关度
  3. * @param queryTerms
  4. * @return
  5. */
  6. private Map<String, Double> queryDocScore(List<String> queryTerms) {
  7. //统计查询中的词频
  8. Map<String, Long> queryTermsCount = queryTerms
  9. .stream()
  10. .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  11. //查询中的总词频
  12. long queryTermsSize = queryTermsCount
  13. .values()
  14. .stream()
  15. .mapToLong(word -> word)
  16. .sum();
  17.  
  18. //文档集中的词频
  19. Map<String, Long> collectionTermsCount = corpusTerms
  20. .stream()
  21. .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  22. //文档集中的总词频
  23. long collectionTermsSize = collectionTermsCount
  24. .values()
  25. .stream()
  26. .mapToLong(word -> word)
  27. .sum();
  28.  
  29. Map<String, Double> scoredDocument = new HashMap<>();
  30. documentList.forEach(docTerms -> {
  31. //文档中的词频
  32. Map<String, Long> docTermsCount = docTerms
  33. .stream()
  34. .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  35. //文档中的总词频
  36. long docTermsSize = docTermsCount
  37. .values()
  38. .stream()
  39. .mapToLong(word -> word)
  40. .sum();
  41.  
  42. //计算交叉熵(或者相对熵)
  43. OptionalDouble score = queryTerms
  44. .stream()
  45. .mapToDouble(queryTerm -> {
  46. //queryTerm的似然
  47. double queryCE = (double)queryTermsCount.get(queryTerm) / queryTermsSize;
  48. //经过Dirichlet smooth的term weight
  49. double docCE = (1.0 + docTermsCount.getOrDefault(queryTerm, 0L) +
  50. this.lambda * (collectionTermsCount.getOrDefault(queryTerm, 0L) / collectionTermsSize)) /
  51. (docTermsSize + this.lambda);
  52. return queryCE * Math.log(1 / docCE);//交叉熵
  53. //return queryCE * Math.log(queryCE / docCE);//相对熵
  54. })
  55. .reduce(Double::sum);
  56. String docID = corpusHashMap.get(docTerms);
  57. scoredDocument.put(docID, Math.exp(-score.getAsDouble()));
  58. });
  59. return scoredDocument;
  60. }

基于熵的方法计算query与docs相似度的更多相关文章

  1. 海量数据挖掘MMDS week2: 频繁项集挖掘 Apriori算法的改进:基于hash的方法

    http://blog.csdn.net/pipisorry/article/details/48901217 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  2. 基于神经网络的混合计算(DNC)-Hybrid computing using a NN with dynamic external memory

    前言: DNC可以称为NTM的进一步发展,希望先看看这篇译文,关于NTM的译文:人工机器-NTM-Neutral Turing Machine 基于神经网络的混合计算 Hybrid computing ...

  3. 云知声 Atlas 超算平台: 基于 Fluid + Alluxio 的计算加速实践

    Fluid 是云原生基金会 CNCF 下的云原生数据编排和加速项目,由南京大学.阿里云及 Alluxio 社区联合发起并开源.本文主要介绍云知声 Atlas 超算平台基于 Fluid + Alluxi ...

  4. 使用并行的方法计算斐波那契数列 (Fibonacci)

    更新:我的同事Terry告诉我有一种矩阵运算的方式计算斐波那契数列,更适于并行.他还提供了利用TBB的parallel_reduce模板计算斐波那契数列的代码(在TBB示例代码的基础上修改得来,比原始 ...

  5. PDO 学习与使用 ( 一 ) :PDO 对象、exec 方法、query 方法与防 SQL 注入

    1.安装 PDO 数据库抽象层 PDO - PHP Data Object 扩展类库为 PHP 访问数据库定义了一个轻量级的.一致性的接口,它提供了一个数据访问抽象层,针对不同的数据库服务器使用特定的 ...

  6. R与数据分析旧笔记(十六) 基于密度的方法:DBSCAN

    基于密度的方法:DBSCAN 基于密度的方法:DBSCAN DBSCAN=Density-Based Spatial Clustering of Applications with Noise 本算法 ...

  7. 面试题:两种方法计算n!

    直接上代码package com.face.test; public class Test { /** * 面试题:递归方法计算n! */ @org.junit.Test public void di ...

  8. 创建一个接口Shape,其中有抽象方法area,类Circle 、Rectangle实现area方法计算其面积并返回。又有Star实现Shape的area方法,其返回值是0,Star类另有一返回值boolean型方法isStar;在main方法里创建一个Vector,根据随机数的不同向其中加入Shape的不同子类对象(如是1,生成Circle对象;如是2,生成Rectangle对象;如是3,生成S

    题目补充: 创建一个接口Shape,其中有抽象方法area,类Circle .Rectangle实现area方法计算其面积并返回. 又有Star实现Shape的area方法,其返回值是0,Star类另 ...

  9. Spark Mllib里决策树回归分析使用.rootMeanSquaredError方法计算出以RMSE来评估模型的准确率(图文详解)

    不多说,直接上干货! Spark Mllib里决策树二元分类使用.areaUnderROC方法计算出以AUC来评估模型的准确率和决策树多元分类使用.precision方法以precision来评估模型 ...

随机推荐

  1. ngixn二级域名

    每个人的配置不一样,我说说我的 安装完nginx后,找到nginx配置文件/usr/local/nginx/conf/nginx.conf nginx代理apche(作为一级域名) 默认一级域名(ds ...

  2. hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c ...

  3. Java集合--Hash、Hash冲突

    一.Hash 散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构.也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这 ...

  4. c#泛型约束(转载)

    博客地址:https://www.cnblogs.com/zhengwk/p/5541921.html 六种类型的约束: T:结构 类型参数必须是值类型.可以指定除 Nullable 以外的任何值类型 ...

  5. C++string类字符串学习

    1.逆转字符串 第一种,使用algorithm中reverse函数. #include <algorithm> #include <string> #include <i ...

  6. iOS 更改状态栏文字颜色

    第一步:在info.plist中添加一个字段:view controller -base status bar 设置为NO 第二步: 在AppDelegate.m的 didFinishLaunchin ...

  7. js的一些兼容融性问题

    1.非行内样式获取 高级浏览器 getComputedStyle(obox.false)//获取所有属性 ie浏览器 box.currentStyle//获取所有属性 兼容写法 function ge ...

  8. JS原生实现照片抽奖

    HTML表格标记实现九宫格,放入九张图片.利用CSS的滤镜属性控制图片的透明度.Javascript实现抽奖和中奖. 可以做为教师上课,随机抽取回答问题的同学,使学生感受到随机的公平性,简单有趣! 点 ...

  9. Vue Elementui中的Tag与页面其它元素相互交互

    参考:https://www.jb51.net/article/147917.htm 思路 一.多选框勾选,出现对应的tag: 1.利用watch监听多选框绑定的值A(数组)的变化:2.根据A的变化, ...

  10. echarts —— 绘制横向柱状图(圆角、无坐标轴)

    UI给了设计图,看了一眼觉得简单,不就是无序列表布局嘛(ul,li),后来才知道那是echarts图,好吧,样式如下: 代码如下:(渐变色没做) <!DOCTYPE html> <h ...