归纳式聚类与分类器结合

在处理包含数百万数据点的大型数据集时,聚类可能会变得非常昂贵。许多聚类算法不具备归纳能力,这意味着它们不能直接应用于新数据样本而不重新计算聚类,这可能是不切实际的。相反,可以使用聚类来学习一个分类器的归纳模型,这样做有几个好处:它允许聚类扩展并应用于新数据;与重新拟合新样本的聚类不同,它确保了标签过程随时间的一致性;它允许使用分类器的推理能力来描述或解释聚类。

以下示例展示了一个通用的元估计器实现,它通过从聚类标签中归纳出一个分类器来扩展聚类。这种方法不仅能够处理大规模数据,还能够确保对新数据的分类是一致的,并且可以利用分类器的推理能力来解释聚类。

首先,需要导入必要的库和模块。这包括用于数据可视化的matplotlib.pyplot,以及scikit-learn库中的各种组件,如BaseEstimator、clone、AgglomerativeClustering、make_blobs、RandomForestClassifier等。

import matplotlib.pyplot as plt from sklearn.base import BaseEstimator, clone from sklearn.cluster import AgglomerativeClustering from sklearn.datasets import make_blobs from sklearn.ensemble import RandomForestClassifier from sklearn.inspection import DecisionBoundaryDisplay from sklearn.utils.metaestimators import available_if from sklearn.utils.validation import check_is_fitted

接下来,定义了一个名为InductiveClusterer的类,它继承自BaseEstimator。这个类有两个主要的属性:clusterer和classifier,分别用于聚类和分类。在fit方法中,首先克隆传入的聚类器和分类器,然后使用聚类器对数据进行拟合和预测,得到聚类标签。接着,使用这些标签来训练分类器。

class InductiveClusterer(BaseEstimator): def __init__(self, clusterer, classifier): self.clusterer = clusterer self.classifier = classifier def fit(self, X, y=None): self.clusterer_ = clone(self.clusterer) self.classifier_ = clone(self.classifier) y = self.clusterer_.fit_predict(X) self.classifier_.fit(X, y) return self @available_if(_classifier_has("predict")) def predict(self, X): check_is_fitted(self) return self.classifier_.predict(X) @available_if(_classifier_has("decision_function")) def decision_function(self, X): check_is_fitted(self) return self.classifier_.decision_function(X)

为了可视化聚类结果,定义了一个名为plot_scatter的函数,它使用matplotlib的scatter方法来绘制散点图。还生成了一些用于聚类的训练数据,并使用AgglomerativeClustering算法对这些数据进行聚类,得到聚类标签。然后,使用这些标签来训练一个随机森林分类器,并使用InductiveClusterer类来预测新样本的聚类成员资格。

def plot_scatter(X, color, alpha=0.5): return plt.scatter(X[:,0], X[:,1], c=color, alpha=alpha, edgecolor='k') # 生成一些用于聚类的训练数据 X, y = make_blobs(n_samples=5000, cluster_std=[1.0, 1.0, 0.5], centers=[(-5, -5), (0, 0), (5, 5)], random_state=42) # 使用AgglomerativeClustering算法对训练数据进行聚类,并得到聚类标签 clusterer = AgglomerativeClustering(n_clusters=3) cluster_labels = clusterer.fit_predict(X) plt.figure(figsize=(12, 4)) plt.subplot(131) plot_scatter(X, cluster_labels) plt.title("Ward Linkage") # 生成一些新的样本,并与原始数据集一起绘制 X_new, y_new = make_blobs(n_samples=10, centers=[(-7, -1), (-2, 4), (3, 6)], random_state=42) plt.subplot(132) plot_scatter(X, cluster_labels) plot_scatter(X_new, "black", 1) plt.title("Unknown instances") # 声明归纳学习模型,用于预测未知实例的聚类成员资格 classifier = RandomForestClassifier(random_state=42) inductive_learner = InductiveClusterer(clusterer, classifier).fit(X) probable_clusters = inductive_learner.predict(X_new) ax = plt.subplot(133) plot_scatter(X, cluster_labels) plot_scatter(X_new, probable_clusters) # 绘制决策区域 DecisionBoundaryDisplay.from_estimator(inductive_learner, X, response_method="predict", alpha=0.4, ax=ax) plt.title("Classify unknown instances") plt.show()

这个脚本的总运行时间为2.190秒。可以通过以下链接下载Jupyter笔记本和Python源代码。

  • 作为开发者API的__sklearn_is_fitted__
  • 硬币图像上的结构化Ward层次聚类演示
  • 数字2D嵌入上的多种Agglomerative Clustering演示
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485