自動キーワード抽出:余弦の類似性を特徴として使用


12

ドキュメント用語マトリックスを取得しました。次に、教師付き学習方法(SVM、Naive Bayesなど)を使用して、各ドキュメントのキーワードを抽出したいと思います。このモデルでは、すでにTf-idf、Posタグなどを使用しています...M

しかし、今私は次のことを考えています。項間のコサインの類似性を持つ行列があります。C

この類似性をモデルの機能として使用する可能性はありますか?私の考えは、言葉のためだったの文書にドキュメント内のすべての用語のコサイン類似点の平均値を使用するように、用語で。これは便利ですか?dはD Iをdd


Googleで検索しましたか?「コサイン類似性キーワード抽出」の下で多くのヒットを見つけました。それらはあなたを始めることができるように思えます
-shadowtalker

Googleでよく検索して、「コサインの類似性」と「キーワードの抽出」という単語を含む多くの論文を読みました。しかし、キーワードを抽出する機能としてコサイン類似性のようなものを使用する論文は見つかりませんでした
-Silke

回答:


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-平均

もう1つの可能性は、用語ドキュメントマトリックスの行で通常のk-meansを実行し、各重心の最も一般的な用語を見つけることです。

たとえば、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-meansはユークリッド距離に依存します。これは、スパースな高次元データには不適切です。テキストに対してよりうまく機能し、コサイン類似性を使用する他の手法があります

コサインK平均と散布/収集

K-meansでコサインを使用することができます(例[3]を参照)。各クラスター内のすべてのドキュメントの平均として重心を計算し、次にコサインを使用して最も近い重心までの距離を計算します。

最後に、通常のk-meansと同じ方法でキーワードを抽出できます。

クラスタ内のすべてのドキュメントの平均として平均重心を計算することは、常に良いとは限りません。Scatter / Gatherアルゴリズムでは別のアプローチが提案されています[4]:クラスターの重心は、このクラスター内のすべてのドキュメントの連結です。

このアプローチでは、各重心クラスターに対して最も頻繁に用語を使用する必要があります。

scikit learnにはこれらのアルゴリズムの実装はありませんが、を拡張することで簡単に実装できますKMeans

どちらの場合でも、重心は非常に密集することに注意してください。各クラスターの残りのドキュメントよりも密集しているため、重心の用語を切り捨てる、つまり「重要でない」用語を削除することができます。([8]を参照)。

スペクトルクラスタリング

別の方法は、スペクトルクラスタリングを適用することです。既に持っている類似度マトリックスを提供する必要があります、そしてそれはそれでクラスターを見つけます。

SpectralClusteringクラスに実装されています。[5]の例を参照してください。既に計算済みのマトリックスがあるためaffinity='precumputed'、初期化時に属性を使用する必要があることに注意してください。

スペクトルクラスタリングはカーネル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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.