Автоматическое извлечение ключевых слов: использование косинусных сходств в качестве функций

12

У меня есть матрица термина документа , и теперь я хотел бы извлечь ключевые слова для каждого документа с помощью контролируемого метода обучения (SVM, Naive Bayes, ...). В этой модели я уже использую Tf-idf, тег Pos, ...M

Но теперь я задаюсь вопросом о nexts. У меня есть матрица с косинусом сходства между терминами.C

Есть ли возможность использовать это сходство в качестве функции для моей модели? Моя идея заключалась в том, чтобы для термина в документе использовать среднее значение косинусных сходств всех терминов в документе с термином . Это полезно?д д яiddi

Silke
источник
Вы делали поиск в Google? В разделе «Извлечение ключевых слов с косинусным сходством» я обнаружил множество
совпадений,
Я много искал в 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-средних

Другая возможность состоит в том, чтобы сделать обычные k-средства в строках матрицы терминов и затем найти наиболее общие термины для каждого центроида.

Например, в 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 опирается на евклидово расстояние, что плохо для редких многомерных данных. Существуют и другие методы, которые лучше работают с текстами и используют косинусное сходство.

Косинус K-средства и разброс / сбор

Можно использовать косинус с K-средними (см., Например, [3] ): вычислить центроиды как среднее значение для всех документов в каждом кластере, а затем использовать косинус, чтобы вычислить расстояние до ближайшего центроида.

В конце вы можете извлечь ключевые слова так же, как и для обычных k-средних.

Вычисление среднего центроида как среднего для всех документов в кластере не всегда хорошо. В алгоритме Scatter / Gather [4] предлагается другой подход : центроид кластера - это объединение всех документов в этом кластере.

Для этого подхода вам просто нужно взять наиболее частые термины для каждого кластера центроидов.

В Scikit Learn нет реализации этих алгоритмов, но вы можете легко реализовать их самостоятельно, расширив KMeans.

Обратите внимание, что в обоих случаях центроиды становятся довольно плотными: более плотными, чем остальные документы в каждом кластере, поэтому вы можете захотеть обрезать термины в центроидах, то есть удалить «неважные». (см. [8]).

Спектральная кластеризация

Другим способом было бы применить спектральную кластеризацию. Вам нужно будет предоставить матрицу сходства, которая у вас уже есть, и она найдет кластеры на ней.

Это реализовано в SpectralClusteringклассе, см. Примеры в [5] . Обратите внимание, что, поскольку у вас уже есть предварительно вычисленная матрица, вам нужно использовать affinity='precumputed'атрибут при инициализации.

Спектральная кластеризация связана с ядром KMeans: есть статья (см. [7]), которая показывает, что это одно и то же. Недавно я наткнулся на реализацию Kernel 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