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

机器算法验证 自然语言 数据挖掘
2022-03-09 18:54:11

例如,我试图将有关编程的字符串与有关编程的其他字符串、有关物理的字符串与有关物理的其他字符串等进行分组,以涵盖广泛的主题。尽管问题的理论语言方面很明显,但我希望使用编程/软件实际做到这一点。

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

特定应用:我有大约 20 万个琐事问题,我想将它们分类为常见的分组(汽车、计算机、政治、加拿大、食品、巴拉克奥巴马等)。

我研究过的内容:维基百科有一个自然语言处理工具包列表(假设我正在尝试做的实际上称为 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 个),因为我自己还没有通读所有问题。我部分期望在分类过程中以某种方式确定有限数量。无论如何,我总是可以手动创建多个类别。

2个回答

这是 NLP 中一个相当标准的问题,您正在寻找的神奇的 Google 词是“主题建模”。尽管您的字符串很短,但您可能会使用Latent Dirichlet Allocation或类似方法取得一些成功。这里有 Edwin Chen 的一篇不错的博客文章,阐述了算法背后的总体思路。Yi Wang的这篇笔记中介绍了实施的细节。

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

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

问题 1:将问题字符串分类到适当的类别中。

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

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

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

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

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

这真的意味着您必须手动标记 500 个问题吗?是和不是。可以使用中间结果和一些技巧来“引导”分类器。虽然它仍然是手工工作,但当您考虑它时,500 个问题不会花费那么长时间来标记。在这里聪明会很快产生比勤奋更糟糕的结果。

当你有足够数量的训练数据时,取其中的 75% 并使用你最喜欢的工具(例如这里提到的那些或其他工具)创建一个分类器。现在,让分类器尝试标记保留的 25% 的数据并测量得到的准确度。如果结果很好,那就来点香槟吧。如果没有,那么制作更多的训练数据或尝试另一个分类器。

TL;博士

总而言之,这就是我的做法。

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.