Кластеризация документов | ИИ Лето | GPTMain News

Кластеризация документов — это задача классификации документов по разным группам на основе их текстового и семантического контекста. Это неконтролируемый метод, поскольку у нас нет меток для документов, и он применяется в информационном поиске и поисковых системах.

Давайте начнем…

Чтобы классифицировать документы на основе их содержания, я решил использовать алгоритм К-средних. Из-за того, что элементы не помечены, это явно проблема обучения без учителя, и одним из лучших решений должно быть K-Means. Конечно, мы можем использовать другой алгоритм, например смешанные модели Гаусса, или даже методы глубокого обучения, такие как автоэнкодеры. Я буду использовать python с блокнотом Jupyter, чтобы объединить код и результаты с документацией.

Я разрабатываю код в среде Anaconda и использую следующие зависимости:

Панды для передачи данных

Sklearn для машинного обучения и предварительной обработки

Matplotlib для построения графиков

Ntlk для алгоритмов естественного языка

BeautifulSoup для анализа текста из XML-файла и избавления от категорий

Анализ данных

Функция parseXML использует xml.etree.ElementTree для анализа данных. Я решил использовать для кластеризации только название и описание элементов, наиболее релевантных семасиологии. Из-за того, что описание не является raw tex, мы извлекаем текст библиотекой BeautifulSoup, как я уже упоминал. Также мы отбрасываем элементы с очень маленьким описанием, потому что они влияют на окончательную кластеризацию. Можно считать, что все они принадлежат дополнительному кластеру. Конечно, есть способы их включить, но я пока ими не пользуюсь.

import xml.etree.ElementTree as ET

import pandas as pd

import nltk

from sklearn.cluster import KMeans

from sklearn.externals import joblib

from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.metrics.pairwise import cosine_similarity

nltk.download('punkt')

from bs4 import BeautifulSoup

from nltk import SnowballStemmer

import re

def parseXML(xmlfile):

tree = ET.parse(xmlfile)

root = tree.getroot()

titles=[]

descriptions=[]

for item in root.findall('./channel/item'):

for child in item:

if(child.tag=='title' ):

titles.append(child.text)

if (child.tag == 'description' ):

soup = BeautifulSoup(str(child.text).encode('utf8','ignore'), "lxml")

strtext=soup.text.replace(u'\xa0', u' ').replace('\n',' ')

descriptions.append(strtext)

return titles,descriptions

bef_titles,bef_descriptions = parseXML('data.source.rss-feeds.xml')

print('Count of items before dropping:' ,len(bef_titles))

titles=[]

descriptions=[]

for i in range(len(bef_titles)):

if ( len(bef_descriptions[i]) > 500):

titles.append(bef_titles[i])

descriptions.append(bef_descriptions[i])

print('Count of items after:' ,len(titles))

[nltk_data] Downloading package punkt to

[nltk_data] C:\Users\sergi\AppData\Roaming\nltk_data...

[nltk_data] Package punkt is already up-to-date!

Count of items before dropping: 1662

Count of items after: 1130

Токенизация и стемминг

Следующим шагом является разбиение текста на слова, удаление всех морфологических аффиксов и удаление общих слов, таких как артикли и предлоги. Это можно сделать с помощью встроенных функций ntlk. В конце концов, мы получаем два разных словаря (один токенизированный и базовый и один только токенизированный), и мы объединяем их в кадр данных pandas.

def tokenize_and_stem(text):

tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]

filtered_tokens = []

for token in tokens:

if re.search('[a-zA-Z]', token):

filtered_tokens.append(token)

stems = [stemmer.stem(t) for t in filtered_tokens]

return stems

def tokenize_only(text):

tokens = [word.lower() for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]

filtered_tokens = []

for token in tokens:

if re.search('[a-zA-Z]', token):

filtered_tokens.append(token)

return filtered_tokens

stemmer = SnowballStemmer("english")

totalvocab_stemmed = []

totalvocab_tokenized = []

for i in descriptions:

allwords_stemmed = tokenize_and_stem(i)

totalvocab_stemmed.extend(allwords_stemmed)

allwords_tokenized = tokenize_only(i)

totalvocab_tokenized.extend(allwords_tokenized)

vocab_frame = pd.DataFrame({'words': totalvocab_tokenized}, index=totalvocab_stemmed)

print('there are ' + str(vocab_frame.shape[0]) + ' items in vocab_frame')

there are 481437 items in vocab_frame

Векторизация и стемминг

Прежде чем мы загрузим данные в алгоритм K-средних, необходимо их векторизовать. Самый популярный метод — Tdidf Vectorizer, который создает матрицу на основе частоты слов в документах, и именно его мы собираемся использовать. По сути, это показывает, насколько важно слово для документа. Стоит отметить, что в будущей работе word2vec и doc2vec могут быть гораздо более эффективными для представления отношений между элементами.

tfidf_vectorizer = TfidfVectorizer(max_df=0.8, max_features=200000,min_df=0.2, stop_words='english',

use_idf=True, tokenizer=tokenize_and_stem, ngram_range=(1,3))

tfidf_matrix = tfidf_vectorizer.fit_transform(descriptions)

print('Td idf Matrix shape: ',tfidf_matrix.shape)

terms = tfidf_vectorizer.get_feature_names()

dist = 1 - cosine_similarity(tfidf_matrix)

Td idf Matrix shape: (1130, 74)

К означает

Здесь происходит фактическая кластеризация, где K означает создание 5 кластеров на основе матрицы Td-idf. Мы можем легко предсказать, что это не будет оптимальным решением, потому что оно учитывает только частоту каждого слова в документе.

num_clusters = 5

km = KMeans(n_clusters=num_clusters)

km.fit(tfidf_matrix)

clusters = km.labels_.tolist()

Чтобы представить кластер, я создаю кадр данных pandas, индексированный кластерами. Ниже представлены первые 6 слов каждого кластера. Мы замечаем, что кластеризация далека от совершенства, поскольку некоторые слова входят более чем в одну группу. Также нет четкого разграничения смыслового содержания кластеров. Мы легко можем видеть, что термины, связанные с работой, включают более одного кластера.

items = { 'title': titles, 'description': descriptions}

frame = pd.DataFrame(items, index = [clusters] , columns = [ 'title','cluster'])

print("Top terms per cluster:")

order_centroids = km.cluster_centers_.argsort()[:, ::-1]

for i in range(num_clusters):

print("Cluster %d words:" % i, end='')

for ind in order_centroids[i, :6]:

print(' %s' % vocab_frame.ix[terms[ind].split(' ')].values.tolist()[0][0], end=',')

print()

Top terms per cluster:

Cluster 0 words: labour, employability, european, social, work, eu,

Cluster 1 words: occupational, sectors, skill, employability, services, workers,

Cluster 2 words: skill, job, labour, develop, market, cedefop,

Cluster 3 words: education, training, learning, vocational, education, cedefop,

Cluster 4 words: rates, unemployment, area, employability, increasingly, stated,

Визуализация

Чтобы визуализировать кластеризацию, мы должны сначала уменьшить их размерность. Мы достигли этого с помощью t-SNE (t-Distributed Stochastic Neighbor Embedding) из библиотеки sklearn.manifold. Другой способ — использовать PCA или Multi-Demiensional Scaling (MDS).

Графика выполняется с помощью библиотеки matplotlib.

import os

import matplotlib.pyplot as plt

import matplotlib as mpl

from sklearn.manifold import TSNE

tsne = TSNE(n_components=2, verbose=1, perplexity=40, n_iter=300)

pos = tsne.fit_transform(dist)

xs, ys = pos[:, 0], pos[:, 1]

cluster_colors = {0: '#1b9e77', 1: '#d95f02', 2: '#7570b3', 3: '#e7298a', 4: '#66a61e'}

cluster_names = {0: 'A',1: 'B', 2: 'C', 3: 'D', 4: 'E'}

[t-SNE] Computing pairwise distances...

[t-SNE] Computing 121 nearest neighbors...

[t-SNE] Computed conditional probabilities for sample 1000 / 1130

[t-SNE] Computed conditional probabilities for sample 1130 / 1130

[t-SNE] Mean sigma: 1.785805

[t-SNE] KL divergence after 100 iterations with early exaggeration: 0.947952

[t-SNE] Error after 125 iterations: 0.947952

%matplotlib inline

df = pd.DataFrame(dict(x=xs, y=ys, label=clusters, title=titles))

groups = df.groupby('label')

fig, ax = plt.subplots(figsize=(16,8) )

for name, group in groups:

ax.plot(group.x, group.y, marker='o', linestyle='', ms=12,

label=cluster_names[name], color=cluster_colors[name], mec='none')

ax.legend(numpoints=1)

plt.show()


Результат кластеризации

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

Следует отметить, что элементы с несколькими словами не представлены на графике. Я также заметил, что некоторые элементы написаны на языке, отличном от английского. В настоящее время мы не обрабатываем их, и поэтому их классификация фактически случайна. На диаграмме несколько неуместных точек.

Кроме того, предстоит еще много работы по очистке и предварительной обработке данных.

Один из способов — оптимизировать параметры векторизации tdidf, использовать для векторизации doc2vec. Или мы можем использовать другой метод, такой как Affinity Propagation, Spectra Clustering или более современные методы, такие как HDBSCAN и Variational Autoencoders, которые я хотел бы разработать.

PS: Чтобы запустить код, вы можете сделать это прямо из jupyter, если установлены необходимые зависимости, или вы можете экспортировать его в виде файла .py и запустить с помощью ide или напрямую через консоль.

Книга «Глубокое обучение в производстве» 📖

Узнайте, как создавать, обучать, развертывать, масштабировать и поддерживать модели глубокого обучения. Изучите инфраструктуру машинного обучения и MLOps на практических примерах.

Узнать больше

* Раскрытие информации: Обратите внимание, что некоторые из приведенных выше ссылок могут быть партнерскими ссылками, и мы без дополнительных затрат для вас получим комиссию, если вы решите совершить покупку после перехода по ссылке.

Последние статьи

Related articles

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь

hentai lou nicehentai.com ahegeo hentai pron v bigztube.mobi kannada school girl sex videos sxsi com pornoko.net indian porn xnxx.com سكس.جماعي pornigh.com سكس لوسي bangali sex in kompoz2.com ganapa kannada movie songs
سكس مع المعلمة matureporni.com سكس كس مفتوح desi clip.com foxporns.info girls sexy pictures хентай манга hentaitale.net hentai zombie girl little sister doujin justhentaiporn.com kasumi tendo hentai افلام جيانا مايكلز gratisfucktube.com foto sex
desi gay porn vedio momyporn.mobi nepali x video مدام شرموطه freetube18x.com ايناس الدغيدي سكس tony tony chopper hentai hentaimangaz.com naruto new hentai manga الكس والزبر pornarabic.net احلى بزاز ميلفاية arabgrid.net فلم\سكس