纯手打,代码整理中,持续更新中^-^
序号延用总结十一
19.K-Means
聚类分析算法是一类强大的无监督学习工具,其核心思想是"物以类聚",通过度量数据点之间的相似性,自动地将数据划分成不同的组(簇),从而帮助我们发现数据中内在的、未知的有价值结构。 scikit-learn(sklearn)中提供了多种常用的聚类算法,如K-Means(K均值),DBSCAN(基于密度的 噪声应用空间聚类),Agglomerative Clustering(凝聚层次聚类)
K-Means(K均值)聚类算法是一种常见的无监督学习算法,广泛用于数据挖掘和模式识别领域。其主要目标是将数据集分为多个簇(cluster),使得同一簇中的数据点相似度较高,而不同簇之间的数据点 相似度较低。
19.1 K-Means 聚类的基本原理

-
初始:随机选择K个数据点作为初始质心(centroid),其中K为预先设定的簇的数量。
-
分配步骤:对于每个数据点,计算它与K个质心的距离,并将其分配到离它最近的质心所在的簇中。
-
更新步骤:一旦所有数据点都被分配到簇中,重新计算每个簇的质心,即计算簇内所有点的均值,并将该均值作为新的质心。
-
重复:重复执行分配和更新步骤,直到簇的质心不再发生显著变化或达到最大迭代次数为止。
19.2 K-Means 聚类的优缺点
优点:
-
计算效率高:对于大数据集,K-Means是非常高效的,时间复杂度是 O (n ⋅k ⋅t ),其中 n 是样本数,k 是簇的个数,t 是迭代次数。
-
简单易懂:K-Means算法的原理简单,易于实现。
缺点:
-
K值的选择:需要事先指定簇的个数 K ,但 K 的选择并不容易,且过多或过少的簇数会导致聚类效果差。
-
容易受初始值影响:K-Means对初始质心非常敏感,容易陷入局部最优解。
-
不能处理非球形簇:K-Means假设每个簇是球形的,因此对于形状不规则的簇,K-Means可能效果不好。
-
对噪声敏感:对异常值(outliers)比较敏感,可能影响聚类效果。
19.3 代码示例
python
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 生成一些样本数据
X = np.random.rand(100, 2) # 100个2维数据点
# 创建KMeans模型,设定簇的个数K=3
kmeans = KMeans(n_clusters=3, random_state=0)
# 训练KMeans模型
kmeans.fit(X)
# 获取每个数据点的簇标签
labels = kmeans.labels_
# 获取簇的质心
centroids = kmeans.cluster_centers_
print(centroids)
# 可视化结果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis') # 根据簇标签着色
plt.scatter(centroids[:, 0], centroids[:, 1], marker='*', color='red') # 绘制质心
plt.show()
运行结果

19.4 API介绍
在使用 Python 的 Scikit-Learn 库时,我们使用KMeans 类来实现K-Means聚类算法:
python
from sklearn.cluster import KMeans
model = KMeans(
n_clusters=8,
init='k-means++',
n_init=10,
max_iter=300,
random_state=42
)
核心参数
-
n_clusters(最重要的参数):形成的簇数
-
init(初始化方法)初始化质心的策略。这个一般推荐使用 k-means++
-
n_init,算法用不同的质心种子运行的次数。
-
max_iter:单次运行中的最大迭代次数。
-
random_state::随机数种子,一般是42。
19.5 如何选择合适的K值
选择K值是K-Means聚类中的一个关键问题,常用的两种方法是:1,肘部法则(Elbow Method)2, 轮廓系数(Silhouette Score)

19.5.1 肘部法则(Elbow Method)
通过计算不同K值下的聚类误差平方和(SSE,Sum of Squared Errors),绘制出K值与SSE的关系图。 当K值增加时,SSE会逐渐减小,但当K达到某个值时,SSE的下降速率会显著变缓,这个拐点就是理想的K值("肘部")。
python
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
sse = []
for k in range(1, 11):
kmeans = KMeans(n_clusters=k, random_state=0)
kmeans.fit(X)
sse.append(kmeans.inertia_)
plt.plot(range(1, 11), sse)
plt.xlabel('K值')
plt.ylabel('SSE值')
plt.title('肘部法则选K值')
plt.show()
运行结果:

kmeans.inertia_ 是 KMeans 聚类算法中的一个属性,它表示聚类结果的 惯性(inertia)。简单来 说,惯性是所有样本点与其所属簇的质心之间的平方距离的总和。惯性值越小,说明聚类结果越紧凑。
19.5.2 轮廓系数(Silhouette Score)
通过计算轮廓系数来评估不同K值的聚类效果,轮廓系数介于-1和1之间,值越大表示聚类效果越好。
python
from sklearn.metrics import silhouette_score
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
silhouette_scores = []
for k in range(2, 11): # 至少需要2个簇
kmeans = KMeans(n_clusters=k, random_state=0)
kmeans.fit(X)
score = silhouette_score(X, kmeans.labels_)
silhouette_scores.append(score)
plt.plot(range(2, 11), silhouette_scores)
plt.xlabel('K值')
plt.ylabel('轮廓系数')
plt.title('轮廓系数选K值')
plt.show()
输出结果
