🎩 欢迎来到技术探索的奇幻世界👨💻
📜 个人主页:@一伦明悦-CSDN博客
✍🏻 作者简介: C++软件开发、Python机器学习爱好者
🗣️ 互动与支持:💬评论 👍🏻点赞 📂收藏 👀关注+
如果文章有所帮助,欢迎留下您宝贵的评论,
点赞加收藏支持我,点击关注,一起进步!
引言
Scikit-Learn工具包提供了多种聚类算法,涵盖了不同的聚类方法和应用场景。下面将对聚集聚类、归纳聚类、光学聚类算法进行简要介绍,并对BIRCH和MiniBatchKMeans进行比较分析。
聚集聚类(Agglomerative Clustering)
聚集聚类是一种基于层次的聚类方法,它通过迭代地将最为相似的样本或聚类合并来构建聚类的层次结构。具体步骤包括:
- 初始阶段:每个样本被视为一个单独的聚类。
- 迭代合并:根据某种相似性度量(如欧氏距离),合并最为相似的两个聚类,直到满足停止条件。
Scikit-Learn中的实现为
AgglomerativeClustering
,支持不同的链接类型(如单链接、完全链接、平均链接)和距离计算方法。归纳聚类(DBSCAN)
归纳聚类(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,它能够发现任意形状的聚类,并能处理噪声点。主要特点包括:
- 核心对象:周围存在足够密度的点被视为核心对象。
- 直接密度可达:如果一个点可以通过核心对象的邻域达到另一个点,则认为它们在同一聚类中。
在Scikit-Learn中,
DBSCAN
是其实现,通过eps
参数定义邻域大小,min_samples
参数定义核心对象所需的最小样本数。光学聚类(Optics)
光学聚类是另一种基于密度的聚类算法,与DBSCAN相似但提供了更大的灵活性,能够捕捉不同密度级别的聚类结构。主要特点包括:
- 核心距离:类似于DBSCAN中的eps,定义了核心对象的邻域大小。
- 最小样本数:定义形成聚类所需的最小核心对象数。
光学聚类能够生成聚类的层次结构,通过
OPTICS
类实现。BIRCH和MiniBatchKMeans的比较分析
BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies) 和 MiniBatchKMeans 是两种不同的聚类算法,适用于大规模数据集的聚类任务。
BIRCH:
- 特点:基于层次的聚类算法,通过聚类特征树(CF树)和层次的聚类结构有效处理大规模数据。
- 优点:对大型数据集的处理效率高,能够在内存受限的情况下进行聚类。
- 适用场景:适合于需要处理大量数据并且对聚类速度有较高要求的场景。
MiniBatchKMeans:
- 特点:是K均值聚类的一种变体,通过随机小批量(mini-batch)数据来更新聚类中心,从而加快收敛速度。
- 优点:适合大规模数据集,尤其是在内存和计算资源有限的情况下能够快速进行聚类。
- 适用场景:处理大规模数据并且要求较快的聚类速度时特别有效。
正文
01-不同度量的聚集聚类
聚集聚类是一种基于层次的聚类方法,它从每个样本开始,逐步合并具有最小距离的一对聚类,直到达到预先指定的聚类数量或达到某个停止条件。在这段代码中,使用的是凝聚层次聚类(Agglomerative Clustering),其中的不同度量通常包括以下几种:
Ward Linkage:
Ward Linkage 是一种聚合准则,它选择合并两个聚类的标准是最小化合并后聚类的总内方差增加。这种方法在实践中通常表现良好,特别是对于球状簇的数据。Complete Linkage:
Complete Linkage 选择合并两个聚类的标准是两个聚类中最远距离的样本之间的距离。这种方法更倾向于形成大小相等且密集的聚类。Single Linkage:
Single Linkage 选择合并两个聚类的标准是两个聚类中最近距离的样本之间的距离。这种方法可能会形成长条状的聚类,对噪声和离群点敏感。Average Linkage:
Average Linkage 选择合并两个聚类的标准是两个聚类中所有样本之间的平均距离。这种方法在大多数情况下都能产生较好的聚类效果。在代码中,使用的是 Ward Linkage,它是 Agglomerative Clustering 默认的聚合准则。这种聚类方法在第一个子图中展示了数据的聚类结果,其中不同颜色代表不同的聚类簇。
这段代码展示了如何使用Python中的scikit-learn库进行凝聚层次聚类(Agglomerative Clustering)以及可视化聚类结果和距离矩阵。让我们逐步解释每个部分的功能和意图:
数据生成
# Generate waveform data
n_features = 2000
t = np.pi * np.linspace(0, 1, n_features)
def sqr(x):
return np.sign(np.cos(x))
X = list()
y = list()
for i, (phi, a) in enumerate([(.5, .15), (.5, .6), (.3, .2)]):
for _ in range(30):
phase_noise = .01 * np.random.normal()
amplitude_noise = .04 * np.random.normal()
additional_noise = 1 - 2 * np.random.rand(n_features)
additional_noise[np.abs(additional_noise) < .997] = 0
X.append(12 * ((a + amplitude_noise)
* (sqr(6 * (t + phi + phase_noise)))
+ additional_noise))
y.append(i)
X = np.array(X)
y = np.array(y)
- 这部分代码生成了包含三种波形的合成数据。每种波形重复生成30次,每次添加不同的噪声,最终得到包含三种波形数据的X和对应的标签y。
可视化 Ground Truth
plt.figure()
plt.axes([0, 0, 1, 1])
for l, c, n in zip(range(n_clusters), 'rgb',
labels):
lines = plt.plot(X[y == l].T, c=c, alpha=.5)
lines[0].set_label(n)
plt.legend(loc='best')
plt.axis('tight')
plt.axis('off')
plt.suptitle("Ground truth", size=20)
plt.savefig("../3.png", dpi=500)
- 这部分代码绘制了数据的地面真实标签(Ground Truth),显示了每个波形的数据示例。每种波形用不同颜色表示,有助于理解数据的分布和真实标签。
距离矩阵的可视化
for index, metric in enumerate(["cosine", "euclidean", "cityblock"]):
avg_dist = np.zeros((n_clusters, n_clusters))
plt.figure(figsize=(5, 4.5))
for i in range(n_clusters):
for j in range(n_clusters):
avg_dist[i, j] = pairwise_distances(X[y == i], X[y == j],
metric=metric).mean()
avg_dist /= avg_dist.max()
for i in range(n_clusters):
for j in range(n_clusters):
plt.text(i, j, '%5.3f' % avg_dist[i, j],
verticalalignment='center',
horizontalalignment='center')
plt.imshow(avg_dist, interpolation='nearest', cmap=plt.cm.gnuplot2,
vmin=0)
plt.xticks(range(n_clusters), labels, rotation=45)
plt.yticks(range(n_clusters), labels)
plt.colorbar()
plt.suptitle("Interclass %s distances" % metric, size=18)
plt.tight_layout()
plt.savefig("../4.png", dpi=500)
- 这部分代码计算并绘制了不同距离度量(余弦相似度、欧氏距离、曼哈顿距离)下数据类间的平均距离矩阵。每个距离矩阵显示了数据类别之间的相似度或差异度量,有助于选择合适的距离度量进行聚类。
凝聚层次聚类的可视化
- 这部分代码使用凝聚层次聚类算法(Agglomerative Clustering)对数据进行聚类,并根据不同的距离度量(余弦相似度、欧氏距离、曼哈顿距离)生成聚类结果的可视化。每个子图展示了使用特定距离度量的聚类结果,以及聚类簇的可视化分布。
总结
该代码演示了如何利用Python中的scikit-learn库对复杂数据集进行凝聚层次聚类,并通过多种视觉手段展示数据的真实标签、距离度量以及聚类结果。这些步骤帮助理解和分析数据的分布、相似度以及聚类效果,对数据分析和机器学习建模有重要的辅助作用。
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import pairwise_distances
np.random.seed(0)
# Generate waveform data
n_features = 2000
t = np.pi * np.linspace(0, 1, n_features)
def sqr(x):
return np.sign(np.cos(x))
X = list()
y = list()
for i, (phi, a) in enumerate([(.5, .15), (.5, .6), (.3, .2)]):
for _ in range(30):
phase_noise = .01 * np.random.normal()
amplitude_noise = .04 * np.random.normal()
additional_noise = 1 - 2 * np.random.rand(n_features)
# Make the noise sparse
additional_noise[np.abs(additional_noise) < .997] = 0
X.append(12 * ((a + amplitude_noise)
* (sqr(6 * (t + phi + phase_noise)))
+ additional_noise))
y.append(i)
X = np.array(X)
y = np.array(y)
n_clusters = 3
labels = ('Waveform 1', 'Waveform 2', 'Waveform 3')
# Plot the ground-truth labelling
plt.figure()
plt.axes([0, 0, 1, 1])
for l, c, n in zip(range(n_clusters), 'rgb',
labels):
lines = plt.plot(X[y == l].T, c=c, alpha=.5)
lines[0].set_label(n)
plt.legend(loc='best')
plt.axis('tight')
plt.axis('off')
plt.suptitle("Ground truth", size=20)
plt.savefig("../3.png", dpi=500)
# Plot the distances
for index, metric in enumerate(["cosine", "euclidean", "cityblock"]):
avg_dist = np.zeros((n_clusters, n_clusters))
plt.figure(figsize=(5, 4.5))
for i in range(n_clusters):
for j in range(n_clusters):
avg_dist[i, j] = pairwise_distances(X[y == i], X[y == j],
metric=metric).mean()
avg_dist /= avg_dist.max()
for i in range(n_clusters):
for j in range(n_clusters):
plt.text(i, j, '%5.3f' % avg_dist[i, j],
verticalalignment='center',
horizontalalignment='center')
plt.imshow(avg_dist, interpolation='nearest', cmap=plt.cm.gnuplot2,
vmin=0)
plt.xticks(range(n_clusters), labels, rotation=45)
plt.yticks(range(n_clusters), labels)
plt.colorbar()
plt.suptitle("Interclass %s distances" % metric, size=18)
plt.tight_layout()
plt.savefig("../4.png", dpi=500)
# Plot clustering results
for index, metric in enumerate(["cosine", "euclidean", "cityblock"]):
model = AgglomerativeClustering(n_clusters=n_clusters,
linkage="average", affinity=metric)
model.fit(X)
plt.figure()
plt.axes([0, 0, 1, 1])
for l, c in zip(np.arange(model.n_clusters), 'rgbk'):
plt.plot(X[model.labels_ == l].T, c=c, alpha=.5)
plt.axis('tight')
plt.axis('off')
plt.suptitle("AgglomerativeClustering(affinity=%s)" % metric, size=20)
plt.savefig("../5.png", dpi=500)
plt.show()
02-归纳聚类
归纳聚类(Hierarchical Clustering)是一种聚类方法,与光学聚类算法不同,它通过逐步合并或分裂数据点来构建聚类层次结构。以下是归纳聚类的详细解释:
工作原理
归纳聚类的核心思想是将数据点根据它们之间的相似度逐步组织成层次结构,形成一个树状图(Dendrogram)。具体步骤包括:
距离计算:计算每对数据点之间的距离或相似度。常用的距离度量包括欧氏距离、曼哈顿距离或相关系数等。
合并最近的数据点:开始时,将每个数据点视为一个独立的聚类。然后,合并距离最近的两个聚类,形成一个新的聚类。
更新距离矩阵:重新计算聚类之间的距离或相似度,并更新距离矩阵。
重复合并:重复上述步骤,直到所有数据点被合并为一个大的聚类或达到预设的聚类数目。
算法类型
归纳聚类分为两种主要类型:
凝聚式聚类(Agglomerative Clustering):从底部开始,逐步合并数据点,直到形成一个大的聚类。它的特点是从下到上构建聚类结构。
分裂式聚类(Divisive Clustering):从一个整体开始,逐步分割成小的聚类,直到每个数据点单独形成一个聚类。它的特点是从上到下逐步分解聚类结构。
优势和适用场景
归纳聚类的优势包括:
层次结构:生成清晰的层次结构,可以帮助用户理解数据中的子群体和相关性。
无需预先指定聚类数:与K均值等方法不同,归纳聚类无需事先指定聚类数量,自动形成聚类层次。
适应不同形状的聚类:能够处理非凸形状和不规则大小的聚类。
适用场景包括需要探索数据内部结构、分析数据间的相似度、或者需要深入理解数据集中群体关系和层次结构的应用场景。
实现
在实际应用中,归纳聚类可以通过多种算法实现,如基于距离的方法(如单链接、完全链接等),或基于点的方法(如平均链接)。具体的实现方式可以根据数据特性和需求选择合适的方法。
归纳聚类通过其自然的层次结构和对数据内在关系的深入挖掘,为数据分析和可视化提供了强大的工具,尤其适用于复杂数据集和需要详细分析的场景。
这段代码实现了一个基于归纳学习的聚类器模型,并使用了Python中常见的机器学习库进行实现和可视化。让我们逐步解释:
-
导入库和模块:
import numpy as np 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.utils.metaestimators import if_delegate_has_method
这里导入了用于数值计算的numpy库,用于绘图的matplotlib库,以及用于机器学习的各种模块和类。
-
定义归纳聚类器类
InductiveClusterer
:
这是一个自定义的机器学习模型,继承自BaseEstimator
,具有以下方法:__init__
: 初始化方法,接收聚类器和分类器作为参数。fit
: 训练方法,使用给定的数据X
进行聚类和分类器的训练。predict
: 预测方法,用于预测新数据的聚类标签。decision_function
: 决策函数方法,用于预测新数据的决策函数值。
-
定义绘图函数
plot_scatter
:
这个函数用于绘制散点图,其中X
是数据集,color
是颜色,alpha
是透明度。 -
生成训练数据:
使用make_blobs
生成包含三个簇的数据集X
和相应的真实标签y
。 -
训练聚类器:
使用AgglomerativeClustering
进行训练,得到训练数据的聚类标签cluster_labels
。 -
绘制子图:
使用matplotlib
绘制三个子图:- 第一个子图展示了原始数据
X
的散点图,并按照聚类标签进行着色。 - 第二个子图在第一个子图的基础上,增加了新生成的数据
X_new
的散点图(黑色)。 - 第三个子图展示了原始数据
X
的散点图,并根据归纳学习模型对新数据X_new
的聚类结果进行了着色,并绘制了决策区域。
- 第一个子图展示了原始数据
-
保存和展示图像:
将绘制的图像保存为文件5.png
,并展示出来。
这段代码的目的是演示如何使用归纳学习模型,即通过结合聚类和分类技术来预测新数据点的类别。
import numpy as np
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.utils.metaestimators import if_delegate_has_method
N_SAMPLES = 5000
RANDOM_STATE = 42
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
@if_delegate_has_method(delegate='classifier_')
def predict(self, X):
return self.classifier_.predict(X)
@if_delegate_has_method(delegate='classifier_')
def decision_function(self, X):
return self.classifier_.decision_function(X)
def plot_scatter(X, color, alpha=0.5):
return plt.scatter(X[:, 0],
X[:, 1],
c=color,
alpha=alpha,
edgecolor='k')
# Generate some training data from clustering
X, y = make_blobs(n_samples=N_SAMPLES,
cluster_std=[1.0, 1.0, 0.5],
centers=[(-5, -5), (0, 0), (5, 5)],
random_state=RANDOM_STATE)
# Train a clustering algorithm on the training data and get the cluster labels
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")
# Generate new samples and plot them along with the original dataset
X_new, y_new = make_blobs(n_samples=10,
centers=[(-7, -1), (-2, 4), (3, 6)],
random_state=RANDOM_STATE)
plt.subplot(132)
plot_scatter(X, cluster_labels)
plot_scatter(X_new, 'black', 1)
plt.title("Unknown instances")
# Declare the inductive learning model that it will be used to
# predict cluster membership for unknown instances
classifier = RandomForestClassifier(random_state=RANDOM_STATE)
inductive_learner = InductiveClusterer(clusterer, classifier).fit(X)
probable_clusters = inductive_learner.predict(X_new)
plt.subplot(133)
plot_scatter(X, cluster_labels)
plot_scatter(X_new, probable_clusters)
# Plotting decision regions
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1),
np.arange(y_min, y_max, 0.1))
Z = inductive_learner.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.title("Classify unknown instances")
plt.savefig("../5.png", dpi=500)
plt.show()
运行结果如下图所示:
03-光学聚类算法的演示
光学聚类(Optics)是一种基于密度的聚类算法,与传统的基于距离的方法(如K均值)和基于密度的方法(如DBSCAN)不同,它提供了更大的灵活性和对数据结构的深层理解。下面详细解释光学聚类算法的工作原理和其在Scikit-Learn中的应用:
工作原理
光学聚类算法主要基于两个核心概念:核心距离(Core Distance)和最小可达距离(Reachability Distance)。
核心距离(Core Distance):对于每个样本点,核心距离是指在指定的半径范围内,样本点能够达到的最小密度(即样本点周围的邻域内最小样本数)。这个距离可以理解为定义核心对象的邻域大小的阈值。
最小可达距离(Reachability Distance):从一个样本点到另一个样本点的可达距离,考虑了连接这两个点的路径中的最大核心距离。这个距离可以用来评估两个样本点之间的密度连接情况,而不仅仅是简单的距离。
算法步骤
光学聚类算法的工作流程如下:
初始化:为每个样本点设置核心距离和最小可达距离为未定义(infinity)。
处理每个样本点:对每个样本点,计算其到所有其他样本点的距离,并确定其核心距离(通过最小样本数和半径确定)。
建立排序列表:根据核心距离,将样本点按照密度从高到低排序。
迭代计算:从未处理的样本点中选择一个点,更新其直接密度可达的样本点,并更新它们的最小可达距离。这一步骤重复直到所有点都被处理过。
聚类提取:根据最小可达距离,将样本点划分为不同的聚类。
在Scikit-Learn中的应用
在Scikit-Learn中,光学聚类算法通过
OPTICS
类实现。它与其他聚类算法类似,可以方便地与其他预处理、特征提取和模型评估步骤集成在一起。主要参数包括:
min_samples
:定义核心对象所需的最小样本数。max_eps
:定义搜索的最大半径,用于确定核心距离。cluster_method
:指定提取聚类的方法,如xi
、dbscan
或xi_and_dbscan
。优势和适用场景
光学聚类算法的优势包括:
- 处理任意形状的聚类:与K均值等算法不同,光学聚类能够处理非凸形状的聚类。
- 适应密度变化:能够处理密度不均匀的数据,对参数敏感度较低。
- 层次结构:生成可以表示不同密度级别的聚类层次结构,适合于数据分析和可视化。
适用场景包括需要处理具有复杂数据结构和密度变化的数据集,以及需要探索数据中隐藏结构和模式的应用场景。
通过光学聚类算法,可以更深入地理解数据的内在结构,并能够有效地处理现实世界中复杂和大规模的数据集。
这段代码演示了如何使用OPTICS算法进行聚类,并可视化聚类结果及其相关属性。让我来逐步解释:
-
首先,生成了六个不同形状的聚类簇,每个簇包含250个样本点。这些点被合并成一个数据集X。
-
使用OPTICS算法(在此例中使用了Scikit-Learn中的OPTICS类)对数据集X进行聚类。参数设置为
min_samples=50
,xi=0.05
,min_cluster_size=0.05
。 -
使用
cluster_optics_dbscan
函数基于OPTICS算法的输出,对每个样本点进行DBSCAN聚类,分别使用了两个不同的epsilon值(0.5和2.0)。 -
通过绘制四个子图,展示了聚类的不同阈值下的效果:
- 第一个子图是“Reachability Plot”,展示了样本点的可达性。
- 第二个子图展示了OPTICS算法的自动聚类结果。
- 第三个子图展示了DBSCAN算法在epsilon值为0.5时的聚类结果。
- 第四个子图展示了DBSCAN算法在epsilon值为2.0时的聚类结果。
-
最后,通过调整布局和保存图像,生成了可视化结果。
这段代码的目的是展示OPTICS算法在不同参数设置下的聚类效果,并对比了其与DBSCAN算法在不同epsilon值下的表现。
from sklearn.cluster import OPTICS, cluster_optics_dbscan
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
import numpy as np
# Generate sample data
np.random.seed(0)
n_points_per_cluster = 250
C1 = [-5, -2] + .8 * np.random.randn(n_points_per_cluster, 2)
C2 = [4, -1] + .1 * np.random.randn(n_points_per_cluster, 2)
C3 = [1, -2] + .2 * np.random.randn(n_points_per_cluster, 2)
C4 = [-2, 3] + .3 * np.random.randn(n_points_per_cluster, 2)
C5 = [3, -2] + 1.6 * np.random.randn(n_points_per_cluster, 2)
C6 = [5, 6] + 2 * np.random.randn(n_points_per_cluster, 2)
X = np.vstack((C1, C2, C3, C4, C5, C6))
clust = OPTICS(min_samples=50, xi=.05, min_cluster_size=.05)
# Run the fit
clust.fit(X)
labels_050 = cluster_optics_dbscan(reachability=clust.reachability_,
core_distances=clust.core_distances_,
ordering=clust.ordering_, eps=0.5)
labels_200 = cluster_optics_dbscan(reachability=clust.reachability_,
core_distances=clust.core_distances_,
ordering=clust.ordering_, eps=2)
space = np.arange(len(X))
reachability = clust.reachability_[clust.ordering_]
labels = clust.labels_[clust.ordering_]
plt.figure(figsize=(10, 7))
G = gridspec.GridSpec(2, 3)
ax1 = plt.subplot(G[0, :])
ax2 = plt.subplot(G[1, 0])
ax3 = plt.subplot(G[1, 1])
ax4 = plt.subplot(G[1, 2])
# Reachability plot
colors = ['g.', 'r.', 'b.', 'y.', 'c.']
for klass, color in zip(range(0, 5), colors):
Xk = space[labels == klass]
Rk = reachability[labels == klass]
ax1.plot(Xk, Rk, color, alpha=0.3)
ax1.plot(space[labels == -1], reachability[labels == -1], 'k.', alpha=0.3)
ax1.plot(space, np.full_like(space, 2., dtype=float), 'k-', alpha=0.5)
ax1.plot(space, np.full_like(space, 0.5, dtype=float), 'k-.', alpha=0.5)
ax1.set_ylabel('Reachability (epsilon distance)')
ax1.set_title('Reachability Plot')
# OPTICS
colors = ['g.', 'r.', 'b.', 'y.', 'c.']
for klass, color in zip(range(0, 5), colors):
Xk = X[clust.labels_ == klass]
ax2.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)
ax2.plot(X[clust.labels_ == -1, 0], X[clust.labels_ == -1, 1], 'k+', alpha=0.1)
ax2.set_title('Automatic Clustering\nOPTICS')
# DBSCAN at 0.5
colors = ['g', 'greenyellow', 'olive', 'r', 'b', 'c']
for klass, color in zip(range(0, 6), colors):
Xk = X[labels_050 == klass]
ax3.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3, marker='.')
ax3.plot(X[labels_050 == -1, 0], X[labels_050 == -1, 1], 'k+', alpha=0.1)
ax3.set_title('Clustering at 0.5 epsilon cut\nDBSCAN')
# DBSCAN at 2.
colors = ['g.', 'm.', 'y.', 'c.']
for klass, color in zip(range(0, 4), colors):
Xk = X[labels_200 == klass]
ax4.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)
ax4.plot(X[labels_200 == -1, 0], X[labels_200 == -1, 1], 'k+', alpha=0.1)
ax4.set_title('Clustering at 2.0 epsilon cut\nDBSCAN')
plt.tight_layout()
plt.savefig("../5.png", dpi=500)
plt.show()
运行结果如下图所示:
04-BIRCH和MiniBatchKMeans的比较
BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)和MiniBatchKMeans是两种用于聚类的算法,它们在一些方面有所不同。
数据处理方式:
- BIRCH:BIRCH是一种基于层次结构的聚类方法,它首先将数据通过CF树(Clustering Feature Tree)进行分裂和合并,然后对生成的子簇进行聚类。
- MiniBatchKMeans:MiniBatchKMeans是一种基于随机抽样和小批量数据处理的方法,它通过在小批量数据上执行K均值算法来进行聚类。
内存消耗:
- BIRCH:BIRCH通常需要较少的内存,因为它在构建CF树时可以压缩数据。
- MiniBatchKMeans:MiniBatchKMeans在处理大型数据集时可能会占用更多内存,因为它需要将小批量数据加载到内存中进行处理。
收敛速度:
- BIRCH:由于BIRCH使用了CF树来减少数据量,因此在大型数据集上通常能够更快地收敛。
- MiniBatchKMeans:MiniBatchKMeans通过在小批量数据上进行迭代来逐步收敛,相对于传统的K均值算法,它可以更快地处理大型数据集。
对噪声和离群点的鲁棒性:
- BIRCH:由于BIRCH使用了CF树来处理数据,它对噪声和离群点有一定的鲁棒性。
- MiniBatchKMeans:MiniBatchKMeans对于噪声和离群点相对较敏感,因为它在每个小批量数据上执行迭代,可能会受到噪声数据的影响。
适用场景:
- BIRCH适合处理大规模数据集,对内存消耗较少,并且需要较快的收敛速度。
- MiniBatchKMeans适合处理中等大小的数据集,对于实时数据流或者需要增量式学习的场景也比较适用。
总体而言,选择使用BIRCH还是MiniBatchKMeans取决于数据集的大小、内存限制、对噪声和离群点的容忍度以及对算法收敛速度的要求。
这段代码演示了如何使用Python中的sklearn库进行聚类分析,比较了BIRCH和MiniBatchKMeans两种算法在生成的大型数据集上的表现。
1. 数据生成
首先,使用make_blobs
函数生成了一个包含10x10个中心点的数据集,共有100,000个样本。这些中心点按照网格状分布在平面上。
xx = np.linspace(-22, 22, 10)
yy = np.linspace(-22, 22, 10)
xx, yy = np.meshgrid(xx, yy)
n_centres = np.hstack((np.ravel(xx)[:, np.newaxis],
np.ravel(yy)[:, np.newaxis]))
X, y = make_blobs(n_samples=100000, centers=n_centres, random_state=0)
2. BIRCH算法的使用
接下来,对BIRCH算法进行了两次不同的运行:
- 第一次使用了
n_clusters=None
,即没有全局聚类步骤,此时BIRCH算法只生成子簇。 - 第二次使用了
n_clusters=100
,包含了全局聚类步骤,即在生成的子簇基础上再进行一次全局聚类。
birch_models = [Birch(threshold=1.7, n_clusters=None),
Birch(threshold=1.7, n_clusters=100)]
for ind, (birch_model, info) in enumerate(zip(birch_models, final_step)):
birch_model.fit(X)
labels = birch_model.labels_
centroids = birch_model.subcluster_centers_
n_clusters = np.unique(labels).size
# 绘制子图
3. MiniBatchKMeans算法的使用
最后,使用MiniBatchKMeans算法进行聚类分析,设置了100个簇,batch大小为100。
mbk = MiniBatchKMeans(init='k-means++', n_clusters=100, batch_size=100,
n_init=10, max_no_improvement=10, verbose=0,
random_state=0)
mbk.fit(X)
4. 可视化
使用Matplotlib库将聚类结果可视化到一个图形中,包括BIRCH算法的两种运行方式和MiniBatchKMeans算法的结果。
fig = plt.figure(figsize=(12, 4))
fig.subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.9)
# 绘制BIRCH算法的结果
for ind, (birch_model, info) in enumerate(zip(birch_models, final_step)):
ax = fig.add_subplot(1, 3, ind + 1)
for this_centroid, k, col in zip(centroids, range(n_clusters), colors_):
mask = labels == k
ax.scatter(X[mask, 0], X[mask, 1],
c='w', edgecolor=col, marker='.', alpha=0.5)
if birch_model.n_clusters is None:
ax.scatter(this_centroid[0], this_centroid[1], marker='+',
c='k', s=25)
ax.set_ylim([-25, 25])
ax.set_xlim([-25, 25])
ax.set_autoscaley_on(False)
ax.set_title('Birch %s' % info)
# 绘制MiniBatchKMeans算法的结果
ax = fig.add_subplot(1, 3, 3)
for this_centroid, k, col in zip(mbk.cluster_centers_,
range(n_clusters), colors_):
mask = mbk.labels_ == k
ax.scatter(X[mask, 0], X[mask, 1], marker='.',
c='w', edgecolor=col, alpha=0.5)
ax.scatter(this_centroid[0], this_centroid[1], marker='+',
c='k', s=25)
ax.set_xlim([-25, 25])
ax.set_ylim([-25, 25])
ax.set_title("MiniBatchKMeans")
ax.set_autoscaley_on(False)
plt.savefig("../5.png", dpi=500)
plt.show()
解释
- BIRCH算法:通过不同的
n_clusters
设置,展示了BIRCH算法在生成子簇和全局聚类的效果。 - MiniBatchKMeans算法:展示了MiniBatchKMeans算法在大规模数据集上的聚类效果,同时比较了其与BIRCH算法的差异。
整体来说,该代码演示了如何使用Python进行聚类分析,并展示了不同算法在大规模数据集上的表现及可视化。
from itertools import cycle
from time import time
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from sklearn.cluster import Birch, MiniBatchKMeans
from sklearn.datasets import make_blobs
# Generate centers for the blobs so that it forms a 10 X 10 grid.
xx = np.linspace(-22, 22, 10)
yy = np.linspace(-22, 22, 10)
xx, yy = np.meshgrid(xx, yy)
n_centres = np.hstack((np.ravel(xx)[:, np.newaxis],
np.ravel(yy)[:, np.newaxis]))
# Generate blobs to do a comparison between MiniBatchKMeans and Birch.
X, y = make_blobs(n_samples=100000, centers=n_centres, random_state=0)
# Use all colors that matplotlib provides by default.
colors_ = cycle(colors.cnames.keys())
fig = plt.figure(figsize=(12, 4))
fig.subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.9)
# Compute clustering with Birch with and without the final clustering step
# and plot.
birch_models = [Birch(threshold=1.7, n_clusters=None),
Birch(threshold=1.7, n_clusters=100)]
final_step = ['without global clustering', 'with global clustering']
for ind, (birch_model, info) in enumerate(zip(birch_models, final_step)):
t = time()
birch_model.fit(X)
time_ = time() - t
print("Birch %s as the final step took %0.2f seconds" % (
info, (time() - t)))
# Plot result
labels = birch_model.labels_
centroids = birch_model.subcluster_centers_
n_clusters = np.unique(labels).size
print("n_clusters : %d" % n_clusters)
ax = fig.add_subplot(1, 3, ind + 1)
for this_centroid, k, col in zip(centroids, range(n_clusters), colors_):
mask = labels == k
ax.scatter(X[mask, 0], X[mask, 1],
c='w', edgecolor=col, marker='.', alpha=0.5)
if birch_model.n_clusters is None:
ax.scatter(this_centroid[0], this_centroid[1], marker='+',
c='k', s=25)
ax.set_ylim([-25, 25])
ax.set_xlim([-25, 25])
ax.set_autoscaley_on(False)
ax.set_title('Birch %s' % info)
# Compute clustering with MiniBatchKMeans.
mbk = MiniBatchKMeans(init='k-means++', n_clusters=100, batch_size=100,
n_init=10, max_no_improvement=10, verbose=0,
random_state=0)
t0 = time()
mbk.fit(X)
t_mini_batch = time() - t0
print("Time taken to run MiniBatchKMeans %0.2f seconds" % t_mini_batch)
mbk_means_labels_unique = np.unique(mbk.labels_)
ax = fig.add_subplot(1, 3, 3)
for this_centroid, k, col in zip(mbk.cluster_centers_,
range(n_clusters), colors_):
mask = mbk.labels_ == k
ax.scatter(X[mask, 0], X[mask, 1], marker='.',
c='w', edgecolor=col, alpha=0.5)
ax.scatter(this_centroid[0], this_centroid[1], marker='+',
c='k', s=25)
ax.set_xlim([-25, 25])
ax.set_ylim([-25, 25])
ax.set_title("MiniBatchKMeans")
ax.set_autoscaley_on(False)
plt.savefig("../5.png", dpi=500)
plt.show()
运行结果如下图所示:
总结
通过上述介绍和比较分析,可以根据具体的数据特点和聚类需求选择合适的算法。聚集聚类、归纳聚类和光学聚类适用于不同的数据结构和聚类形式,而BIRCH和MiniBatchKMeans则是处理大规模数据时的有力工具。