如何判断两个句子是否谈论相似的话题?

How to determine if two sentences talk about similar topics?

我想问你一个问题。有什么 algorithm/tool 可以让我在单词之间做一些关联吗? 例如:我有下面这组句子:

(1)
    "My phone is on the table"
    "I cannot find the charger". # no reference on phone
(2) 
    "My phone is on the table"
    "I cannot find the phone's charger". 

我想做的是找到一个联系,可能是一个语义联系,它可以让我说前两个句子在谈论一个话题(phone)作为两个术语(phone和充电器)在里面很常见(一般来说)。第二句也一样。 在第一句话中,我应该有一些可以将 phone 连接到充电器的东西。 我正在考虑使用 Word2vec,但我不确定我是否可以用它来做这件事。 你对我可以用来确定主题相似性的算法有什么建议吗(即以不同方式表达但具有相同主题的句子)?

在 Python 中,我很确定你有一个可以使用的序列匹配器

from difflib import SequenceMatcher

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

如果您想要自己的算法,我建议您使用 Levenstains Distance(它计算将一个字符串(句子)转换为另一个字符串(句子)所需的操作次数。可能会有用。)。我自己为两个字符串编写了这样的代码

    edits = [[x for x in range(len(str1) + 1)] for y in range(len(str2)+ 1)]
    for i in range(len(str2) + 1):
        edits[i][0] = i
    for i in range(1, len(str2) + 1):
        for j in range(1,  len(str1) + 1):
            if str2[i-1] == str1[j-1]:
                edits[i][j] = edits[i-1][j-1]
            else:
                edits[i][j] = 1 + min(edits[i-1][j-1], edits[i-1][j],
                                     edits[i][j-1])
    return edits[-1][-1]

[编辑] 对你来说,你想比较句子是否是关于相似主题的。我会建议以下任何算法(都很简单)

  1. Jaccary 相似度
  2. K 均值和层次聚类树状图
  3. 余弦相似度

这种类型的任务称为句子相似性,或更一般的语义文本相似性。对于此类任务,您可能会使用几种不同的方法。在 paperswithcode 上,您可以找到基准和最新技术水平。

首先可以看一下分享词的比例。 Jaccard 指数可能是您可以为此使用的最简单的指标。如果将两个句子都建模为单词集,则 jaccard 索引是交集的大小除以这两个集的并集的大小。

另一种方法是通过对单词进行计数并使用余弦相似度来衡量它们的相关程度,将这些句子转换为向量。

但并不是每个词都同样重要。要在计算中使用它,您可以使用加权方案,例如词频 - 逆文档频率 (TF-IDF) 或 BM25,它们本质上为更重要的词分配更大的权重。他们通过查看单词在语料库中所有文档中出现的频率来衡量单词的重要性。

您可以仅使用文中提到的实体来改进这些方法。在您的示例中,我、phone、table 和充电器。如果您使用 python.

,则可以使用 spaCy 或节来查找实体

如果您使用词嵌入,例如 word2vec、glove 或 fasttext,您可以取词向量的平均值并将其用作整个句子的向量。然后你可以再次使用余弦相似度。

或者在使用词嵌入的更复杂的方面,您可以使用词移动距离来测量两个词向量集合之间的距离。

还有句子相似度的神经模型。使用 transformer 模型目前是解决此类问题的最先进方法,正如我们在 STSBenchmark 上看到的那样,目前首先采用基于 BERT 的 transformer 模型。这种类型的模型通常需要大量的计算能力才能工作,但您不必从头开始训练每个模型,您只需下载一个模型即可立即使用。

这可能还有很多方法。 Here 是最近对语义相似性方法的调查。