Автоматичне вилучення ключових слів: використання схожих косинусів як функцій


12

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

Але зараз мені цікаво про некси. У мене є матриця із косинусною схожістю між термінами.С

Чи є можливість використовувати цю подібність як особливість для моєї моделі? Моя ідея полягала в тому, щоб термін в документі використав середнє значення косинусної подібності всіх термінів у документі з терміном . Це корисно?iггi


Ви здійснили пошук у Google? Я знайшов багато звернень у розділі "вилучення ключових слів косинусоподібності схожості", які, здається, можуть почати вас
shadowtalker

Я багато шукав в Google і прочитав багато робіт зі словами "косинусна схожість" і "вилучення ключових слів". Але я не знайшов папір, де вони використовують щось подібне до косинусового подібності як функції для вилучення ключових слів
Silke

Відповіді:


12

Я не знаю, як можна робити вилучення ключових слів під контрольованим навчанням, але я знаю, як це зробити при непідконтрольному навчанні.

Існує кілька методів цього, і ось вони:

Ієрархічна

Ви можете застосувати будь-який ієрархічний метод кластеризації на матриці подібності терміна безпосередньо (з будь-якою функцією подібності, а не просто косинусом)

У 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-означає покладається на евклідову відстань, що погано для розріджених високомірних даних. Є й інші методи, які краще працюють на тексти та використовують схожість косинусів

Cosine K-засоби та розсіювання / збирання

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

Зрештою, ви можете витягти ключові слова так само, як і для звичайних k-засобів.

Розрахунок середнього центроїда як середнього для всіх документів кластеру не завжди є добрим. Інший підхід запропонований в алгоритмі Scatter / Gather [4] : центроїд кластера - це конкатенація всіх документів цього кластеру.

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

Немає реалізації цих алгоритмів у scikit learn, але ви можете легко реалізувати їх самостійно, розширивши їх KMeans.

Зауважте, що в обох випадках центроїди стають досить щільними: щільніше, ніж решта документів у кожному кластері, тому ви, можливо, захочете обрізати терміни в центроїдах, тобто видалити "неважливі". (див. [8]).

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

Іншим способом було б застосування спектральної кластеризації. Вам потрібно буде надати матрицю подібності, яка вже є, і вона знайде кластери на ній.

Він реалізований у SpectralClusteringкласі, див. Приклади в [5] . Зауважте, що оскільки у вас вже є попередньо обчислена матриця, вам потрібно використовувати affinity='precumputed'атрибут при ініціалізації.

Спектральна кластеризація пов'язана з Kernel 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

Джерела


1
Це неймовірно якісна відповідь. Дякую! Чи є у вас думки щодо використання алгоритму поширення спорідненості Scikit для кластеризації слів? Значення подібності косинусу можна використовувати (я вважаю, подібності були б потрібні, а не відстані) як попередньо обчислена матриця спорідненості в алгоритмі.
нельшів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.