自动关键字提取:使用余弦相似度作为特征


12

我有一个文档项矩阵,现在我想使用一种监督学习方法(SVM,Naive Bayes等)为每个文档提取关键字。在此模型中,我已经使用了Tf-idf,Pos标签,...M

但是现在我想知道下一个。我有一个矩阵,两个词之间的余弦相似。C

是否可以将这种相似性用作模型的功能?我的想法是对长期在文档d,用平均所有条款的余弦相似的文档d足月。这有用吗?iddi


您是否在Google上进行搜索?我在“余弦相似度关键字提取”下发现了许多热门歌曲,看来它们可以帮助您入门
Shadowtalker,2015年

我在Google上进行了很多搜索,并且阅读了许多论文,其中包含“余弦相似度”和“关键字提取”两个字。但我没有找到一篇论文,他们使用诸如余弦相似度之类的特征来提取关键字
Silke,2015年

Answers:


11

我不知道如何在监督学习中进行关键字提取,但是我确实知道如何在监督学习中进行关键字提取。

有几种方法可以这样做,所以这里是:

分层的

您可以直接在术语相似度矩阵上应用任何分层聚类方法(使用任何相似度函数,而不仅仅是余弦)

在scikit-learn中,您将执行以下操作:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.cluster import AgglomerativeClustering

vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(data)
C = 1 - cosine_similarity(X.T)
ward = AgglomerativeClustering(n_clusters=k, linkage='ward').fit(C)
label = ward.labels_

资料来源:[1]

但是,由于它是聚集集群,因此在计算上很昂贵,并且需要一段时间才能计算出来。

K均值

另一种可能性是在术语文档矩阵的行上执行常规k均值,然后为每个质心找到最常用的术语

例如,在scikit中学习以下方法:

from sklearn.cluster import KMeans

km = KMeans(n_clusters=k, init='k-means++', max_iter=100, n_init=1)
km.fit(X)
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
for i in range(k):
    print("Cluster %d:" % i, end='')
    for ind in order_centroids[i, :10]:
        print(' %s' % terms[ind], end='')

资料来源:[2]

但是k均值依赖于欧几里得距离,这对稀疏的高维数据不利。还有其他一些技术更适合文本使用余弦相似度

余弦K均值和散布/聚集

可以将余弦与K均值一起使用(请参见[3]):计算质心作为每个簇中所有文档的均值,然后使用余弦计算到最接近质心的距离。

最后,您可以使用与通常的k均值相同的方式提取关键字。

计算平均质心作为群集中所有文档的平均值并不总是一件好事。分散/聚集算法[4]中提出了另一种方法:群集的质心是该群集中所有文档的串联。

对于这种方法,您只需要为每个质心簇采用最常用的术语。

scikit learning中没有实现这些算法,但是您可以通过扩展轻松地自己实现它们KMeans

请注意,在两种情况下,质心都变得非常密集:比每个簇中的其余文档都稠密,因此您可能希望截断质心中的术语,即删除“无关紧要”的术语。(见[8])。

光谱聚类

另一种方法是应用频谱聚类。您需要提供一个已经具有的相似度矩阵,它将在其上找到簇。

它在SpectralClustering类中实现,请参见[5]中的示例。请注意,由于您已经有一个预先计算的矩阵,因此affinity='precumputed'在初始化时需要使用attribute。

光谱聚类与内核KMeans有关:有论文(参见[7])表明它们是同一回事。我最近遇到了一个可能有用的内核KMeans实现:https ://gist.github.com/mblondel/6230787

非负矩阵分解

最后,您可以使用线性代数的某些分解技术将术语文档矩阵聚类,例如SVD(这就是所谓的“潜在语义分析”)或非负矩阵分解。后者可以看作是聚类,并且可以同时聚类矩阵的行和列。

例如,您可以通过以下方式提取关键字:

from sklearn.decomposition import NMF
nmf = NMF(n_components=k, random_state=1).fit(X)

feature_names = vectorizer.get_feature_names()

for topic_idx, topic in enumerate(nmf.components_):
    print("Topic #%d:" % topic_idx)
    print(" ".join([feature_names[i]
                    for i in topic.argsort()[:-10-1:-1]]))
    print()

代码来源:[6]

即使这里的示例在python scikit-learn中,我认为找到一些R的示例也不是什么大问题

资料来源


这是一个令人难以置信的高质量答案。谢谢!您对使用Scikit的相似度传播算法对单词进行聚类有什么想法吗?可以使用余弦相似度值(我认为需要相似度,而不是距离)作为算法中的预计算亲和度矩阵。
neelshiv '16
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.