有关Lucene的问题4影响Lucene对文档打分的四种方式.docx

上传人:b****1 文档编号:2793105 上传时间:2023-05-04 格式:DOCX 页数:21 大小:87.28KB
下载 相关 举报
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第1页
第1页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第2页
第2页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第3页
第3页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第4页
第4页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第5页
第5页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第6页
第6页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第7页
第7页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第8页
第8页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第9页
第9页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第10页
第10页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第11页
第11页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第12页
第12页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第13页
第13页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第14页
第14页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第15页
第15页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第16页
第16页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第17页
第17页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第18页
第18页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第19页
第19页 / 共21页
有关Lucene的问题4影响Lucene对文档打分的四种方式.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

有关Lucene的问题4影响Lucene对文档打分的四种方式.docx

《有关Lucene的问题4影响Lucene对文档打分的四种方式.docx》由会员分享,可在线阅读,更多相关《有关Lucene的问题4影响Lucene对文档打分的四种方式.docx(21页珍藏版)》请在冰点文库上搜索。

有关Lucene的问题4影响Lucene对文档打分的四种方式.docx

有关Lucene的问题4影响Lucene对文档打分的四种方式

有关Lucene的问题(4):

影响Lucene对文档打分的四种方式

在索引阶段设置DocumentBoost和FieldBoost,存储在(.nrm)文件中。

如果希望某些文档和某些域比其他的域更重要,如果此文档和此域包含所要查询的词则应该得分较高,则可以在索引阶段设定文档的boost和域的boost值。

这些值是在索引阶段就写入索引文件的,存储在标准化因子(.nrm)文件中,一旦设定,除非删除此文档,否则无法改变。

如果不进行设定,则DocumentBoost和FieldBoost默认为1。

DocumentBoost及FieldBoost的设定方式如下:

Documentdoc=newDocument();

Fieldf=newField("contents","helloworld",Field.Store.NO,Field.Index.ANALYZED);

f.setBoost(100);

doc.add(f);

doc.setBoost(100);

两者是如何影响Lucene的文档打分的呢?

让我们首先来看一下Lucene的文档打分的公式:

score(q,d)  =  coord(q,d) · queryNorm(q) · ∑(tf(tind) · idf(t)2 · t.getBoost()· norm(t,d))

                                                                      tinq

DocumentBoost和FieldBoost影响的是norm(t,d),其公式如下:

norm(t,d)  =  doc.getBoost() · lengthNorm(field) · ∏f.getBoost()

fieldfindnamedast

它包括三个参数:

∙Documentboost:

此值越大,说明此文档越重要。

∙Fieldboost:

此域越大,说明此域越重要。

∙lengthNorm(field)=(1.0/Math.sqrt(numTerms)):

一个域中包含的Term总数越多,也即文档越长,此值越小,文档越短,此值越大。

其中第三个参数可以在自己的Similarity中影响打分,下面会论述。

当然,也可以在添加Field的时候,设置Field.Index.ANALYZED_NO_NORMS或Field.Index.NOT_ANALYZED_NO_NORMS,完全不用norm,来节约空间。

根据Lucene的注释,Nonormsmeansthatindex-timefieldanddocumentboostingandfieldlengthnormalizationaredisabled. ThebenefitislessmemoryusageasnormstakeuponebyteofRAMperindexedfieldforeverydocumentintheindex,duringsearching. Notethatonceyouindexagivenfieldwithnormsenabled,disablingnormswillhavenoeffect.没有norms意味着索引阶段禁用了文档boost和域的boost及长度标准化。

好处在于节省内存,不用在搜索阶段为索引中的每篇文档的每个域都占用一个字节来保存norms信息了。

但是对norms信息的禁用是必须全部域都禁用的,一旦有一个域不禁用,则其他禁用的域也会存放默认的norms值。

因为为了加快norms的搜索速度,Lucene是根据文档号乘以每篇文档的norms信息所占用的大小来计算偏移量的,中间少一篇文档,偏移量将无法计算。

也即norms信息要么都保存,要么都不保存。

下面几个试验可以验证norms信息的作用:

试验一:

DocumentBoost的作用

publicvoidtestNormsDocBoost()throwsException{

 FileindexDir=newFile("testNormsDocBoost");

 IndexWriterwriter=newIndexWriter(FSDirectory.open(indexDir),newStandardAnalyzer(Version.LUCENE_CURRENT),true,IndexWriter.MaxFieldLength.LIMITED);

 writer.setUseCompoundFile(false);

 Documentdoc1=newDocument();

 Fieldf1=newField("contents","commonhellohello",Field.Store.NO,Field.Index.ANALYZED);

 doc1.add(f1);

 doc1.setBoost(100);

 writer.addDocument(doc1);

 Documentdoc2=newDocument();

 Fieldf2=newField("contents","commoncommonhello",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

 doc2.add(f2);

 writer.addDocument(doc2);

 Documentdoc3=newDocument();

 Fieldf3=newField("contents","commoncommoncommon",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

 doc3.add(f3);

 writer.addDocument(doc3);

 writer.close();

 IndexReaderreader=IndexReader.open(FSDirectory.open(indexDir));

 IndexSearchersearcher=newIndexSearcher(reader);

 TopDocsdocs=searcher.search(newTermQuery(newTerm("contents","common")),10);

 for(ScoreDocdoc:

docs.scoreDocs){

   System.out.println("docid:

"+doc.doc+"score:

"+doc.score);

 }

}

如果第一篇文档的域f1也为Field.Index.ANALYZED_NO_NORMS的时候,搜索排名如下:

docid:

2score:

1.2337708

docid:

1score:

1.0073696

docid:

0score:

0.71231794

如果第一篇文档的域f1设为Field.Index.ANALYZED,则搜索排名如下:

docid:

0score:

39.889805

docid:

2score:

0.6168854

docid:

1score:

0.5036848

试验二:

FieldBoost的作用

如果我们觉得title要比contents要重要,可以做一下设定。

publicvoidtestNormsFieldBoost()throwsException{

 FileindexDir=newFile("testNormsFieldBoost");

 IndexWriterwriter=newIndexWriter(FSDirectory.open(indexDir),newStandardAnalyzer(Version.LUCENE_CURRENT),true,IndexWriter.MaxFieldLength.LIMITED);

 writer.setUseCompoundFile(false);

 Documentdoc1=newDocument();

 Fieldf1=newField("title","commonhellohello",Field.Store.NO,Field.Index.ANALYZED);

 f1.setBoost(100);

 doc1.add(f1);

 writer.addDocument(doc1);

 Documentdoc2=newDocument();

 Fieldf2=newField("contents","commoncommonhello",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

 doc2.add(f2);

 writer.addDocument(doc2);

 writer.close();

 IndexReaderreader=IndexReader.open(FSDirectory.open(indexDir));

 IndexSearchersearcher=newIndexSearcher(reader);

 QueryParserparser=newQueryParser(Version.LUCENE_CURRENT,"contents",newStandardAnalyzer(Version.LUCENE_CURRENT));

 Queryquery=parser.parse("title:

commoncontents:

common");

 TopDocsdocs=searcher.search(query,10);

 for(ScoreDocdoc:

docs.scoreDocs){

   System.out.println("docid:

"+doc.doc+"score:

"+doc.score);

 }

}

如果第一篇文档的域f1也为Field.Index.ANALYZED_NO_NORMS的时候,搜索排名如下:

docid:

1score:

0.49999997

docid:

0score:

0.35355338

如果第一篇文档的域f1设为Field.Index.ANALYZED,则搜索排名如下:

docid:

0score:

19.79899

docid:

1score:

0.49999997

试验三:

norms中文档长度对打分的影响

publicvoidtestNormsLength()throwsException{

 FileindexDir=newFile("testNormsLength");

 IndexWriterwriter=newIndexWriter(FSDirectory.open(indexDir),newStandardAnalyzer(Version.LUCENE_CURRENT),true,IndexWriter.MaxFieldLength.LIMITED);

 writer.setUseCompoundFile(false);

 Documentdoc1=newDocument();

 Fieldf1=newField("contents","commonhellohello",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

 doc1.add(f1);

 writer.addDocument(doc1);

 Documentdoc2=newDocument();

 Fieldf2=newField("contents","commoncommonhellohellohellohello",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

 doc2.add(f2);

 writer.addDocument(doc2);

 writer.close();

 IndexReaderreader=IndexReader.open(FSDirectory.open(indexDir));

 IndexSearchersearcher=newIndexSearcher(reader);

 QueryParserparser=newQueryParser(Version.LUCENE_CURRENT,"contents",newStandardAnalyzer(Version.LUCENE_CURRENT));

 Queryquery=parser.parse("title:

commoncontents:

common");

 TopDocsdocs=searcher.search(query,10);

 for(ScoreDocdoc:

docs.scoreDocs){

   System.out.println("docid:

"+doc.doc+"score:

"+doc.score);

 }

}

当norms被禁用的时候,包含两个common的第二篇文档打分较高:

docid:

1score:

0.13928263

docid:

0score:

0.09848769

当norms起作用的时候,虽然包含两个common的第二篇文档,由于长度较长,因而打分较低:

docid:

0score:

0.09848769

docid:

1score:

0.052230984

试验四:

norms信息要么都保存,要么都不保存的特性

publicvoidtestOmitNorms()throwsException{

 FileindexDir=newFile("testOmitNorms");

 IndexWriterwriter=newIndexWriter(FSDirectory.open(indexDir),newStandardAnalyzer(Version.LUCENE_CURRENT),true,IndexWriter.MaxFieldLength.LIMITED);

 writer.setUseCompoundFile(false);

 Documentdoc1=newDocument();

 Fieldf1=newField("title","commonhellohello",Field.Store.NO,Field.Index.ANALYZED);

 doc1.add(f1);

 writer.addDocument(doc1);

 for(inti=0;i<10000;i++){

   Documentdoc2=newDocument();

   Fieldf2=newField("contents","commoncommonhellohellohellohello",Field.Store.NO,Field.Index.ANALYZED_NO_NORMS);

   doc2.add(f2);

   writer.addDocument(doc2);

 }

 writer.close();

}

当我们添加10001篇文档,所有的文档都设为Field.Index.ANALYZED_NO_NORMS的时候,我们看索引文件,发现.nrm文件只有1K,也即其中除了保持一定的格式信息,并无其他数据。

当我们把第一篇文档设为Field.Index.ANALYZED,而其他10000篇文档都设为Field.Index.ANALYZED_NO_NORMS的时候,发现.nrm文件又10K,也即所有的文档都存储了norms信息,而非只有第一篇文档。

在搜索语句中,设置QueryBoost.

在搜索中,我们可以指定,某些词对我们来说更重要,我们可以设置这个词的boost:

common^4hello

使得包含common的文档比包含hello的文档获得更高的分数。

由于在Lucene中,一个Term定义为Field:

Term,则也可以影响不同域的打分:

title:

common^4content:

common

使得title中包含common的文档比content中包含common的文档获得更高的分数。

实例:

publicvoidtestQueryBoost()throwsException{

 FileindexDir=newFile("TestQueryBoost");

 IndexWriterwriter=newIndexWriter(FSDirectory.open(indexDir),newStandardAnalyzer(Version.LUCENE_CURRENT),true,IndexWriter.MaxFieldLength.LIMITED);

 Documentdoc1=newDocument();

 Fieldf1=newField("contents","common1hellohello",Field.Store.NO,Field.Index.ANALYZED);

 doc1.add(f1);

 writer.addDocument(doc1);

 Documentdoc2=newDocument();

 Fieldf2=newField("contents","common2common2hello",Field.Store.NO,Field.Index.ANALYZED);

 doc2.add(f2);

 writer.addDocument(doc2);

 writer.close();

 IndexReaderreader=IndexReader.open(FSDirectory.open(indexDir));

 IndexSearchersearcher=newIndexSearcher(reader);

 QueryParserparser=newQueryParser(Version.LUCENE_CURRENT,"contents",newStandardAnalyzer(Version.LUCENE_CURRENT));

 Queryquery=parser.parse("common1common2");

 TopDocsdocs=searcher.search(query,10);

 for(ScoreDocdoc:

docs.scoreDocs){

   System.out.println("docid:

"+doc.doc+"score:

"+doc.score);

 }

}

根据tf/idf,包含两个common2的第二篇文档打分较高:

docid:

1score:

0.24999999

docid:

0score:

0.17677669

如果我们输入的查询语句为:

"common1^100common2",则第一篇文档打分较高:

docid:

0score:

0.2499875

docid:

1score:

0.0035353568

那QueryBoost是如何影响文档打分的呢?

根据Lucene的打分计算公式:

score(q,d)  =  coord(q,d) · queryNorm(q) ·∑(tf(tind) · idf(t)2 · t.getBoost()· norm(t,d))

                                                                     tinq

注:

在queryNorm的部分,也有q.getBoost()的部分,但是对query向量的归一化(见向量空间模型与Lucene的打分机制[

继承并实现自己的Similarity

Similariy是计算Lucene打分的最主要的类,实现其中的很多借口可以干预打分的过程。

(1)floatcomputeNorm(Stringfield,FieldInvertStatestate)

(2)floatlengthNorm(StringfieldName,intnumTokens)

(3)floatqueryNorm(floatsumOfSquaredWeights)

(4)floattf(floatfreq)

(5)floatidf(intdocFreq,intnumDocs)

(6)floatcoord(intoverlap,intmaxOverlap)

(7)floatscorePayload(intdocId,StringfieldName,intstart,intend,byte[]payload,intoffset,intlength)

它们分别影响Lucene打分计算的如下部分:

score(q,d)  =  (6)coord(q,d) · (3)queryNorm(q) ·∑((4)tf(tind) · (5)idf(t)2 · t.getBoost()· 

(1)norm(t,d))

tinq

norm(t,d)  =  doc.getBoost() · 

(2)lengthNorm(field) · ∏f.getBoost()

                                                                          fieldfind

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2