在nlp任务中,我们常常需要判断两个文本的相似程度,计算这两个文本的相似度。比如,在文本聚类任务中,需要将相似度高的文本聚到同一个簇;在文本预处理过程中,基于文本相似度把重复的文本过滤掉;在检索式对话系统中,通过计算用户的query与数据库中的query的相似度,来选择回复。
文本相似度计算 有2个关键组件:文本表示模型 和 相似度度量方法。文本表示模型 负责将文本表示为可计算的数值向量,也就是提供特征; 相似度度量方法负责基于数值向量计算文本之间的相似度。
特征构建方式
TF-IDF
TF-IDF(term frequency-inverse document frequency) 是一种数学统计方法,反映了在一个语料集中,某一个词对一篇文档的重要程度,也就是这个词在多大程度上反映了这篇文档的特征。
tf-idf分数常常作为信息检索中的权重因子,tf-idf是使用最广的词语加权方案之一。tf-idf分数与一个词出现在一篇文档中的次数成正比,与整个语料库中包含这个词的文档数成反比。给定一个用户查询(query),搜索引擎根据相关度对文档进行打分排序,tf-idf加权方案就是搜索引擎实现这个过程的一个重要手段。
在NLP任务的预处理过程中,我们经常会使用停用词表
的方式过滤掉(的、是、在)这些没有实际意义的功能性词语。tf-idf给最常见的词(是、在、的)给予很小的权重分数,较常见的词分配较小的权重,较少见的词分配较大的权重。某种意义上,这个过程实现了跟停用词表
类似的功能。
词频(term frequence)
假设对于一个用户查询”中国的蜜蜂养殖”,要根据与query的相关性,对一个文档集合中的文档进行打分排序。我们把这个query分词为”中国”、”的”、”蜜蜂”、”养殖”。最简单的方法是先找出包含这四个词的文档(至少包含其中一个词)。为了进一步对这些文档进行排序,我们可以计算每个词出现在文档中的次数(词频,term frequency),一个词的权重与这个词的词频成正比。
词频TF(term frequency)的计算方式有多种。常见的有两种:
- 一个词出现在文档中的次数。$$词频TF = 某个词出现在文档中的次数$$
- 考虑到文档的长度不同,为了便于不同文章之间的比较,对‘词频’进行归一化。$$词频TF = \frac{某个词出现在文档中的次数}{文档的总词数}$$ 或者 $$词频TF = \frac{某个词出现在文档中的次数}{文档中出现次数最多的词的出现次数}$$
逆文档频率(inverse document frequency)
由于常见词 ‘的’在文档中的出现频率会比较大,词频(term frequency)会错误地给 使用”的”次数更多的文档更大的权重分数,而没有给 “中国”、”蜜蜂”、”养殖”给予足够的重视。像”的”这样的常用词没有实际的意义,不是适合区分文档相关度的好的关键词,而少见词”中国”、”蜜蜂”、”养殖”可以更好地反映文档的相关程度。因此,引入逆文档频率(inverse document frequency)来给常见词分配更小的权重,给少见词分配更大的权重。
逆文档频率的计算方式如下: $$逆文档频率IDF = log(\frac{语料库中的文档数}{包含该词的文档数 + 1})$$ 一个词越常见,那么分母越大,逆文档频率越小。分母之所以要加1,是为了避免分母为0。
词频-逆文档频率(TF-IDF)
TF-IDF定义为 词频和逆文档频率这两个统计量的乘积。$$TF-IDF = 词频TF \times 逆文档频率IDF$$ 一个词的tf-idf分数反映了这个词对文档的重要性,这个词在多大程度上反映了这篇文档的特征。
回到”中国的蜜蜂养殖”这个检索问题上,对于每个文档,分别计算”中国”、”的”、”蜜蜂”、”养殖”这四个词的tf-idf分数,并求和作为这篇文档总的分数。用同样的方法对所有包含这四个词的文档打分,并排序。这样就得到了query”中国的蜜蜂养殖”的查询结果。 TF-IDF这种词语加权方法 常常与倒排索引方法联合使用,来实现文本检索。
距离的度量方式
闵可夫斯基距离
闵可夫斯基距离(Minkowski distance)是衡量数值点之间距离的常见方法。闵可夫斯基距离可以看作是曼哈顿距离和欧式距离的推广。
假设n维空间中的两个数值点:$X= {x_1, x_2, …, x_n}, Y= {y_1, y_2, …, y_n}$,那么闵可夫斯基距离的定义为: $$D_{p}(X,Y) = (\sum_{i=1}^{n}|x_i - y_i|^p)^{\frac{1}{p}}$$ 当$p = 2$时,闵可夫斯基距离转化为欧式距离(Euclidean_distance): $$\sqrt{\sum_{i=1}^{n}(x_i - y_i)^2}$$ 当$p = 1$时,闵可夫斯基距离转化为曼哈顿距离(Manhattan_distance): $$\sum_{i=1}^{n}|x_i - y_j|$$ 当$p \to \infty$时,闵可夫斯基距离转化为切比雪夫距离(Chebyshev_distance): $$lim_{p \to \infty}(\sum_{i=1}^{n}|x_i - y_i|^p)^{\frac{1}{p}} = max_{i=1}^{n}|x_i - y_i|$$
jaccard相似度
jaccard相似度系数(jaccard similarity coefficient),也称为并交比(intersection over union),可以用来衡量两个有限样本集合之间的相似度。jaccard相似度定义为 两个集合交集大小 与并集大小的比例: $$J(A,B) = \frac{|A \cap B|}{|A \cup B|} = \frac{|A \cap B|}{|A| + |B| - |A \cap B|}$$
jaccard相似度的思想很简单:如果两个集合共有的元素越多,那么这两个集合就越相似。
如果集合$A$和集合$B$完全重合,则$J(A,B) = 1$。jaccard相似度的取值范围是: $0 \le J(A,B) \le 1$。
jaccard距离(jaccard distance)用于衡量样本集之间的不相似度,定义为1减去jaccard相似度。$$d_{J}(A,B) = 1 - J(A,B) = \frac{|A \cup B| - |A \cap B|}{|A \cup B|}$$
与欧式距离、余弦相似度等距离度量方式相比,jaccard相似度的优点在于:不需要把文本表示成数值化的向量表示,就可以计算两个文本之间的相似度。
在文本聚类任务中,可以先通过jaccard相似度来计算数据集中文本之间的相似度,再用networkx来构建无向图;在无向图的基础上可以用louvain算法或DBSCAN算法来对文本进行聚类。 需要注意的是,louvain算法
的无向图边的权重应该是 文本之间的jaccard相似度,来计算模块度。而DBSCAN算法
的无向图边的权重应该是 文本之间的jaccard距离,来计算$\epsilon$-邻域内样本点的数量。
参考链接:
wikipedia-雅卡尔系数