基于新闻组数据集的共聚类算法

在处理文本数据时,共聚类算法能够同时对文档和词汇进行分组,以便发现文档子集和词汇子集之间的关联。本文将介绍如何将这种算法应用于著名的新闻组数据集,并且排除了'comp.os.ms-windows.misc'类别,因为该类别中的许多帖子只包含数据而不包含实际的文本内容。

首先,使用TF-IDF方法将帖子向量化,形成一个词频矩阵。然后,利用Dhillon的谱共聚类算法对这个词频矩阵进行双聚类。通过这种方法,能够识别出在特定文档子集中更频繁使用的词汇子集。

对于找到的最佳双聚类,打印出最常见的文档类别和最重要的十个词汇。最佳双聚类是根据它们的归一化割裂度来确定的,而最佳词汇则是通过比较它们在双聚类内外的总和来确定的。

为了进行比较,还使用MiniBatchKMeans算法对文档进行了聚类。从双聚类派生的文档聚类比MiniBatchKMeans找到的聚类具有更好的V-measure值。

在执行向量化和共聚类之后,得到了以下结果:

Vectorizing... Coclustering... Done in 1.14s. V-measure: 0.4415 MiniBatchKMeans... Done in 2.16s. V-measure: 0.3015

以下是一些最佳的双聚类示例:

双聚类 0: 包含8个文档,6个词汇 类别: 100% talk.politics.mideast 词汇: cosmo, angmar, alfalfa, alphalpha, proline, benson

双聚类 1: 包含1948个文档,4325个词汇 类别: 23% talk.politics.guns, 18% talk.politics.misc, 17% sci.med 词汇: gun, guns, geb, banks, gordon, clinton, pitt, cdt, surrender, veal

双聚类 2: 包含1259个文档,3534个词汇 类别: 27% soc.religion.christian, 25% talk.politics.mideast, 25% alt.atheism 词汇: god, jesus, christians, kent, sin, objective, belief, christ, faith, moral

双聚类 3: 包含775个文档,1623个词汇 类别: 30% comp.windows.x, 25% comp.sys.ibm.pc.hardware, 20% comp.graphics 词汇: scsi, nada, ide, vga, esdi, isa, kth, s3, vlb, bmug

双聚类 4: 包含2180个文档,2802个词汇 类别: 18% comp.sys.mac.hardware, 16% sci.electronics, 16% comp.sys.ibm.pc.hardware 词汇: voltage, shipping, circuit, receiver, processing, scope, mpce, analog, kolstad, umass

在代码实现方面,首先导入了必要的库,包括用于处理集合的defaultdict,用于记录时间的time,以及用于数值计算的numpy。还导入了机器学习库sklearn中的MiniBatchKMeans和SpectralCoclustering,以及用于数据集加载的fetch_20newsgroups,用于文本特征提取的TfidfVectorizer,以及用于聚类评估的v_measure_score。

import operator from collections import defaultdict from time import time import numpy as np from sklearn.cluster import MiniBatchKMeans, SpectralCoclustering from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.cluster import v_measure_score

定义了一个名为number_normalizer的函数,用于将所有数字标记映射到一个占位符。对于许多应用来说,以数字开头的标记可能没有直接的用途,但这样的标记存在这一事实可能是相关的。通过应用这种降维形式,一些方法可能会表现得更好。

def number_normalizer(tokens): ""“将所有数字标记映射到一个占位符。 对于许多应用来说,以数字开头的标记可能没有直接的用途,但这样的标记存在这一事实可能是相关的。 通过应用这种降维形式,一些方法可能会表现得更好。 ""“ return ("#NUMBER" if token[0].isdigit() else token for token in tokens)

还定义了一个名为NumberNormalizingVectorizer的类,它继承自TfidfVectorizer。这个类重写了build_tokenizer方法,以便在对文档进行标记化时应用number_normalizer函数。

class NumberNormalizingVectorizer(TfidfVectorizer): def build_tokenizer(self): tokenize = super().build_tokenizer() return lambda doc: list(number_normalizer(tokenize(doc)))

在确定了要使用的类别后,使用fetch_20newsgroups函数加载新闻组数据。然后,创建了一个NumberNormalizingVectorizer实例和一个SpectralCoclustering实例,用于后续的向量化和共聚类操作。还创建了一个MiniBatchKMeans实例,用于比较聚类效果。

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, n_init=3)

在向量化和共聚类过程中,记录了所需的时间,并计算了V-measure值来评估聚类效果。还定义了bicluster_ncut函数来计算每个双聚类的归一化割裂度,并找到了最佳的五个双聚类。

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)))
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485