如何对使用Lucene索引的文档进行分类

5

我用Lucene对一组文档进行了分类(字段:内容,类别)。每个文档都有自己的类别,但其中一些被标记为未分类。在Java中有没有简单的方法来对这些文档进行分类?

3个回答

3

从 Lucene 5.2.1 开始,您可以使用索引文档对新文档进行分类。Lucene默认提供了朴素贝叶斯分类器、基于MoreLikeThis类的k最邻近分类器和感知器分类器。

缺点是所有这些类都带有实验性警告,并且用链接到维基百科进行记录。


3
分类是机器学习/统计领域中的一个广泛问题。阅读您的问题后,我觉得您使用了一种SQL group by子句(虽然在Lucene中)。如果您希望机器对文档进行分类,则需要了解机器学习算法,如神经网络、贝叶斯、SVM等。Java中有出色的库可用于这些任务。为此,您需要功能(从数据中提取的一组属性),可以在其上训练算法,以便它可以预测分类标签。
在Java中有一些很好的API(允许您专注于代码而不过多理解那些算法背后的数学理论,但如果您知道将非常有优势)。Weka很好。我还遇到了Manning出版社的几本书,处理这些任务很好。这里你去:
《集体智能实战》第10章(分类):http://www.manning.com/alag/ 《智能Web算法》第5章(分类):http://www.manning.com/marmanis/ 这些都是绝对梦幻般的材料(适合Java人)分类特别适合那些不想深入研究理论(尽管非常重要:))和只想快速获得工作代码的人。
《集体智能实战》使用JDM和Weka解决了分类问题。因此,请查看这两个任务。

当然,我可以从Lucene生成的索引中提取特征。让我在这本书中查一下,然后再回来 ;) - orezvani
我认为许多机器学习算法的问题在于它们只能产生单标签分类,而理想情况下应该是多标签分类。我可能错了,但Weka有一个很好的实现。其他的似乎没有做到这一点。 - Amir Raminfar

3
是的,您可以使用相似性查询来实现此类事情,例如由MoreLikeThisQuery类实现的查询(假设您在Lucene索引中有一些大文本字段)。查看底层MoreLikeThis类的JavaDoc以获取有关其工作方式的详细信息。
要将您的Lucene索引转换为文本分类器,您有两个选择:
  1. 对于任何新文本分类器,请查询最相似的前10或50篇至少有一个类别的文档,对这些“邻居”中的类别出现次数求和,并从这些相似文档中挑选出出现最频繁的三个类别(例如)。

  2. 或者,您可以通过连接(全部或部分)属于此类别的文档的文本来为每个类别索引一个新的聚合文档集。然后在这些“虚假”文档上直接使用输入文本运行相似性查询。

第一种策略在机器学习中被称为k-最近邻分类。第二个是一个hack :)
如果您有许多类别(例如超过1000种),则第二个选项可能更好(更快的分类)。尽管如此,我还没有进行任何干净的性能评估。
您可能还会发现这篇博客帖子有趣。
如果您想使用Solr,则需要启用 MoreLikeThisHandler 并在内容字段上设置 termVectors=true
Python 的 sunburnt Solr 客户端可以执行 mlt 查询。这是一个原型 Python 分类器,它使用维基百科分类的索引来使用 Solr 进行分类:https://github.com/ogrisel/pignlproc/blob/master/examples/topic-corpus/categorize.py

谢谢您的建议,但需要分类的文档大约有10^6个,第一个选项可行吗? - orezvani
我认为第一个更容易实现:你的索引中不需要任何新对象。如果对于你的应用程序来说效果不够好,也可以尝试后者。我没有足够的经验来确定。对于这么多示例进行批处理分类可能需要一些时间。根据最大查询项数(我使用30),如果您使用shingles和具有类别的文档数量在索引中,则单个查询时间可能相当长,例如300ms。训练mahout SGD分类器并在一次特征提取上进行批处理预测可能会更快。 - ogrisel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接