我已經解決了這個問題,我想和大家分享我的回答得到任何更正或意見..
的問題是如何計算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);
}
}
我剛剛發現這個[鏈接](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