2012-08-09 61 views
0

任何人都可以向我解釋如何計算Lucene的BM25實現中的'avgLengthPath'變量。我的理解是,我必須在索引期間計算它。但仍不清楚如何去做。如何計算Lucene(JAVA)的BM25實現中的avgLengthPath

提供的示例:

IndexSearcher searcher = new IndexSearcher("IndexPath"); 

//Load average length 
BM25Parameters.load(avgLengthPath); 
BM25BooleanQuery query = new BM25BooleanQuery("This is my Query", 
    "Search-Field", 
    new StandardAnalyzer()); 

TopDocs top = searcher.search(query, null, 10); 
ScoreDoc[] docs = top.scoreDocs; 

//Print results 
for (int i = 0; i $<$ top.scoreDocs.length; i++) { 
     System.out.println(docs[i].doc + ":"+docs[i].score); 
} 

表明,有一個方法或類以從加載的平均長度。

希望得到任何幫助......

感謝

回答

1

我已經解決了這個問題,我想和大家分享我的回答得到任何更正或意見..

的問題是如何計算avgLengthPath參數。當我查看採用此參數的方法時:load()可以看出它需要一個字符串,它是包含平均長度的文件的路徑。所以avgLengthPath會是這樣的:

/Users/admib/Study/avgLength 

load()方法如下:

public static void load(String path) throws NumberFormatException, 
     IOException { 
    BufferedReader in = new BufferedReader(new FileReader(path)); 
    String line; 
    while (null != (line = in.readLine())) { 
     String field = line; 
     Float avg = new Float(in.readLine()); 
     BM25Parameters.setAverageLength(field, avg); 
    } 
    in.close(); 
} 

現在恐怕看看如何創建這樣的文件。我們可以看到上面的方法逐行讀取文件並將每兩行發送到另一個稱爲BM25Parameters.setAverageLength()的方法。該avgLengthPath文件的甲應該是這樣的:

CONTENT 
459.2903f 
ANCHOR 
84.55523f 

當第一行是提起名字,第二行是這一領域的平均長度。 此外,第三行是另一個字段,第四行是該字段的平均長度。

這個文件的問題是,我們無法從默認位置獲取Lucene的文檔長度。爲了克服這個問題,我重新索引了我的集合,並將文檔長度添加爲由Lucene索引的字段之一。

首先我創建了一個方法,它接受一個文件並將文檔長度作爲字符串返回。我把它叫做getDocLength(File f)

public static String getDocLength(File f) throws IOException { 
    FileInputStream stream = new FileInputStream(f); 
    try { 
     FileChannel fc = stream.getChannel(); 
     MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 

     String doc = Charset.defaultCharset().decode(bb).toString(); 
     int length = doc.length(); 
     return Integer.toString(length); 
    } finally { 
     stream.close(); 
    } 
} 

在索引過程中該方法被調用並把文件長度字段中添加如下:

protected Document getDocument(File f) throws Exception { 
    Document doc = new Document(); 
    String docLength = Integer.toString(io.getDocLength(f)); 
    doc.add(new Field("contents", new FileReader(f), Field.TermVector.YES)); 
    doc.add(new Field("docLength", i, Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("filename", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
    doc.add(new Field("fullpath", f.getCanonicalPath(), Field.Store.YES, Field.Index.NOT_ANALYZED));   
    return doc; 
} 

最後,我在索引創建了一個方法,通過所有文檔環路和計算平均文檔長度,最後將結果保存到帶有正確的合成文件的avgLengthPath文件中。我稱這種方法generateAvgLengthPathFile()

public static void generateAvgLengthPathFile(String luceneIndexPath, String outputFilePath) { 
    try { 
     Directory dir = FSDirectory.open(new File(luceneIndexPath)); 
     IndexReader reader = IndexReader.open(dir); 
     int totalLength = 0; 
     //here we loop through all the docs in the index 
     for (int i = 0; i < reader.maxDoc(); i++) { 
      if (reader.isDeleted(i)) { 
       continue; 
      } 
      Document doc = reader.document(i); 
      totalLength += Integer.parseInt(doc.get("docLength")); 
     } 
     //calculate the avarage length 
     float avarageLength = totalLength * 1.0f/reader.maxDoc() * 1.0f; 
     //create the a String varibale with the correct formate 
     String avgLengthPathFile = "contents" + "\n" + avarageLength; 

     //finally, save the file 
     Writer output = null; 
     String text = "contents" + "\n" + avarageLength; 
     File file = new File(outputFilePath); 
     output = new BufferedWriter(new FileWriter(file)); 
     output.write(text); 
     output.close(); 

    } catch (Exception e) { 
System.err.println(e); 
    } 
} 
+0

我剛剛發現這個[鏈接](http://ipl.cs.aueb.gr/stougiannis/bm25_2.html),提供有關在Lucene的運行BM25好細節。另外,從這個[question](http://stackoverflow.com/questions/9675444/lucene-4-0-statistics),似乎Lucene 4對BM25有一些支持。 – user692704 2012-08-13 02:55:35