我有一个文档术语矩阵,现在我想使用监督学习方法(SVM、朴素贝叶斯……)为每个文档提取关键字。在这个模型中,我已经使用了 Tf-idf、Pos 标签、...
但现在我想知道下一个。我有一个矩阵与术语之间的余弦相似性。
是否有可能将这种相似性用作我的模型的特征?我的想法是文档 d 中的术语使用文档中所有术语与术语的余弦相似度的平均值。这有用吗?
我有一个文档术语矩阵,现在我想使用监督学习方法(SVM、朴素贝叶斯……)为每个文档提取关键字。在这个模型中,我已经使用了 Tf-idf、Pos 标签、...
但现在我想知道下一个。我有一个矩阵与术语之间的余弦相似性。
是否有可能将这种相似性用作我的模型的特征?我的想法是文档 d 中的术语使用文档中所有术语与术语的余弦相似度的平均值。这有用吗?
我不知道如何通过监督学习进行关键字提取,但我确实知道如何通过无监督学习来进行。
有几种方法可以做到这一点,所以这里它们是:
您可以直接在术语相似度矩阵上应用任何层次聚类方法(使用任何相似度函数,而不仅仅是余弦)
在 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-means,然后为每个质心找到最常见的术语
例如,在 scikit learn 中,这是这样做的:
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-means依赖于欧几里得距离,这对于稀疏的高维数据是不利的。还有其他技术更适用于文本并使用余弦相似度
可以将 Cosine 与 K-means 一起使用(参见例如[3]):将质心计算为每个集群中所有文档的平均值,然后使用 cosine 计算到最近质心的距离。
最后,您可以像通常的 k-means 一样提取关键字。
将平均质心计算为集群中所有文档的平均值并不总是好的。Scatter/Gather 算法[4]中提出了另一种方法:集群的质心是该集群中所有文档的串联。
对于这种方法,您只需要为每个质心集群采用最常见的术语。
scikit learn 中没有这些算法的实现,但是您可以通过扩展KMeans
.
请注意,在这两种情况下,质心变得非常密集:比每个集群中的其余文档更密集,因此您可能希望截断质心中的术语,即删除“不重要”的术语。(见[8])。
另一种方法是应用谱聚类。您需要提供一个已有的相似度矩阵,它会在上面找到聚类。
它在SpectralClustering
类中实现,参见[5]中的示例。请注意,由于您已经有一个预先计算的矩阵,因此您需要affinity='precumputed'
在初始化时使用属性。
Spectral clustering 与 Kernel 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 找到一些示例应该不是什么大问题
来源