import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
# 加载手写数字数据集
data, labels = load_digits(return_X_y=True)
# 获取数据集的形状和数据集包含的手写数字种类数
(n_samples, n_features), n_digits = data.shape, np.unique(labels).size
# 打印数据集的相关信息,即手写数字的种类数、样本数量和特征数量
print(f"# digits: {n_digits}; # samples: {n_samples}; # features {n_features}")
from time import time
from sklearn import metrics
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from time import time # 导入time模块用于计时
from sklearn import metrics # 导入metrics模块用于计算聚类评估指标
from sklearn.pipeline import make_pipeline # 导入make_pipeline函数用于创建处理流水线
from sklearn.preprocessing import StandardScaler # 导入StandardScaler用于数据标准化
# 用于评估K均值聚类初始化方法的基准测试函数。
def bench_k_means(kmeans, name, data, labels):
"""
参数
----------
kmeans : KMeans实例对象
已经设置初始化方法的KMeans实例对象。
name : str
策略的名称,将用于在表格中显示结果。
data : 形状为(n_samples, n_features)的数组
用于聚类的数据。
labels : 形状为(n_samples,)的ndarray
用于计算聚类指标的真实标签。
"""
t0 = time() # 记录开始时间
estimator = make_pipeline(StandardScaler(), kmeans).fit(data) # 创建管道,并拟合数据
fit_time = time() - t0 # 计算拟合时间
results = [name, fit_time, estimator[-1].inertia_] # 初始化结果列表,包括名称、拟合时间、聚类不确定性度量
# 定义聚类评估指标
clustering_metrics = [
metrics.homogeneity_score,
metrics.completeness_score,
metrics.v_measure_score,
metrics.adjusted_rand_score,
metrics.adjusted_mutual_info_score,
]
results += [m(labels, estimator[-1].labels_) for m in clustering_metrics] # 计算并添加聚类评估指标结果到结果列表
# Silhouette系数需要使用完整的数据集
results += [
metrics.silhouette_score(
data,
estimator[-1].labels_,
metric="euclidean",
sample_size=300,
)
]
# 显示结果
formatter_result = (
"{:9s}\t{:.3f}s\t{:.0f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}"
)
print(formatter_result.format(*results))
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
print(82 * "_")
print("init\t\ttime\tinertia\thomo\tcompl\tv-meas\tARI\tAMI\tsilhouette")
# 使用"k-means++"初始化方法创建KMeans实例对象
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="k-means++", data=data, labels=labels)
# 使用"random"初始化方法创建KMeans实例对象
kmeans = KMeans(init="random", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="random", data=data, labels=labels)
# 使用PCA进行数据降维,将数据降至n_digits维
pca = PCA(n_components=n_digits).fit(data)
kmeans = KMeans(init=pca.components_, n_clusters=n_digits, n_init=1)
bench_k_means(kmeans=kmeans, name="PCA-based", data=data, labels=labels)
print(82 * "_")
import matplotlib.pyplot as plt
# 用pca对数据降维度,降到二维
reduced_data = PCA(n_components=2).fit_transform(data)
# 使用 K-means 对数据进行聚类操作,用"k-means++"初始化聚类点
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4)
kmeans.fit(reduced_data)
# 步长大小,画网格用
h = 0.02
# 初始化网格,边界
x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1
y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# ravel()展平数组,c_()连接,当作测试集
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
# 在画板上绘制最终结果
Z = Z.reshape(xx.shape)
plt.figure(1)
plt.clf()
plt.imshow(
Z,
interpolation="nearest",
extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.Paired,
aspect="auto",
origin="lower",
)
plt.plot(reduced_data[:, 0], reduced_data[:, 1], "k.", markersize=2)
# Plot the centroids as a white X
centroids = kmeans.cluster_centers_
plt.scatter(
centroids[:, 0],
centroids[:, 1],
marker="x",
s=169,
linewidths=3,
color="w",
zorder=10,
)
plt.title(
"K-means clustering on the digits dataset (PCA-reduced data)\n"
"Centroids are marked with white cross"
)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
心得:
1.几个常用的聚类评估指标,包括:
metrics.homogeneity_score: 均一性
metrics.completeness_score: 完整性
metrics.v_measure_score: V-measure指标
metrics.adjusted_rand_score: 调整兰德指数
metrics.adjusted_mutual_info_score: 调整互信息指数
这些指标的作用是用于评估聚类结果的质量,通过比较聚类结果和真实标签之间的差异来度量聚类的准确性和一致性。这些指标的取值范围通常是从0到1,值越接近1表示聚类结果与真实标签的一致性越高。
2.从时间角度来看,经过pca降维的数据处理速度最快,这也体现的降维的作用。