前言:

由于新版本的产品已经上线,但是还没有一个搜索的功能,做一个搜索模块出来是当务之急。新的搜索模块将同时实现两个功能,搜索商品,与搜索店铺及品牌。搜索商品关键词部分由陈哥寻找开源的搜索引擎。另一部分由我来修改wand算法,找到与关键词最匹配的店铺。

我的github:

我实现的代码全部贴在我的github中,欢迎大家去参观。

https://github.com/YinWenAtBIT

一、算法简介:

1.1算法来源:

算法的出处来自与Efficient Query Evaluation using a Two-Level Retrieval Process,这一篇论文,最初直接阅读论文之后,没能立刻理解算法,原因在于对于搜索算法中的idf,tf,posting list等等概念,以及其数据结构的不甚了解,看论文中的伪代码不能看明白。于是直接找了已有的介绍wand算法的博客:http://www.cnblogs.com/daremen/archive/2013/08/29/3289694.html

在仔细阅读完其博客之后,彻底明白了wand算法的运作方式。

1.2算法简介:

WAND全称Weak AND或者Weighted AND,主要用于计算文档之间的相似度。

IR中与文档相似度相关的几个概念

倒排索引

在向量空间模型中一篇文档(document)通常会表示为词(term)的向量,比如这样的三个文档:

d1: I love you.
d2: I hate you.
d3: I miss you.
表示为: d1 = [1, 1, 0, 0, 1], d2 = [1, 0, 1, 0, 1], d3 = [1, 0, 0, 1, 1]。 向量位置依次表示[I, love, hate, miss, you],其中1表示在文档中出现,0表示没有出现。

上面是文档表示,其相应的倒排索引可以表示为:

I: [1, 2, 3]
love: [1]
hate: [2]
miss: [3]
you: [1, 2, 3]
当然在索引中除了可以出现文档信息,还可以添加其它信息,比如这个term在此文档中出现的次数。文档会有一个唯一的id号,称为DID,在倒排索引中文档通常是按照DID的增序排列。

posting 和 posting list

在倒排索引中以冒号作为分割可以分为两部分,第一部分称为字典(dictionary),第二部分称为posting(也称为posting list)。所有的posting合在一起称为postings(或者posting lists)。

tf-idf

这个概念有点复杂,可以直接看wikipedia和吴军博士数学之美中的相关解释。

两段评估

通常完全评估两篇文档的相似度计算量很大,为了减少计算,可以在完全评估之前引入另一个比较廉价的计算(本文称之为预计算),并且设置一个threshold,只有当这个廉价的计算结果大于threshold的时候才进行费时的完全计算。

WAND算法正是采用了这种想法,而且WAND算法在预计算时也进行了优化,使得其在性能上有很大的提升。

WAND算法

Wand方法简单来说,一般我们在计算文本相关性的时候,会通过倒排索引的方式进行查询,通过倒排索引已经要比全量遍历节约大量时间,但是有时候仍然很慢。
  原因是很多时候我们其实只是想要top n个结果,一些结果明显较差的也进行了复杂的相关性计算,而weak-and算法通过计算每个词的贡献上限来估计文档的相关性上限,从而建立一个阈值对倒排中的结果进行减枝,从而得到提速的效果。

  wand算法首先要估计每个词对相关性贡献的上限,最简单的相关性就是TF*IDF,一般query中词的TF均为1,IDF是固定的,因此就是估计一个词在文档中的词频TF上限,一般TF需要归一化,即除以文档所有词的个数,因此,就是要估算一个词在文档中所能占到的最大比例,这个线下计算即可。

  知道了一个词的相关性上界值,就可以知道一个query和一个文档的相关性上限值,显然就是他们共同的词的相关性上限值的和。

  这样对于一个query,获得其所有词的相关性贡献上限,然后对一个文档,看其和query中都出现的词,然后求这些词的贡献和即可,然后和一个预设值比较,如果超过预设值,则进入下一步的计算,否则则丢弃。

  如果按照这样的方法计算n个最相似文档,就要取出所有的文档,每个文档作预计算,比较threshold,然后决定是否在top-n之列。这样计算当然可行,但是还是可以优化的。优化的出发点就是尽量减少预计算,wand论文中提到的算法如下:

  其基本思路是基于倒排索引来实现WAND方法:

  首先是初始化:

  1. 提取出da中所有的词,以及这些词的倒排索引;
  2. 初始化curDoc=0;
  3. 初始化posting数组,使得posting[t]为词t倒排索引中第一个文档;
Function next(θ)repeat/* Sort the terms in non decreasing order of DID */sort(terms, posting)/* Find pivot term - the first one with accumulated UB ≥ θ */pTerm ← findPivotTerm(terms, θ)if (pTerm = null) return (NoMoreDocs)pivot ← posting[pTerm].DIDif (pivot = lastID) return (NoMoreDocs)if (pivot ≤ curDoc)/* pivot has already been considered, advance one of the preceding terms */aterm ← pickTerm(terms[0..pTerm])posting[aterm] ← aterm.iterator.next(curDoc+1)else /* pivot > curDoc */if (posting[0].DID = pivot) //注,这个是sort之后的第一个term位置的doc id/* Success, all terms preceding pTerm belong to the pivot */curDoc ← pivotreturn (curDoc, posting)else/* not enough mass yet on pivot, advance one of the preceding terms */aterm ← pickTerm(terms[0..pTerm])posting[aterm] ← aterm.iterator.next(pivot)end repeat

二、算法修改:

1.1现有资源:

现在本地有一个各个商品的特性描述文本文档,其中含有商品的id,商品的名字,商品的特性描述(这些都由抓取的商品切词而来,部分人工整理)。在数据库中,有每个商品id对应的店铺id,和品牌id(如果没有对应的则为空)。

因此,在这里我们可以吧店铺和品牌的id,当做DID使用,而其对应的商品的特性,作为其内容,每种商品出现一次,其对应的特性也相应的作为content在店铺或者品牌的正文中出现一次。这样我们就有了词频,TF,以及IDF。

1.2提供给WAND算法类资源:

由于有了以上数据,我们需要想办法理清楚wand算法进行TOP-N计算所需要的各种资源,进行提前处理,以避免在实际运行时进行过多的计算,也可以分离后台数据处理与实际运算程序,避免由于后台数据接口改变而导致程序需要大改。

经过分析,WAND算法需要以下四种处理好的数据结构:

1. 已经计算好的IDF(可以保存在字典中,key为term,value为idf)

2. wt数据(这是进行精算中,at 乘以的后半数据,其只与DID中的term 词频,以及DID的content长度有关)

3. UB数据(每个term对应的最大的score值,计算这个值需要at与wt中的最大值相乘,我们假设at中同一个词只出现一次,商品搜索中这个很正常。因此我们可以提前计算出来)

4. term的倒排索引(这个是最关键的了)

1.3数据预处理实现:

有了上诉总结的加快运算的数据值,那么需要将他们合理的组织,以便捷的使用,我写了一个read_goods_features.py 函数来读取文本文档,并得到以上四种需要的数据,具体代码在github中列出,

wand(wead and)算法简介与改造,修改为店铺与品牌的关键字搜索相关推荐

  1. 店铺与品牌的关键字搜索——wand(wead and)算法简介与改造

    前言: 由于新版本的产品已经上线,但是还没有一个搜索的功能,做一个搜索模块出来是当务之急.新的搜索模块将同时实现两个功能,搜索商品,与搜索店铺及品牌.搜索商品关键词部分由陈哥寻找开源的搜索引擎.另一部 ...

  2. 数据结构与算法:算法简介

    数据结构与算法:算法简介 雪柯 大工生物信息 提笔为写给奋进之人 已关注 你说呢 . shenwei356 等 70 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国 ...

  3. Minimax 和 Alpha-beta 剪枝算法简介,及以此实现的井字棋游戏(Tic-tac-toe)

    前段时间用 React 写了个2048 游戏来练练手,准备用来回顾下 React 相关的各种技术,以及试验一下新技术.在写这个2048的过程中,我考虑是否可以在其中加入一个 AI 算法来自动进行游戏, ...

  4. 量子计算(二十):量子算法简介

    文章目录 量子算法简介 一.概述 二.量子经典混合算法 量子算法简介 一.概述 量子算法是在现实的量子计算模型上运行的算法,最常用的模型是计算的量子电路模型.经典(或非量子)算法是一种有限的指令序列, ...

  5. 『分享』水平集算法简介(Level Set)

    注:原文网页广告太多,决定转帖到这里,待更新! [原链接]http://www.caogenit.com/caogenxueyuan/yingyongfangxiang/rengongzhineng/ ...

  6. 详细介绍用MATLAB实现基于A*算法的路径规划(附完整的代码,代码逐行进行解释)(一)--------A*算法简介和环境的创建

       本系列文章主要介绍基于A*算法的路径规划的实现,并使用MATLAB进行仿真演示.本文作为本系列的第一篇文章主要介绍如何进行环境的创建,还有一定要记得读前言!!! 本系列文章链接: ------- ...

  7. 【音效处理】Compressor 压缩器算法简介

    系列文章目录 Delay Line 简介及其 C/C++ 实现 LFO 低频振荡器简介及其 C/C++ 实现 [音效处理]Delay/Echo 算法简介 [音效处理]Vibrato 算法简介 [音效处 ...

  8. 算法图解第一章——算法简介

    目录 前言 一.算法简介 1.引言 1.什么是算法 2.需要具备的知识 2.二分查找 1.什么是二分查找 2.举个例子,猜数字 3.对数函数 3.大 O 表示法 1.定义 2.一些常见的大 O 运行时 ...

  9. LoRaWAN ADR (自适应速率) 算法简介及最新研究方向

    LoRaWAN ADR 自适应速率 算法简介及最新研究方向 1. 背景: 1.1 ADR简介 1.2 LoRaWan NS 1.3 ADR目标 1.4 ADR应用场景 2. ADR实现方式.原理: 3 ...

最新文章

  1. DNS服务器分离解析 RAID阵列 进程管理 日志管理 systemd作用
  2. 计算机网络计算机应用答案,计算机网络与应用(含答案).doc
  3. Node.js笔记-使用socket.io构建websocket聊天室
  4. 用python批量执行VBA代码
  5. Python学习笔记:文件(File)
  6. 实现企业员工外出登记(二)
  7. 面试微软等公司必备的书
  8. 在PaddlePaddle框架下通过两层全连接网络实现IRIS数据分类
  9. 爬虫日记(7):用urllib和beautifulsoup来实战抓取新闻
  10. 转:程序员这口饭-职业规划解决方案
  11. java 时区 mysql 时区:时区在程序和数据库中的作用及其机制
  12. 基本表改变视图不改变为什么_为什么说10万本金以下穷人玩股票一般都会赔?不改变穷人思维,还不如退出股市...
  13. android 录屏 sdk,浅析Android录屏 MediaRecorder
  14. element-ui Form表单验证
  15. GIS应用技巧之景观格局分析(一)
  16. Ubuntu 18.04 Wine下安装微信并成功解决疑难杂症
  17. 解决Win10频繁禁用IME的问题
  18. 用excel做anova分析
  19. adobe reader xi补丁_Adobe Reader XI
  20. 入门UI设计一般要学习多久,学习哪些内容

热门文章

  1. Inconsistency detected. Invalid view holder adapter positionVH
  2. 东塔靶场之文件上传cms--pluck
  3. silverlight mysql_Silverlight中衔接MySQL数据库实例详解
  4. 阿里云解析是什么?个人版和企业版有什么区别?
  5. pandas parquet文件读取pyarrow、feather文件保存与读取;requests 或wget下载图片文件
  6. 【程序】Marvell 88W8686 WiFi模块(WM-G-MR-09)创建或连接热点,并使用lwip2.0.3建立http服务器(20180312版)
  7. windows10突发explorer.exe“没有注册类”错误的解决方式
  8. ZYNQ基本使用(2) GPIO的使用
  9. 搜索引擎收录、抓取、排序页面的原理简析
  10. MIPI扫盲系列博文