使用RAPIDS cuML的零代码修改加速K-Means手写数字聚类分析
cuml cuML - RAPIDS Machine Learning Library 项目地址: https://gitcode.com/gh_mirrors/cu/cuml
引言
在机器学习领域,K-Means算法是最常用的聚类算法之一,广泛应用于图像分析、市场细分、文档分类等场景。然而,当处理大规模数据集时,K-Means算法的计算效率往往成为瓶颈。本文将介绍如何利用RAPIDS cuML项目中的cuml.accel
工具,在不修改现有Scikit-Learn代码的情况下,显著加速K-Means算法的执行。
cuML.accel简介
cuml.accel
是RAPIDS cuML提供的一个创新工具,它允许用户在不改变现有Scikit-Learn代码的情况下,利用NVIDIA GPU的强大计算能力加速机器学习算法。这种"零代码修改"的特性使得数据科学家可以无缝地将现有的CPU工作流迁移到GPU上,获得显著的性能提升。
实验准备
我们将使用经典的手写数字数据集(digits dataset)进行演示,该数据集包含0-9的手写数字图像,每张图像被表示为64维的特征向量(8x8像素)。我们的目标是使用K-Means算法将这些数字图像聚类成10个类别。
数据集加载
import numpy as np
from sklearn.datasets import load_digits
data, labels = load_digits(return_X_y=True)
(n_samples, n_features), n_digits = data.shape, np.unique(labels).size
print(f"数字类别数: {n_digits}; 样本数: {n_samples}; 特征数: {n_features}")
评估基准设计
为了全面评估K-Means算法的性能,我们设计了一个评估基准,包括以下内容:
- 数据标准化处理
- 算法训练时间测量
- 多种聚类质量指标评估
我们定义了以下评估指标:
- 同质性分数(homo):衡量每个簇是否只包含单一类别的样本
- 完整性分数(compl):衡量同一类别的样本是否被分配到相同簇中
- V-measure:同质性和完整性的调和平均
- 调整兰德指数(ARI):衡量聚类结果与真实标签的相似度
- 调整互信息(AMI):考虑随机性的互信息度量
- 轮廓系数(silhouette):衡量样本与自身簇和其他簇的距离关系
from time import time
from sklearn import metrics
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def bench_k_means(kmeans, name, data, labels):
"""评估KMeans初始化方法的基准测试"""
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]
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))
启用GPU加速
启用GPU加速仅需一行代码:
%load_ext cuml.accel
这行代码会加载cuML的加速扩展,自动将后续的Scikit-Learn操作映射到GPU执行。
不同初始化方法比较
我们比较了三种K-Means初始化方法:
- k-means++:智能选择初始聚类中心,减少收敛所需迭代次数
- 随机初始化:完全随机选择初始聚类中心
- PCA-based初始化:基于PCA主成分确定初始聚类中心
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
print(82 * "_")
print("init\t\ttime\tinertia\thomo\tcompl\tv-meas\tARI\tAMI\tsilhouette")
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)
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 = 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 * "_")
加速效果分析
使用cuml.accel
后,我们可以观察到:
- 随机初始化和PCA-based初始化:由于这些方法涉及大量矩阵运算,GPU加速效果显著,通常可获得数倍至数十倍的加速比。
- k-means++初始化:加速效果相对较小,因为该算法包含较多顺序逻辑,GPU并行化效果有限。
- 结果质量:虽然数值结果可能与CPU版本略有差异,但聚类质量指标(如轮廓系数)通常相当或更好。
结果可视化
为了直观展示聚类效果,我们将数据通过PCA降维到2维空间并进行可视化:
import matplotlib.pyplot as plt
reduced_data = PCA(n_components=2).fit_transform(data)
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))
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)
centroids = kmeans.cluster_centers_
plt.scatter(
centroids[:, 0],
centroids[:, 1],
marker="x",
s=169,
linewidths=3,
color="w",
zorder=10,
)
plt.title(
"基于PCA降维的手写数字K-means聚类\n"
"聚类中心用白色十字标记"
)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
结论
通过RAPIDS cuML的cuml.accel
工具,我们实现了:
- 无缝加速:无需修改现有Scikit-Learn代码即可获得GPU加速
- 显著性能提升:特别是对于计算密集型的矩阵运算部分
- 保持结果质量:聚类质量与CPU版本相当或更好
这种方法特别适合希望快速迁移现有工作流到GPU环境的数据科学家,可以显著减少开发时间和计算资源消耗。对于更大规模的数据集,GPU加速的优势将更加明显。
cuml cuML - RAPIDS Machine Learning Library 项目地址: https://gitcode.com/gh_mirrors/cu/cuml
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考