如何按常见主题对字符串进行分组?


10

我试图将例如关于编程的字符串与其他关于编程的字符串,关于物理的字符串与关于物理的其他字符串等进行分组,以涵盖广泛的主题。尽管问题在语言学方面令人眼花aspect乱,但我仍希望使用编程/软件来实际执行此操作。

总结:给定大量字符串,我该如何按语义主题对它们进行分组?

特定的应用程序:我有大约200,000个琐事问题,我想将其归类为常见的组别(汽车,计算机,政治,加拿大,食品,巴拉克·奥巴马(Barack Obama)等)。

我研究的内容: Wikipedia 列出了自然语言处理工具包(假设我要尝试的工作实际上是NLP),因此我查看了一些内容,但似乎没有一个能满足我的需求。

注意:已经指出,这样做需要更多的知识(例如,保时捷是汽车,C ++是编程语言)。当时我认为需要训练数据,但是如果我只有问题和答案的列表,那么如何生成训练数据?然后如何使用训练数据?

更多说明:如果我的问与答帮助的当前格式(尽管看起来像JSON,但基本上是原始文本文件):

// row 1: is metadata
// row 2: is a very specific kind of "category"
// row 3: is the question
// row 4: is the answer
{
  15343
  A MUSICAL PASTICHE
  Of classical music's "three B's", he was the one born in Hamburg in 1833
  Johannes Brahms
}

但是在有人指出已经存在一个类别之前,请注意,大约有20万个这样的问题和答案,并且基本上有许多“类别”。我正在尝试将它们分为以上所列的更广泛的组。此外,我可以通过编程方式轻松地针对所有问题更改此格式。

以及更多注意事项:我实际上不知道我需要多少个类别(至少10-20个),因为我自己并未阅读所有问题。我部分期望在分类过程中以某种方式确定有限数。无论如何,我总是可以手动创建多个类别。


你怎么用胡萝卜?从我对此的简短阅读中,看来它应该可以轻松处理20万条记录。

它只花了比我预期的时间长得多的时间,并迫使我将JVM的初始内存分配增加到1024m,并将最大内存增加到2048m。这没有我说的那么糟糕。

您只需要足够的培训数据,然后就可以将问题分类为这些类别。全自动方法可能最终会通过其他方式将它们分组,例如,包含“汽车”一词的问题。创建分组时,您不能同时学习同义词。
已退出– Anony-Mousse 2012年

嗯,您正在执行批量处理;提供JVM并不是真正的问题。它花了多少时间?您是从哪里装载文件的?自定义来源?

我大概花了10分钟,但我同意,根据定义,批量处理非常耗时且占用大量内存。尽管这不是问题的全部话题,但更多是附带说明。

Answers:


4

在NLP中,这是一个相当标准的问题,而您正在寻找的神奇的Google单词是“主题建模”。尽管字符串很短,但是使用Latent Dirichlet Allocation或类似的方法可能会取得一些成功。有一个很好的博客文章由埃德温·陈在这里,其中规定了该算法背后的总体思路。实现的详细信息在本说明王毅。

如果您正在寻找现成的解决方案,我建议您试用topicmodelsR 的软件包,因为它为LDA和更复杂的“相关主题模型”提供了一个相当不错的接口。David Mimno 在这里还维护了很多实现。


谢谢,Chen的博客文章似乎已成为我正在尝试做的事情。您是否有可能使用过之前列出/完成的所有操作?我在这里处于全新的境地,并希望逐步了解我需要做的事情(使用一种现成的解决方案)。我应该如何格式化我的“文档”?我是否应该将ID应用于每个问答,以便识别哪个文档属于哪个组?如何使用输出的数据?就像我说的,我不了解很多细节。
Whymarrh

我已经使用了R topicmodels包很多。我肯定会推荐您使用自己的代码-在cran.r-project.org/web/packages/topicmodels/vignettes/…中有一些包含示例的文档。每个文档的特定格式并不重要,因为无论如何一切都将简化为“单词袋”表示。只需将所有关联的文本放入一个字符串中即可。
Martin O'Leary 2012年

4

您正在尝试在这里解决两个问题。

问题1:将问题字符串分类为正确的类别。

问题2:创建适当的类别。

第一个问题可以通过所谓的监督算法来解决,许多分类器可以提供非常好的准确性和性能。但是,问题2凭空创建类别(大量数据)要棘手得多。这是一个不受监督的问题,在给定大量条件的情况下,计算机可以自动确定类别的数据。理想情况下,这些条件和算法应将数据整齐地组织到群集中。然后可以将其标记。但是,由于这是一项艰巨的任务,我想说的是,这里没有可以接受的直接解决方案,无需大量调整工作即可获得良好的结果,而这可能需要专家进行大量调整。

因此,恐怕这里还没有魔术按钮。但是,您可以做的是稍微帮助一下机器。例如,您可以决定类别集。确定类别后,您可以创建训练数据。在这种设置中,训练数据只是问题和正确的类别对。

训练数据越多越好。但是,由于任务仍然是自动执行某项任务,因此一开始手动执行任务没有任何意义。现在为什么要拥有训练数据?准确性评估。如果要获得良好的结果,至关重要的是,您可以对设置的效果进行某种评估。做到这一点的唯一方法是系统地手动标记一些问题。否则,您将处于盲目状态。

然后,确实出现了一些新问题。第一:我需要多少训练数据?“这取决于”。在没有看到您的数据或类别的情况下,我不确定我是否会猜测。但我可以估算一下,说出约500个问题。请注意,我可能偏离了一个数量级。

这是否真的意味着您必须手动标记500个问题?是的,没有。可以使用中间结果和一些巧妙的“引导”分类器。不过,它仍然是手动工作,当您考虑它时,只需500个问题即可花很长时间。在这里聪明可以比勤劳迅速产生更糟糕的结果。

当您拥有足够数量的训练数据时,请使用其中的75%,然后使用您喜欢的工具(例如,此处提到的工具或诸如此类的工具)创建分类器。现在,让分类器尝试标记保留的25%的数据并衡量由此产生的准确性。如果效果良好,则加香槟。如果不是,则提供更多训练数据或尝试其他分类器。

TL; DR

总而言之,这就是我要做的事情。

0) Use a supervised learner.
1) Create a category set yourself. 
2) Label manually about 500 questions
3) Use 75% of those to train a classifier.
4) Check performance.
5) If good then cheers else goto 2.

一个小问题:您说“大约500个问题”用于训练数据并手动标记它们,但是“我可能偏离一个数量级”,因此,如果我改用5k或50k问题,我仍然手动标记那么多?

事情是; 在没有看到您的数据或对项目中所有细节都没有一个非常清晰的认识的情况下,很难给出一个很好的估计。但是,记住这一点很重要,如果500太低,则不会浪费标签工作。您仍然需要手动标记问题以进行评估。您拥有的评估数据越多,您可以做出的评估就越好。

一个数量级的意思是50-500-5000。我认为您不需要分类50k。那是您整个语料库的1/4!如果500个问题太低,则可以引导分类器。这里的想法是,您在一个小的初始语料库(例如500)上训练分类器,然后标记其余的。现在,您可以使用分类器非常有信心重新训练更大的新分类器的一些情况。

要记住的另一件事是:许多分类器的性能在训练数据量上不是线性的,而是通常为S型曲线。这意味着再加上500个带标签的问题可能几乎和5000个一样好。我的建议是分步骤进行。

哪些细节可以为我的项目提供更多的见解?我可以分享一些示例问题来显示我的格式,但我愿意定制问答的格式以适合分类过程。感谢您的帮助。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.