在 Lucene 分类器中使用多个叶子

Posted

技术标签:

【中文标题】在 Lucene 分类器中使用多个叶子【英文标题】:Using multiple Leaves in Lucene Classifiers 【发布时间】:2017-08-24 07:35:54 【问题描述】:

我正在尝试在 lucene 中使用 KNearestNeighbour 分类器。文档分类器在其构造函数中接受一个leafReader,用于训练分类器。 问题是,我用来训练分类器的索引有多个叶子。但是该类的构造函数只接受一个叶子,我找不到将剩余的 LeafReaders 添加到类的过程。我可能会错过一些东西。谁能帮我解决这个问题?

这是我目前使用的代码:

    FSDirectory index = FSDirectory.open(Paths.get(indexLoc));
    IndexReader reader = DirectoryReader.open(index);
    LeafReaderContext leaf = leaves.get(0);
    LeafReader atomicReader = leaf.reader();
    KNearestNeighborDocumentClassifier knn = new KNearestNeighborDocumentClassifier(atomicReader, BM25, null, 10, 0, 0, "Topics", field2analyzer, "Text");

【问题讨论】:

【参考方案1】:

叶子代表索引的每个部分。在性能和资源使用方面,您应该迭代叶子,为每个细分运行分类并累积您的结果。

for (LeafReaderContext context : indexReader.getContext().leaves()) 
  LeafReader reader = context.reader();
  // run for each leaf

如果不可能,您可以使用SlowCompositeReaderWrapper,顾名思义,它可能会非常慢,因为它会即时聚合所有叶子。

LeafReader singleLeaf = SlowCompositeReaderWrapper.wrap(indexReader);
// run classifier on singleLeaf

根据您的 Lucene 版本,它位于 lucene-core 或 lucene-misc(我认为从 Lucene 6.0 开始)。此外,此类已被弃用并计划在 Lucene 7.0 中删除。

第三个选项可能是运行forceMerge(1),直到你只有一个段,你可以为此使用单叶。但是,强制合并到单个段还有其他问题,可能不适用于您的用例。如果您的数据是一次写入然后仅用于读取,则可以使用 forceMerge。如果您有定期更新,您最终将不得不使用第一个选项并自己汇总分类结果。

【讨论】:

我使用的是 lucene 6.3。第一个对我来说不是一个选项,因为我必须一次训练分类器,聚合将是不可能的。 “SlowCompositeReaderWrapper”目前似乎是一个可行的选择。谢谢。

以上是关于在 Lucene 分类器中使用多个叶子的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将多个管道组合到 Neuraxle 或 sklearn 中的单个估计器中以创建多输出分类器并一次性适应

如何在 sklearn 的集成分类器中使用自定义分类器?

如何在斯坦福分类器中使用朴素贝叶斯分类器、SVM 和最大熵

如何在 Weka 分类器中使用 svm?

J48树分类器的叶子节点是啥意思

在 weka 分类器中缩放训练数据