- 浏览: 200524 次
文章分类
最新评论
-
code_xiaoke:
session可是有30分钟有效期的还有如果在分布式的环境下 ...
Java Web 用户登陆示例代码 -
xul0038:
http://www.baidu.com
Java Web 用户登陆示例代码 -
16866:
非常棒,配置信息呢
Nginx负载均衡 -
开发小菜:
什么意思,没明白?能不能写一个例子
JS 实现DIV随浏览器窗口大小变化
搜索排序结果的控制
Lucnen作为搜索引擎中,应用最为广泛和成功的开源框架,它对搜索结果的排序,有一套十分完整的机制来控制;但我们控制搜索结果排序的目的永远只有一个,那就是信息过滤,让用户快速,准确的找到其想要的结果,丰富用户体验。
以前看过一个牛人的博客,总结了4个地方,可对Lucene检索结果的排序进行控制,现在已经记不住。我自己简单整理了下面几个,若有疏漏,欢迎补充:
1. 通过Lucene自有的查询表达式:Lucene提供相当丰富的表达式解析,要细讲就多了去了;这里只强调下,我在项目中用的比较多的是通过对指定域的加权,来影响检索结果(例如:field1:(XXX)^10 or field2:(XXX)^5;其中XXX是用户提交的检索)
2. 权重的控制:这是在建索引的时候就写入索引的,查询时只是读取出来,用乘的方式来对一些检索结果加分。据我自己看Lucene代码,Similarity中也能在建索引时,对权重的写入进行控制;后面会细讲。
3. Controller 模块:Lucene的排序流程控制模块,里面提供的一些接口能让你对打分后的搜索结果进行一些筛选和调整。
4. Similarity 模块:Lucene的搜索结果打分控制模块,也是这里要详细分析的模块。他能让你对一个检索结果的打分进行优化,或面目全非,哈哈。
Lucene的打分公式
要理解Similarity模块对打分结果控制,首先要了解Lucene自己评分原理:相似度评分公式;次公式是目前公认的用户体验较好的一个,原理是根据余弦定理,我在以前的博文中有介绍过。下面是在摘自 《Lucene实战》(第二版)的公式表达式:
其中q 为查询语句,t 是q 分词后的每一项, d为去匹配的文档。
接下来对公式中的每一个函数,进行详解,他们都能在 Similarity 模块中进行控制。
Lucene打分流程
首先,我简单说明下,Lucene对一次查询是如何封装;这涉及到对打分公式是如何调用的,如此一来更能全面的了解打分流程:
第一步的处理肯定是分词,查询语句 => term_1, term_2 … term_n(n∈[1,∞]),紧接着是将这些term 封装成Query对象,总的Query对象是BooleanQuery,它里面包含和分词数相同TermQuery,和分词后的词项一一对应;这是对一个域的查询,若你多个域联合查询,那就会有多个这样的BooleanQuery,被一个更大的BooleanQuery包裹着。
而打分公式,贯穿所有Query,其中一部分在TermQuery中计算,一部分在BooleanQuery计算,最后按此计算出的得分进行排序,就得到了我们的搜索结果。
下面是我通过explain(Query query, int doc) 导出的打分解释:
对照Lucene的打分解释,我们一层一层往里拨(上述每个缩进为一层),每一个函数都能在Similarity中进行控制。
1. 首先第一层:3.3936599 = (MATCH) product of:,是此条记录的总得分。
2. 第二层:8.48414992 = (MATCH) sum of: 它对应一个BooleanQuery,它把它包含的TermQuery的得分累加起来,由于TermQuery总共有5个,此条结果中只匹配了2个,所以最后一行将得分乘以了0.4得到最后的打分,coord()在Similarity中的默认实现如下:
1 /** Implemented as <code>overlap / maxOverlap</code>. */
2 @Override
3 public float coord(int overlap, int maxOverlap) {
4 return overlap / (float)maxOverlap;
5 }
你也可以继承Similarity对此方法重写。
3. 第三层:(MATCH) weight(field:XXX in m), product of: 有2个,它们分别是“三国”、“无双”对应的词项查询TermQuery的得分。
再往里,就是TermQuery的打分规则了,里面的函数已经和公式有所对应了,下面就详细介绍TermQuery中每一项计算的作用。
Similarity 函数详解
TermQuery中有4个函数,都是Similarity里可以控制的函数,他们分别是queryNorm、tf、idf、fieldNorm;其中queryNorm对于某一次搜索中结果的排序没有影响,在一次搜索中queryNorm的值是固定的。这里就不介绍了
tf(t in q)
此函数表示词项T 在该文档中的该字段里 出现的频率;对应到上图的例子中:既是分词后的词项(三国 或 无双)在此条记录中Name字段里出现的频率。当然出现的次数越多,它返回的值越大,也正好反映了此文档的重要性。下面是DefaultSimilarity 中的默认实现的默认实现。
1 /** Implemented as <code>sqrt(freq)</code>. */
2 @Override
3 public float tf(float freq) {
4 return (float)Math.sqrt(freq);
5 }
默认实现是开平方。同样你可以重写此函数。
它实际对结果排序的影响,表现和它的意义一样,一个搜索结果包含的搜索关键词越多,得分越高。
idf(t)
此函数出现了两次,也刚好对应公式中的 idf(t)^2;
这个函数被称作倒频率,表示词项T 在所有文档中出现的频率。若它在所有文档中出现的次数越多,表明这个词项T 越不重要;以下是DefaultSimilarity的默认实现。
1 /** Implemented as <code>log(numDocs/(docFreq+1)) + 1</code>. */
2 @Override
3 public float idf(int docFreq, int numDocs) {
4 return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
5 }
此函数实际对结果排序的影响,在于当一次搜索包含多个词项时,文档A和B分别包含了其中一个词项;比如A包含“三国”,B包含“无双”;那么“三国”和“无双”的倒频率就会影响,让A、B的得分产生差异了。若词项只有一个,那本次搜索idf(t) 实际对结果排序不会产生影响。
fieldNorm (t)
它的值对应着公式中 boost(t.field in d)×lengthNorm(t.field in d) 的值。其中boost(t.field in d)的值,在创建索引时就被记录下来,而lengthNorm(t.field in d)得值,会在查询过程中计算;它表示此条搜索结果中,给定字段中包含词项的总数;若值越大,得分越低;你可以这么理解;若A文档有包含了1000个词项,关键词出现的频率为10;而B文档包20个词项,相同关键词出现的频率为8;很明显B文档的打分应该要高一些;由此函数可以起到这样的效果。以下是Similarity 的默认实现,函数名在3.0以后变了,原来就叫lengthNorm
01 /** Decodes a normalization factor stored in an index.
02 * <p>
03 * <b>WARNING: If you override this method, you should change the default
04 * Similarity to your implementation with {<a href="http://my.oschina.net/link1212" target="_blank" rel="nofollow">@link</a> Similarity#setDefault(Similarity)}.
05 * Otherwise, your method may not always be called, especially if you omit norms
06 * for some fields.</b>
07 * <a href="http://my.oschina.net/u/244147" target="_blank" rel="nofollow">@see</a> #encodeNormValue(float)
08 */
09 public float decodeNormValue(byte b) {
10 return NORM_TABLE[b & 0xFF]; // & 0xFF maps negative bytes to positive above 127
11 }
至此Lucene打分流程和Similarity模块的函数已经将的差不多了。可以通过这些函数让你的搜索展示出完全不一样的效果,这也需要根据不同的业务慢慢调试,才能得出最优化的搜索结果
原文地址:http://my.oschina.net/BreathL/blog/51498
搜索引擎和网络爬虫技术群293961767欢迎志同道合的朋友加入!
Lucnen作为搜索引擎中,应用最为广泛和成功的开源框架,它对搜索结果的排序,有一套十分完整的机制来控制;但我们控制搜索结果排序的目的永远只有一个,那就是信息过滤,让用户快速,准确的找到其想要的结果,丰富用户体验。
以前看过一个牛人的博客,总结了4个地方,可对Lucene检索结果的排序进行控制,现在已经记不住。我自己简单整理了下面几个,若有疏漏,欢迎补充:
1. 通过Lucene自有的查询表达式:Lucene提供相当丰富的表达式解析,要细讲就多了去了;这里只强调下,我在项目中用的比较多的是通过对指定域的加权,来影响检索结果(例如:field1:(XXX)^10 or field2:(XXX)^5;其中XXX是用户提交的检索)
2. 权重的控制:这是在建索引的时候就写入索引的,查询时只是读取出来,用乘的方式来对一些检索结果加分。据我自己看Lucene代码,Similarity中也能在建索引时,对权重的写入进行控制;后面会细讲。
3. Controller 模块:Lucene的排序流程控制模块,里面提供的一些接口能让你对打分后的搜索结果进行一些筛选和调整。
4. Similarity 模块:Lucene的搜索结果打分控制模块,也是这里要详细分析的模块。他能让你对一个检索结果的打分进行优化,或面目全非,哈哈。
Lucene的打分公式
要理解Similarity模块对打分结果控制,首先要了解Lucene自己评分原理:相似度评分公式;次公式是目前公认的用户体验较好的一个,原理是根据余弦定理,我在以前的博文中有介绍过。下面是在摘自 《Lucene实战》(第二版)的公式表达式:
其中q 为查询语句,t 是q 分词后的每一项, d为去匹配的文档。
接下来对公式中的每一个函数,进行详解,他们都能在 Similarity 模块中进行控制。
Lucene打分流程
首先,我简单说明下,Lucene对一次查询是如何封装;这涉及到对打分公式是如何调用的,如此一来更能全面的了解打分流程:
第一步的处理肯定是分词,查询语句 => term_1, term_2 … term_n(n∈[1,∞]),紧接着是将这些term 封装成Query对象,总的Query对象是BooleanQuery,它里面包含和分词数相同TermQuery,和分词后的词项一一对应;这是对一个域的查询,若你多个域联合查询,那就会有多个这样的BooleanQuery,被一个更大的BooleanQuery包裹着。
而打分公式,贯穿所有Query,其中一部分在TermQuery中计算,一部分在BooleanQuery计算,最后按此计算出的得分进行排序,就得到了我们的搜索结果。
下面是我通过explain(Query query, int doc) 导出的打分解释:
对照Lucene的打分解释,我们一层一层往里拨(上述每个缩进为一层),每一个函数都能在Similarity中进行控制。
1. 首先第一层:3.3936599 = (MATCH) product of:,是此条记录的总得分。
2. 第二层:8.48414992 = (MATCH) sum of: 它对应一个BooleanQuery,它把它包含的TermQuery的得分累加起来,由于TermQuery总共有5个,此条结果中只匹配了2个,所以最后一行将得分乘以了0.4得到最后的打分,coord()在Similarity中的默认实现如下:
1 /** Implemented as <code>overlap / maxOverlap</code>. */
2 @Override
3 public float coord(int overlap, int maxOverlap) {
4 return overlap / (float)maxOverlap;
5 }
你也可以继承Similarity对此方法重写。
3. 第三层:(MATCH) weight(field:XXX in m), product of: 有2个,它们分别是“三国”、“无双”对应的词项查询TermQuery的得分。
再往里,就是TermQuery的打分规则了,里面的函数已经和公式有所对应了,下面就详细介绍TermQuery中每一项计算的作用。
Similarity 函数详解
TermQuery中有4个函数,都是Similarity里可以控制的函数,他们分别是queryNorm、tf、idf、fieldNorm;其中queryNorm对于某一次搜索中结果的排序没有影响,在一次搜索中queryNorm的值是固定的。这里就不介绍了
tf(t in q)
此函数表示词项T 在该文档中的该字段里 出现的频率;对应到上图的例子中:既是分词后的词项(三国 或 无双)在此条记录中Name字段里出现的频率。当然出现的次数越多,它返回的值越大,也正好反映了此文档的重要性。下面是DefaultSimilarity 中的默认实现的默认实现。
1 /** Implemented as <code>sqrt(freq)</code>. */
2 @Override
3 public float tf(float freq) {
4 return (float)Math.sqrt(freq);
5 }
默认实现是开平方。同样你可以重写此函数。
它实际对结果排序的影响,表现和它的意义一样,一个搜索结果包含的搜索关键词越多,得分越高。
idf(t)
此函数出现了两次,也刚好对应公式中的 idf(t)^2;
这个函数被称作倒频率,表示词项T 在所有文档中出现的频率。若它在所有文档中出现的次数越多,表明这个词项T 越不重要;以下是DefaultSimilarity的默认实现。
1 /** Implemented as <code>log(numDocs/(docFreq+1)) + 1</code>. */
2 @Override
3 public float idf(int docFreq, int numDocs) {
4 return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
5 }
此函数实际对结果排序的影响,在于当一次搜索包含多个词项时,文档A和B分别包含了其中一个词项;比如A包含“三国”,B包含“无双”;那么“三国”和“无双”的倒频率就会影响,让A、B的得分产生差异了。若词项只有一个,那本次搜索idf(t) 实际对结果排序不会产生影响。
fieldNorm (t)
它的值对应着公式中 boost(t.field in d)×lengthNorm(t.field in d) 的值。其中boost(t.field in d)的值,在创建索引时就被记录下来,而lengthNorm(t.field in d)得值,会在查询过程中计算;它表示此条搜索结果中,给定字段中包含词项的总数;若值越大,得分越低;你可以这么理解;若A文档有包含了1000个词项,关键词出现的频率为10;而B文档包20个词项,相同关键词出现的频率为8;很明显B文档的打分应该要高一些;由此函数可以起到这样的效果。以下是Similarity 的默认实现,函数名在3.0以后变了,原来就叫lengthNorm
01 /** Decodes a normalization factor stored in an index.
02 * <p>
03 * <b>WARNING: If you override this method, you should change the default
04 * Similarity to your implementation with {<a href="http://my.oschina.net/link1212" target="_blank" rel="nofollow">@link</a> Similarity#setDefault(Similarity)}.
05 * Otherwise, your method may not always be called, especially if you omit norms
06 * for some fields.</b>
07 * <a href="http://my.oschina.net/u/244147" target="_blank" rel="nofollow">@see</a> #encodeNormValue(float)
08 */
09 public float decodeNormValue(byte b) {
10 return NORM_TABLE[b & 0xFF]; // & 0xFF maps negative bytes to positive above 127
11 }
至此Lucene打分流程和Similarity模块的函数已经将的差不多了。可以通过这些函数让你的搜索展示出完全不一样的效果,这也需要根据不同的业务慢慢调试,才能得出最优化的搜索结果
原文地址:http://my.oschina.net/BreathL/blog/51498
搜索引擎和网络爬虫技术群293961767欢迎志同道合的朋友加入!
发表评论
-
java实现动态切换上网IP (ADSL拨号上网) java开发
2013-04-24 10:06 1302动态切换IP的实现主是也由Windows的rasdial命令提 ... -
JAVA字符串处理函数
2013-04-12 09:21 1151Java中的字符串也是一连串的字符。但是与许多其他的计算机语 ... -
Compass将lucene、Spring、Hibernate三者结合
2013-02-01 11:02 1679版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声 ... -
Lucene3.0详解
2013-02-01 10:57 1420★第一部分:概述 1. 我 ... -
Java Web 用户登陆示例代码
2013-02-01 09:56 58118实现功能: 1、用户登陆、注销 2、利用session记 ... -
Java对数函数及Java对数运算
2013-02-01 09:47 6799Java对数函数的计算方法非常有问题,然而在API中却有惊人 ... -
Lucene为不同字段指定不同分词器(转)
2013-01-31 17:34 3476在lucene使用过程中,如 ... -
域名管理与解析原理 — 《Java邮件开发详解》读书笔记
2013-01-31 14:56 1723一 基本概念 1. 域名:域名是由圆点分开一串单词或缩写组 ... -
优秀的Java工程师需要掌握的10项技能
2013-01-31 14:04 1864编程专业相对于计算机领域其他专业来讲,是一门比较难以修炼的专业 ... -
Web开发入门不得不看
2013-01-28 17:31 1036如今,各种互联网的Web ... -
MVC框架的映射和解耦
2013-01-25 21:37 836最近在写一个业务上用到的框架,回想起接触过的一些MVC框架, ... -
JAVA发送EMAIL的例子
2013-07-09 09:44 907import javax.mail.*; ... -
SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎
2012-11-19 09:55 1388前两天看到了一个中国新闻网,这个网站的搜索form的actio ... -
Lucene多字段搜索
2012-11-19 09:53 1043最近在学习Lucene的过程中遇到了需要多域搜索并排序的问题, ... -
lucene之sort
2012-11-16 15:06 1096package cn.zqh.lucene.sort; im ... -
Nginx负载均衡
2012-11-16 11:45 7669最近迷上了Nginx,真实麻雀虽小,五脏俱全..功能实在强大. ... -
Lucene相关度排序的调整
2012-11-16 11:38 1732Lucene的搜索结果默认按 ... -
HashSet重复元素判断
2012-10-15 16:37 9143HashSet不能添加重复的元素,当调用add(Object) ... -
JAVA提高教程(2)-认识Set集合之HashSet
2012-10-09 09:44 976集合在Java里面的作用非 ... -
使用solr搭建你的全文检索
2012-09-28 16:34 1067Solr 是一个可供企业使用的、基于 Lucene 的开箱即用 ...
相关推荐
它的核心功能之一是根据用户查询与文档的相关性进行打分,这个过程涉及到一个关键的概念——评分公式。本文将深入探讨Lucene的评分公式,理解其工作原理,并探讨如何通过自定义评分公式来影响搜索结果的排序。 首先...
《lucene、lucene.NET 详细使用与优化详解》 lucene 是一个广泛使用的全文搜索引擎库,其.NET版本称为lucene.NET,它提供了强大的文本检索和分析能力,适用于各种场景下的全文搜索需求。lucene 并非一个可以直接...
**Lucene 常用功能介绍** Lucene 是一个高性能、全文检索库,由Apache软件基金会开发并维护。它提供了一个简单但功能强大的API,用于在各种应用中实现全文索引和搜索。以下是对Lucene常用功能的详细介绍: 1. **...
lucene打分公式解释,非常详细,帮助理解搜索ranking.
Lucene中的SpanQuery和PhraseQuery详解 Lucene是一个功能强大的搜索引擎库,提供了多种查询方式,其中SpanQuery和PhraseQuery是两个重要的查询类型。本文将详细介绍SpanQuery和PhraseQuery的使用和区别。 一、...
**Lucene分词与查询详解** Lucene是一个高性能、全文本搜索库,广泛应用于各种搜索引擎的开发中。它提供了一套强大的API,用于索引文本数据,并执行复杂的查询操作。在深入理解Lucene的分词与查询机制之前,我们...
本文将深入探讨Lucene示例中的BM25相似度计算,旨在帮助初学者理解如何利用Lucene 4.7.1版本构建索引、执行查询,并比较默认的TF-IDF相似度与BM25相似度的区别。 首先,我们需要了解什么是Lucene。Lucene是一个由...
这样,Lucene 就会使用我们的自定义评分规则进行匹配和排序。 在实际应用中,可能还需要考虑其他因素,如用户偏好、文档质量、关键词位置等。这些都可以通过自定义相似度类中的方法来实现。例如,对于位置敏感的...
在"Lucene 实时搜索视频详解"的课程中,我们将深入探讨如何利用 Lucene 实现高效且实时的搜索功能。 一、Lucene 基础 1. **索引过程**:Lucene 的核心概念之一是建立索引,将原始文本数据转化为可快速查询的结构。...
**Lucene引擎模块详解** Lucene是一个高性能、全文本搜索引擎库,由Apache软件基金会开发并维护,它是Java语言实现的。作为一个开源项目,Lucene为开发者提供了构建自定义搜索引擎应用的基础工具,使得开发者能够...
### Hibernate 与 Lucene 的整合框架详解 #### 一、概述 在软件开发领域,特别是企业级应用开发中,高效的数据检索与管理是至关重要的。Hibernate 和 Lucene 分别作为对象关系映射(ORM)工具和全文搜索引擎,在...
SpringBoot与Lucene集成案例详解 本文将详细介绍如何将SpringBoot与Lucene集成,以实现站内搜索系统。 Lucene是一个高性能的全文检索引擎,它可以帮助我们快速地检索大量的文本数据。 一、案例介绍 在本案例中,...
【Lucene3.0查询类型详解】 在Lucene3.0中,查询处理是一个关键环节,涉及多种查询方式和理论模型。以下是对这些概念的详细解释: 1. **查询方式**: - **顺序查询**:是最简单的查询方式,直接遍历索引,效率较...
Lucene还提供了一些高级功能,如近似搜索(Fuzzy Search)、范围查询(Range Query)、短语高亮(Highlighting)和相似度计算(Similarity)。这些特性可以根据实际需求进一步提升搜索体验。 ### 总结 Lucene搜索...
4. **结果排序**:找到匹配的文档后,Lucene会根据评分机制(如TF-IDF)对结果进行排序,返回最相关的文档。 5. **结果展示**:最后,搜索结果将以用户友好的形式展示出来,包括文档ID、分数和摘要等信息。 **三、...
Lucene,作为一种全文搜索的辅助工具,为我们进行条件搜索,无论是像Google,Baidu之类的搜索引 擎,还是论坛中的搜索功能,还是其它C/S架构的搜索,都带来了极大的便利和比较高的效率。本文主要是利用Lucene对MS Sql...
【Lucene 4.7.0 全套JAR包详解】 Lucene是一个开源全文搜索引擎库,由Apache软件基金会开发并维护。它提供了一个高级、灵活的文本搜索API,允许开发者轻松地在应用程序中实现复杂的搜索功能。这次提供的“lucene-...
jar包,亲测可用