§ 1。配置Lucene,对ccer数据建立索引和查询系统
中文分词模块(IKAnalyzer可选)
§ 2。阅读代码,分析Lucene的ranking算法。写一个简短的报告文档。
§ 3。改进ranking算法,并进行评估,给出一个实验报告。
算法改进可用方法:PageRank Combination, LSI, Language Model, or…
评估指标可用:P@10, MAP, F1, or …
评估方法可用:human judgment or auto compare with google result or …
1. 使用IKAnalyzer对ccer下的18652左右的网页进行了索引建立和查询系统的建立,索引建立的过程大概持续了10分钟,CPU使用率持续100%。下面是索引建立之后的文件。
Index文件 (调用了optimize之后的结果)
实现代码如下。(附件中)
(我们做的是将目标的URL和所得的分数显示出来)
查询结果如下:
(1)搜“北京大学”
ReadNews.asp?NewsID=1487 0.14996947
readview.asp?reviewID=2296&NewsID=24960.14321162
ReadNews.asp?NewsID=83950.14157297
ReadNews.asp?NewsID=4173 0.14049698
ReadNews.asp?NewsID=1890 0.14018208
ReadNews.asp?NewsID=3450 0.13792434
readview.asp?reviewID=2958&NewsID=30200.13510498
ReadNews.asp?NewsID=6009 0.13157436
ReadNews.asp?NewsID=2808 0.13154271
ReadNews.asp?NewsID=1587 0.12664454
18292 pages(s) found (in 63 milliseconds)
我看了下网页中的内容,搜索结果中,第一个网页有39处匹配,文档内容也较长。第二个网页有3处匹配,文档内容很短。第三个网页有27处匹配,文档内容较长。。。
(2)第二次搜索是针对第一次搜索结果中,排在第三位的网页中的内容。网页中有一个获得全国三好学生的学生名字,叫“曾垚”。试下看看结果。
ReadNews.asp?NewsID=8395 0.73862696
ReadNews.asp?NewsID=8448 0.10303292
ReadNews.asp?NewsID=10894 0.10303292
news.asp?alllistpage=91 0.09587039
ReadNews.asp?NewsID=10557 0.09587039
ReadNews.asp?NewsID=6889 0.09587039
6 pages(s) found (in 31 milliseconds)
果然,第一个匹配的网页是第一次搜索的第三个网页,结果还不错。
2.通过阅读相关文档和源代码,Lucene的Ranking算法中,包括score的计算和相似度分析。
Lucene 将信息检索中的Boolean model (BM)和Vector Space Model(VSM)联合起来,实现了自己的评分机制。VSM模型如下:
计算某个查询q的文档d得分如下(摘自API文档注释):其中每个因子的分析如下:
1) 在Lucene的实现中,使用了
2) 反映有多少个文档包含了该term,文档数越多,该因子的值越小,反之越大。计算idf的常用方法为
3) 查询时期t的加权,或者由t.setBoost(int boost)来指定
4) 压缩几个索引期间的加权和长度因子。计算公式如下:
其中的因子解释如下:
Document boost:
文档加权。在索引创建过程中写入了索引中。用 doc.setBoost()
Field boost:
字段加权,在索引创建过程中写入了索引中。 field.setBoost()
lengthNorm(field):
由字段(Field)内的 Token 的个数来计算此值,字段越短,评分越高,在做索引的时候由Similarity.lengthNorm 计算。
5) 评分因子,是基于文档中出现查询项的个数。越多的查询项在一个文档中,说明些文档的匹配程序越高。
6) 查询的标准查询,使不同查询之间可以比较。此因子不影响文档的排序,因为所有有文档都会使用此因子。这个因子是在查询的时候计算的。
而sumOfSquareWeights的计算由下面来得到:
(注:以上部分摘自Lucene的API文档的英文部分,自己进行了理解和翻译)
在Lucene的Ranking计算过程中,包括了Query、Weight、Score、Similarity,Collector几个不同的类。文档匹配阶段主要调用Searcher对象的search方法,在search方法内部,通过直接或间接调用,search(Weightweight, Filter filter, Collectorcollector)方法。通过阅读源代码,使用search的时候都将得到一个Weight对象(第一个的search方法显示调用了Query的createWeight方法来创建一个Weight对象),Weight对象会创建一个Scorer对象,Scorer对象来进行score函数的调用并将结果保存在Collector对象中。如下:
。
public void search(Query query,Collector results)
throwsIOException {
search(createWeight(query), null, results);
}
@Override
public voidsearch(Weight weight, Filter filter, Collectorcollector)
throws IOException {
if(filter == null) {//没有使用Filter对象的时候
for (int i = 0; i < subReaders.length;i++) { // 遍历每个subReader,但在indexSearcher中,只有一个reader
collector.setNextReader(subReaders[i], docStarts[i]);
Scorer scorer = weight.scorer(subReaders[i],!collector.acceptsDocsOutOfOrder(),true);//创建了一个scorer对象
if (scorer != null) {
scorer.score(collector);//将结果保存在collector中,以便后边使用
}
}
}else {
for (int i = 0; i < subReaders.length;i++) { // search each subreader
collector.setNextReader(subReaders[i], docStarts[i]);
searchWithFilter(subReaders[i], weight, filter,collector);
}
}
}
public Weightweight(Searcher searcher) throws IOException {
Query query= searcher.rewrite(this);
Weightweight = query.createWeight(searcher);
floatsum = weight.sumOfSquaredWeights();
floatnorm = getSimilarity(searcher).queryNorm(sum);
if(Float.isInfinite(norm) || Float.isNaN(norm))
norm = 1.0f;
weight.normalize(norm);//归一化
return weight;
}
在源代码中可以看出(没有列出),在IndexReader中的subReaders数组中存放的只有原reader,没有其他的reader,那么docStarts数组中也是一个只包含一个0的长度为1的数组。构造Weight对象,通过调用scorer函数来构造Score对象,得到所有符合要求的文档序列。
IDF的计算:(在DefaultSimilarity类中)
public floatidf(int docFreq, int numDocs) {
return(float)(Math.log(numDocs/(double)(docFreq+1))+ 1.0);
}
TF的计算:(在DefaultSimilarity中)
publicfloat tf(float freq) {
return (float)Math.sqrt(freq);
}
得到Boost:(在Query类中。虽然在Fieldable接口和Document类中也有setBoost方法,但是还是建议在Query中调用,因为在Fieldable和Document中定义boost的话,会一同写到index中,想改变boost会变得困难。如果确实想提高一个文档或文档中某个Field的分值,可以同index一起写到索引文件中)
public float getBoost() { return boost;}//Query类中的方法
3. Lucene的Ranking算法的结果主要有Score和Similarity来进行计算,所以要改进Ranking算法,要从这两个方面入手。
思路:
1) 网页的重要性
对网页的链接分析得到。网页的链接分析主要根据外部链接网页的数量和链接网页的质量,网页内容的主题相关性等内容,确定网页重要性。来改变Score的计算结果。
2) 关键词匹配程度:
根据关键字匹配的算法,对基本的检索理论进行改进,针对不同位置、不同格式、不同形式的关键词,进行综合计算,最终得到每个文档与检索相关的匹配程度。