Часть 6. Бикластеризация документов с помощью алгоритма спектральной кластеризации
Добро пожаловать на мой канал, чтобы посмотреть еще один пример машинного обучения с использованием scikit-learn. Сегодня мы поговорим о бикластеризации документов с помощью алгоритма Spectral Co-clustering. Помните, что вам нужно попробовать это самостоятельно, чтобы получить наиболее эффективное обучение. Вся информация и код были получены из scikit-learn. орг. Я очень благодарен за сильное сообщество Python и все пакеты с открытым исходным кодом! Без лишних слов, давайте приступим к кодированию! 🔥
Алгоритм спектральной совместной кластеризации документов
В этом примере вы можете увидеть демонстрацию алгоритма Spectral Co-clustering в действии. Мы будем использовать набор данных из двадцати групп новостей. Мы исключим категорию «comp.os.ms-windows.misc», поскольку она содержит много сообщений, содержащих только данные.
Векторизованные сообщения TF-IDF формируют матрицу частоты слов, которая затем подвергается бикластеризации с использованием алгоритма спектральной совместной кластеризации Dhillon. Полученные бикластеры слов документа указывают на подмножества слов, которые чаще всего используются в этих подмножествах документов.
Для некоторых из лучших бикластеров в качестве вывода печатаются наиболее распространенные категории документов и десять наиболее важных слов. В то время как лучшие бикластеры определяются их нормализованным разрезом, лучшие слова определяются путем сравнения их сумм внутри и вне бикластера.
Для сравнения документы также сгруппированы с помощью MiniBatchKMeans. Кластер документов, полученный из бикластера, имеет лучшую V-меру, чем кластеры, найденные с помощью MiniBatchKMeans.
Приведенный ниже код был взят из: scikit-learn. орг.
from collections import defaultdict import operator from time import time import numpy as np from sklearn.cluster import SpectralCoclustering from sklearn.cluster import MiniBatchKMeans from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.cluster import v_measure_score def number_normalizer(tokens): """Map all numeric tokens to a placeholder. For many applications, tokens that begin with a number are not directly useful, but the fact that such a token exists can be relevant. By applying this form of dimensionality reduction, some methods may perform better. """ return ("#NUMBER" if token[0].isdigit() else token for token in tokens) class NumberNormalizingVectorizer(TfidfVectorizer): def build_tokenizer(self): tokenize = super().build_tokenizer() return lambda doc: list(number_normalizer(tokenize(doc))) # exclude 'comp.os.ms-windows.misc' categories = [ "alt.atheism", "comp.graphics", "comp.sys.ibm.pc.hardware", "comp.sys.mac.hardware", "comp.windows.x", "misc.forsale", "rec.autos", "rec.motorcycles", "rec.sport.baseball", "rec.sport.hockey", "sci.crypt", "sci.electronics", "sci.med", "sci.space", "soc.religion.christian", "talk.politics.guns", "talk.politics.mideast", "talk.politics.misc", "talk.religion.misc", ] newsgroups = fetch_20newsgroups(categories=categories) y_true = newsgroups.target vectorizer = NumberNormalizingVectorizer(stop_words="english", min_df=5) cocluster = SpectralCoclustering( n_clusters=len(categories), svd_method="arpack", random_state=0 ) kmeans = MiniBatchKMeans(n_clusters=len(categories), batch_size=20000, random_state=0) print("Vectorizing...") X = vectorizer.fit_transform(newsgroups.data) print("Coclustering...") start_time = time() cocluster.fit(X) y_cocluster = cocluster.row_labels_ print( "Done in {:.2f}s. V-measure: {:.4f}".format( time() - start_time, v_measure_score(y_cocluster, y_true) ) ) print("MiniBatchKMeans...") start_time = time() y_kmeans = kmeans.fit_predict(X) print( "Done in {:.2f}s. V-measure: {:.4f}".format( time() - start_time, v_measure_score(y_kmeans, y_true) ) ) feature_names = vectorizer.get_feature_names_out() document_names = list(newsgroups.target_names[i] for i in newsgroups.target) def bicluster_ncut(i): rows, cols = cocluster.get_indices(i) if not (np.any(rows) and np.any(cols)): import sys return sys.float_info.max row_complement = np.nonzero(np.logical_not(cocluster.rows_[i]))[0] col_complement = np.nonzero(np.logical_not(cocluster.columns_[i]))[0] # Note: the following is identical to X[rows[:, np.newaxis], # cols].sum() but much faster in scipy <= 0.16 weight = X[rows][:, cols].sum() cut = X[row_complement][:, cols].sum() + X[rows][:, col_complement].sum() return cut / weight def most_common(d): """Items of a defaultdict(int) with the highest values. Like Counter.most_common in Python >=2.7. """ return sorted(d.items(), key=operator.itemgetter(1), reverse=True) bicluster_ncuts = list(bicluster_ncut(i) for i in range(len(newsgroups.target_names))) best_idx = np.argsort(bicluster_ncuts)[:5] print() print("Best biclusters:") print("----------------") for idx, cluster in enumerate(best_idx): n_rows, n_cols = cocluster.get_shape(cluster) cluster_docs, cluster_words = cocluster.get_indices(cluster) if not len(cluster_docs) or not len(cluster_words): continue # categories counter = defaultdict(int) for i in cluster_docs: counter[document_names[i]] += 1 cat_string = ", ".join( "{:.0f}% {}".format(float(c) / n_rows * 100, name) for name, c in most_common(counter)[:3] ) # words out_of_cluster_docs = cocluster.row_labels_ != cluster out_of_cluster_docs = np.where(out_of_cluster_docs)[0] word_col = X[:, cluster_words] word_scores = np.array( word_col[cluster_docs, :].sum(axis=0) - word_col[out_of_cluster_docs, :].sum(axis=0) ) word_scores = word_scores.ravel() important_words = list( feature_names[cluster_words[i]] for i in word_scores.argsort()[:-11:-1] ) print("bicluster {} : {} documents, {} words".format(idx, n_rows, n_cols)) print("categories : {}".format(cat_string)) print("words : {}\n".format(", ".join(important_words)))
Выход
Vectorizing... Coclustering... Done in 1.48s. V-measure: 0.4431 MiniBatchKMeans... Done in 3.47s. V-measure: 0.3177 Best biclusters: ---------------- bicluster 0 : 1961 documents, 4388 words categories : 23% talk.politics.guns, 18% talk.politics.misc, 17% sci.med words : gun, geb, guns, banks, gordon, clinton, pitt, cdt, surrender, veal bicluster 1 : 1269 documents, 3558 words categories : 27% soc.religion.christian, 25% talk.politics.mideast, 24% alt.atheism words : god, jesus, christians, sin, objective, kent, belief, christ, faith, moral bicluster 2 : 2201 documents, 2747 words categories : 18% comp.sys.mac.hardware, 17% comp.sys.ibm.pc.hardware, 16% comp.graphics words : voltage, board, dsp, packages, receiver, stereo, shipping, package, compression, image bicluster 3 : 1773 documents, 2620 words categories : 27% rec.motorcycles, 23% rec.autos, 13% misc.forsale words : bike, car, dod, engine, motorcycle, ride, honda, bikes, helmet, bmw bicluster 4 : 201 documents, 1175 words categories : 81% talk.politics.mideast, 10% alt.atheism, 7% soc.religion.christian words : turkish, armenia, armenian, armenians, turks, petch, sera, zuma, argic, gvg47
Попробуйте код в своей любимой среде IDE и просмотрите его. Найдите в Google то, чего вы не знаете, и увеличьте свои знания в области машинного обучения! Удачного кодирования/изучения!
Спасибо за чтение этой статьи! Если вы хотите поддержать меня, вы можете сделать это следующим образом:
1. Подпишитесь на меня здесь, на Medium или в Twitter, Instagram, TikTok или YouTube.
2. Поддержите статью хлопком
3. Оставьте короткий комментарий
Я очень ценю любую поддержку! Каждое ваше взаимодействие с контентом поможет мне расти и со временем предоставлять более качественный контент. 🚀
Спасибо, VEGXCODES
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Присоединяйтесь к нашему сообществу Discord.