我有一个包含200万个播客名称的列表。此外,我还从一个子Reddit中抓取了一个庞大的文本语料库(包括帖子、评论、线程等),其中我们的列表中的播客被用户频繁提及。我要解决的任务是,计算每个名称在我们的语料库中的提及次数。换句话说,生成一个(名称:计数)对的字典。
这里的挑战是,这些播客名称通常由多个单词组成,例如:“Utah’s Noon News”;“Congress Hears Tech Policy Debates”等。然而,Reddit用户的提及往往是原始名称的粗略子字符串,例如:“Utah Noon/Utah New”或“Congress Tech Debates/Congress Hears Tech”。这使得从列表中识别名称变得相当困难。
我尝试过的方法:首先,我处理并将原始播客名称中的所有单词连接成一个单词。例如,“Congress Hears Tech Policy Debates” -> “Congresshearstechpolicydebates”
在遍历子Reddit语料库时,每当我发现一个命名实体或潜在的播客名称时,我会像这样处理其单词,
“Congress Hears Tech”(假设这是我在语料库中发现的)-> “congresshearstech”
我将这个“congresshearstech”字符串与播客列表中所有处理过的名称进行比较。我使用基于单词拼写相似性的分数进行这种比较。我使用了Python的difflib库来实现此操作。还有像Leveshtein和Hamming距离这样的相似性分数。最终,我会奖励与我们从语料库中找到的字符串相似度最高的播客名称。
我的问题:问题是,上述策略实际上是准确的。然而,对于整个语料库来说,它的速度太慢了。此外,我的名称列表也非常长。请问有人能建议一种更快的算法/数据结构来比较如此多的名称在如此庞大的语料库上吗?这里是否有基于深度学习的方法?比如我可以用200万个播客名称训练一个LSTM模型。这样,每当遇到一个可能的名称时,这个训练过的模型可以输出我们列表中任何播客的最接近拼写?
回答:
你可以使用tf-idf和余弦相似度来解决这个问题。我不熟悉在这里有用的任何机器学习方法。
这篇文章提供了更详细的过程描述,并链接到了一些有用的库。你还应该阅读这篇文章,它描述了一个与你的项目有些相似的项目,并包括了关于提高性能的信息。我在这里描述我理解的方法。
tf-idf是“术语频率逆文档频率”的缩写。基本上,你查看文本的一个子集,并找到你的子集中术语的频率相对于整个文本语料库中这些术语的频率。在你的子集和整个语料库中都很常见的术语将具有较低的值,而在你的子集中常见但在语料库中罕见的术语将具有较高的值。
如果你能计算一个“文档”(或文本子集)的tf-idf,你可以将一个文本子集转换成一个tf-idf值的向量。一旦你有了这个向量,你就可以用它来计算你的文本子集与其他子集的余弦相似度。比如,找出Reddit摘录与所有标题的相似度。(有一种方法可以管理这一点,这样你就不会不断地将每个Reddit摘录与每个标题进行比较 – 请参阅这篇文章)。
一旦你能做到这一点,那么我认为解决方案是选择一个值n,然后以n个单词为单位扫描Reddit帖子,对你的标题进行tf-idf/余弦相似度扫描,并在余弦相似度高于某个值时标记匹配(你需要试验这一点以找到给你好的结果的值)。然后,你减少n并重复,直到n为0。