如何对用 lucene 索引的文档进行分类
Posted
技术标签:
【中文标题】如何对用 lucene 索引的文档进行分类【英文标题】:How to classify documents indexed with lucene 【发布时间】:2012-03-16 15:57:12 【问题描述】:我用 Lucene 对一组文档进行了分类(字段:内容、类别)。每个文档都有自己的类别,但其中一些被标记为未分类。有没有什么方法可以在java中轻松分类这些文档?
【问题讨论】:
【参考方案1】:分类是机器学习/统计领域的一个广泛问题。阅读您的问题后,我觉得您使用了一种 SQL 分组语句(尽管在 Lucene 中)。如果您希望机器对文档进行分类,那么您需要了解机器学习算法,例如神经网络、贝叶斯、SVM 等。Java 中有出色的库可用于这些任务。为此,您将需要特征(从数据中提取的一组属性),您可以在这些特征上训练您的算法,以便它可以预测您的分类标签。
Java 中有一些很好的 API(它可以让您专注于代码,而无需过多地理解这些算法背后的数学理论,但如果您知道这将是非常有利的)。维卡不错。我还看到了曼宁的几本书,它们很好地处理了这些任务。给你:
第 10 章(分类)集体智慧行动:http://www.manning.com/alag/
第5章(分类)智能网算法:http://www.manning.com/marmanis/
这些绝对是很棒的分类材料(对于 Java 人来说),特别适合那些不想深入研究理论(虽然非常重要:))并且很快想要一个工作代码的人。
Collective Intelligence in Action 使用 JDM 和 Weka 解决了分类问题。因此,请查看这两个以完成您的任务。
【讨论】:
当然,我可以从 Lucene 生成的索引中提取特征。让我在这本书里看看,我会回来的;) 我认为其中许多 ML 的问题在于它们产生单标签分类,而多标签分类是理想的。我可能错了,但 Weka 很好地实现了这一点。其余的似乎没有完成这项工作。【参考方案2】:是的,您可以使用相似性查询,例如由MoreLikeThisQuery class 实现的此类事情(假设您的文档中有一些大的文本字段用于您的 lucene 索引)。查看底层 MoreLikeThis class 的 javadoc 以了解其工作原理的详细信息。
要将 lucene 索引转换为文本分类器,您有两种选择:
对于分类器的任何新文本,查询具有至少一个类别的前 10 或 50 个最相似的文档,将这些“邻居”中的类别出现次数相加,并在相似的类别中选取前 3 个频繁类别文件(例如)。
或者,您可以索引一组新的聚合文档,通过连接(全部或部分)该类别文档的文本为每个类别创建一个。然后直接在那些“假”文档上输入文本运行相似度查询。
第一个策略在机器学习中称为 k-最近邻分类。第二个是 hack :)
如果您有很多类别(比如超过 1000 个),则第二个选项可能会更好(分类速度更快)。不过,我还没有进行任何干净的性能评估。
您可能还会发现这个blog post interesting。
如果你想使用 Solr,你需要启用 MoreLikeThisHandler 并在内容字段上设置termVectors=true
。
用于 python 的 sunburnt Solr 客户端能够执行 mlt 查询。这是一个原型 python 分类器,它使用 Solr 使用***类别的索引进行分类:
https://github.com/ogrisel/pignlproc/blob/master/examples/topic-corpus/categorize.py
【讨论】:
谢谢您的建议,但是要分类的文档大约有10^6个,第一个选项好吗? 我认为第一个更容易实现:您不需要在索引中添加任何新对象。如果它对您的应用程序不够好,也请尝试后者。我没有足够的经验来确定。批量分类这么多示例可能需要一些时间。根据最大查询词的数量(我使用 30),如果您使用 shingles 和索引中具有类别的文档数量,则单个查询时间可能会很长,例如 300 毫秒。训练一个 mahout SGD 分类器并在一次特征提取上进行批量预测可能会更快。【参考方案3】:从 Lucene 5.2.1 开始,您可以使用 indexed documents to classify new documents。开箱即用,Lucene 提供了一个朴素贝叶斯分类器、一个 k 近邻分类器(基于 MoreLikeThis 类)和一个基于感知器的分类器。
缺点是所有这些类都标有实验性警告,并附有***的链接。
【讨论】:
以上是关于如何对用 lucene 索引的文档进行分类的主要内容,如果未能解决你的问题,请参考以下文章