首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在BM25实现中计算avgLengthPath

如何在BM25实现中计算avgLengthPath
EN

Stack Overflow用户
提问于 2012-08-09 10:27:11
回答 1查看 1K关注 0票数 0

谁能给我解释一下如何在Lucene的BM25实现中计算'avgLengthPath‘变量。我所理解的是,我必须在索引过程中计算它。但目前仍不清楚如何做到这一点。

提供的示例如下:

代码语言:javascript
复制
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);
}

建议存在用于加载平均长度的方法或类。

会很感谢你的帮助。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-12 14:44:41

我已经解决了这个问题,我想分享我的答案,以获得任何更正或评论。

问题是如何计算avgLengthPath参数。当我查看接受此参数的方法:load()时,可以看到它需要一个字符串,该字符串是包含平均长度的文件的路径。所以avgLengthPath应该是这样的:

代码语言:javascript
复制
/Users/admib/Study/avgLength

load()方法如下:

代码语言:javascript
复制
    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文件的格式应如下所示:

代码语言:javascript
复制
CONTENT 
459.2903f
ANCHOR
84.55523f

其中第一行是文件名,第二行是该字段的平均长度。此外,第三行是另一个字段,第四行是该字段的平均长度。

这类文件的问题在于,我们无法从Lucene的默认位置获取文档长度。为了克服这个问题,我重新索引了我的集合,并将文档长度添加为Lucene要索引的字段之一。

首先,我创建了一个接受文件并以字符串形式返回文档长度的方法。我管它叫getDocLength(File f)

代码语言:javascript
复制
    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();
    }
}

在索引过程中调用此方法来添加文档长度字段,如下所示:

代码语言:javascript
复制
 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()

代码语言:javascript
复制
    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);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11875949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档