Как сгруппировать тексты по наиболее актуальным словам

Вопрос или проблема

У меня есть огромное количество документов, и каждый документ имеет свой собственный портрет, где портрет имеет такую структуру (document_id, слово, вес). В основном это TFIDF.

Я хочу сгруппировать эти документы в разные кластеры, скажем, 10.
Я пытаюсь реализовать алгоритм K-Means с помощью sklearn, но у меня почти нет опыта в области науки о данных. Все уроки, которые я нашел, используют текстовые данные из Википедии или откуда-то еще, но у меня нет доступа к самим текстам. У меня есть только их портреты. Надеюсь, это имеет смысл.

Можно ли это реализовать с помощью sklearn, и если да, можете ли вы направить меня, где копать или на что смотреть?

Вы можете использовать эти слова с их весом в качестве векторного представления документа. Важный момент заключается в том, чтобы все документы были векторами по полному словарному составу, так что любая позиция $i$ в любом векторе всегда представляет одно и то же слово $w_i$. Это означает, что вектор должен содержать нули во всех позициях, соответствующих слову, которого нет в документе.

Используя эти векторы, вы действительно можете использовать k-means для кластеризации документов. Конечно, качество результатов зависит от данных: если очень мало общих слов, это может работать не очень хорошо.

Я не знаю природы слов, которые у вас есть, но вы могли бы начать с косинусного сходства. Оно основано на количестве общих слов между 2 предложениями/документами.

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

Если простое косинусное сходство не сработает, вам придется почитать о других мерах сходства или встраивании слов.

Существует инструмент с открытым исходным кодом под названием [VOSviewer][1], который может отлично отображать топическую схожесть, используя кластеризацию ключевых слов для визуализации различных [сетей сопредельности]. Его довольно легко использовать, и он мощный, так как позволяет изменять определенные гиперпараметры, включая размер кластера.

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

В зависимости от вашего варианта использования, это может быть проще, чем создавать что-то с нуля с помощью [sklearn].

[1]: Университет Лейдена. VOSviewer: Визуализация научных ландшафтов. https://www.vosviewer.com/

Ответ или решение

Кластеризация текстов по наиболее релевантным словам

Кластеризация текстов, особенно когда у вас есть их представления в виде "портретов" (document_id, слово, вес), представляет собой интересную задачу. В данном случае мы будем использовать алгоритм K-Means и библиотеку scikit-learn для выполнения кластеризации. В этой статье мы подробно рассмотрим, как осуществить эту задачу, начиная с подготовки данных и заканчивая оценкой результатов.

1. Подготовка данных

Ваши документы представлены в виде "портретов", что прекрасно подходит для создания векторного представления. Каждый "портрет" содержит слово и его взвешенное значение. Основная задача заключается в том, чтобы сформировать векторы для всех документов, используя полное словарное представление. Это можно сделать следующим образом:

  • Сбор словаря: Определите полный массив уникальных слов из всех документов.
  • Создание векторов: Для каждого документа создайте вектор, длина которого равна количеству уникальных слов. Для позиции, соответствующей слову, укажите его вес, а для всех других — 0.

Пример кода для этого процесса:

import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer

# Предполагаем, что у нас есть DataFrame с "портретами"
data = {
    'document_id': [1, 1, 2, 2, 3, 3],
    'word': ['apple', 'banana', 'apple', 'orange', 'banana', 'grape'],
    'weight': [1, 1, 2, 1, 1, 1]
}

df = pd.DataFrame(data)

# Создаем словарь
mlb = MultiLabelBinarizer()
df['words'] = df.apply(lambda x: [x['word']] * x['weight'], axis=1)
word_matrix = mlb.fit_transform(df['words'].explode())
word_matrix = pd.DataFrame(word_matrix, columns=mlb.classes_)

# Группируем по document_id и суммируем веса
document_vectors = word_matrix.groupby(df['document_id']).sum()

2. Кластеризация с использованием K-Means

После того как все документы представлены в виде векторов, вы можете приступить к кластеризации. Далее следует использовать K-Means из scikit-learn:

from sklearn.cluster import KMeans

# Устанавливаем количество кластеров
num_clusters = 10
kmeans = KMeans(n_clusters=num_clusters, random_state=42)

# Обучаем модель
kmeans.fit(document_vectors)

# Получаем метки кластеров
clusters = kmeans.labels_
document_vectors['cluster'] = clusters

3. Оценка результатов кластеризации

Качество кластеризации можно оценить с помощью различных метрик, таких как:

  • Силуэтный коэффициент: Оценивает, насколько хорошо каждый объект-кластер отделен от других.
  • Коэффициент Дэвиса-Боулдина: Измеряет компактность и разделимость кластеров.

Пример кода для вычисления силуэтного коэффициента:

from sklearn.metrics import silhouette_score

score = silhouette_score(document_vectors.drop('cluster', axis=1), clusters)
print(f"Silhouette Score: {score}")

4. Альтернативные методы

Если K-Means не подходит, вы можете рассмотреть другие методы, такие как:

  • Иерархическая кластеризация
  • DBSCAN

Также стоит упомянуть об использовании EM-алгоритма, который может быть более устойчив к выбросам.

5. Визуализация результатов

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

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCA

# Применяем PCA для уменьшения размерности
pca = PCA(n_components=2)
reduced_data = pca.fit_transform(document_vectors.drop('cluster', axis=1).values)

# Визуализируем кластеры
plt.figure(figsize=(10, 6))
sns.scatterplot(x=reduced_data[:, 0], y=reduced_data[:, 1], hue=clusters, palette='viridis')
plt.title('Visualizing Clusters')
plt.xlabel('PCA Component 1')
plt.ylabel('PCA Component 2')
plt.legend()
plt.show()

Заключение

Кластеризация текстов на основе их векторных представлений является осуществимой задачей с использованием K-Means. С правильной подготовкой данных, выбором алгоритма и оценкой результатов вы сможете получить качественные кластеры, которые помогут вам в анализе ваших документов. Исследуйте и экспериментируйте, чтобы найти наилучший подход для ваших конкретных данных и задач.

Оцените материал
Добавить комментарий

Капча загружается...