|NO.Z.00020|——————————|BigDataEnd|——|Arithmetic&Machine.v20|——|Machine:无监督学习算法.v05|

一、案例:基于轮廓系数来选择n_clusters
### --- 案例:基于轮廓系数来选择n_clusters

~~~     我们通常会绘制轮廓系数分布图和聚类后的数据分布图来选择我们的最佳 n_clusters。
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
for i in range(2,10,2): # 6个质心的聚合情况,分别画在6张图
fig, (ax1, ax2) = plt.subplots(1, 2) # 每张图有两幅子图
fig.set_size_inches(18, 7) # 设置大图尺寸
# 给第一幅子图大小做限定
ax1.set_xlim([-0.1, 1])
ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])
# 生成模型、簇标签、轮廓系数均值,样本轮廓系数
clusterer = KMeans(n_clusters=i, random_state=10).fit(X) # 生产KMeans模型
cluster_labels = clusterer.labels_ # 记录聚合结果的所有簇标签
silhouette_avg = silhouette_score(X, cluster_labels) # 全体样本的轮廓系数
sample_silhouette_values = silhouette_samples(X, cluster_labels) # 记录每个样本的轮廓系数
print("簇数 =", i,
"\n 轮廓系数均值:", silhouette_avg)
y_lower = 10 # 为后面画图设定一个y轴最低范围
for j in range(i):
ith_cluster_silhouette_values =
sample_silhouette_values[cluster_labels== j] # 筛选留下簇j类样本的轮廓系数
ith_cluster_silhouette_values.sort() # 对上面的数组结果排序
size_cluster_j = ith_cluster_silhouette_values.shape[0] #
size_cluster_i记录第i簇样本个数
# 画图
y_upper = y_lower + size_cluster_j # 第j簇在y轴的范围上限
color = cm.nipy_spectral(float(j)/i) # 第j 簇设定颜色
ax1.fill_betweenx(np.arange(y_lower, y_upper) # 图形直角在y轴上
,ith_cluster_silhouette_values # 簇j全部样本的轮廓系数,高度映射在x轴
,facecolor=color
,alpha=0.5)
ax1.text(-0.05 # 添加簇j的编号
, y_lower + 0.5 * size_cluster_j
, str(j));
y_lower = y_upper + 10 # 下一簇的图显示的y轴坐标起点往上挪10个单位
ax1.set_title("不同簇的轮廓图")
ax1.set_xlabel("轮廓系数值")
ax1.set_ylabel("簇类标签")
ax1.axvline(x=silhouette_avg, color="red", linestyle="--") # 全样本的轮廓系数
ax1.set_yticks([])
ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
# 接下来画出子图2的散点图
colors = cm.nipy_spectral(cluster_labels.astype(float) / i)
ax2.scatter(X[:, 0], X[:, 1] ,marker='o' ,s=8 ,c=colors )
centers = clusterer.cluster_centers_ # 返回不同簇的质心坐标
ax2.scatter(centers[:, 0], centers[:, 1], marker='x', c="red", s=200)
ax2.set_title("簇群数据可视化")
ax2.set_xlabel("第一特征的特征空间")
ax2.set_ylabel("第二特征的特征空间")
plt.suptitle(("样本数据的KMeans轮廓分析--簇数为:%d"% i),
fontsize=14, fontweight='bold')
plt.show();
### --- 重要参数 init & n_init & random_state:初始质心选择

~~~     在 K-Means 中有一个重要的环节,就是放置初始质心。
~~~     如果有足够的时间,K-means 一定会收敛,但 Inertia 可能收敛到局部最小值。
~~~     是否能够收敛到真正的最小值很大程度上取决于质心的初始化。
~~~     init 就是用来帮助我们决定初始化方式的参数。
~~~     初始质心放置的位置不同,聚类的结果很可能也会不一样,
~~~     一个好的质心选择可以让 K-Means 避免更多的计算,让算法收敛稳定且更快。
~~~     在之前讲解初始质心的放置时,我们是使用”随机“的方法在样
~~~     本点中抽取 k 个样本作为初始质心,这种方法显然不符合”稳定且更快“的需求。
~~~     为此,我们可以使用random_state参数来控制每次生成的初始质心都在相同位置,
~~~     甚至可以画学习曲线来确定最优的random_state 是哪个整数。

~~~     一个 random_state 对应一个质心随机初始化的随机数种子。
~~~     如果不指定随机数种子,则 sklearn中的K-means 并不会只选择一个随机模式扔出结果,
~~~     而会在每个随机数种子下运行多次,并使用结果最好的一个随机数种子来作为初始质心。
~~~     我们可以使用参数 n_init 来选择,每个随机数种子下运行的次数。
~~~     这个参数不常用到,默认 10 次,如果我们希望运行的结果更加精确,
~~~     那我们可以增加这个参数n_init 的值来增加每个随机数种子下运行的次数。
~~~     然而这种方法依然是基于随机性的。
~~~     为了优化选择初始质心的方法,
~~~     2007年Arthur, David, and Sergei Vassilvitskii三人发表了论文“kmeans++: The advantages of careful seeding”,
~~~     他们开发了”k-means ++“初始化方案,使得初始质心(通常)彼此远离,以此来引导出比随机初始化更可靠的结果。
~~~     在 sklearn 中,我们使用参数 init='kmeans ++'来选择使用 k-means ++作为质心初始化的方案。
~~~     通常来说,建议保留默认的"kmeans++"的方法。

~~~     init
~~~     可输入"k-means++""random"或者一个 n 维数组
~~~     初始化质心的方法,默认"k-means++"
~~~     输入"k-means++":一种为 K 均值聚类选择初始聚类中心的聪明的办法,以加速收敛
~~~     如果输入了 n 维数组,数组的形状应该是(n_clusters,n_features)并给出初始质心
cluster_01 = KMeans(n_clusters = 8,init='k-means++').fit(X)
cluster_01.n_iter_ # 输出运行的迭代次数
silhouette_score(X,cluster_01.labels_)
cluster_02 = KMeans(n_clusters = 8,init="random").fit(X)
cluster_02.n_iter_
silhouette_score(X,cluster_02.labels_)
~~~     # 8
0.32661746724551005
~~~     # 12
0.3425432424623584
~~~     # n_init
~~~     # 整数,默认 10
~~~     # 使用不同的质心随机初始化的种子来运行 k-means 算法的次数。最终结果会是基于 Inertia 来计算的
~~~     # n_init 次连续运行后的最佳输出
~~~     # random_state
cluster_01 = KMeans(n_clusters = 10,n_init=500).fit(X)
cluster_01.n_iter_ # 输出运行的迭代次数
silhouette_score(X,cluster_01.labels_)
cluster_02 = KMeans(n_clusters = 10,n_init=500,random_state=10).fit(X) # 每次运行结果将会一样
cluster_02.n_iter_
silhouette_score(X,cluster_02.labels_)
~~~     # 8
0.3280527630493156
~~~     # 7
0.328279610118647
### --- 重要参数max_iter & tol:让迭代停下来

~~~     在之前描述 K-Means 的基本流程时我们提到过,当质心不再移动,Kmeans 算法就会停下来。
~~~     但在完全收敛之前,我们也可以使用 max_iter,最大迭代次数,或者 tol,
~~~     两次迭代间 Inertia 下降的量,这两个参数来让迭代提前停下来。
~~~     有时候,当我们的 n_clusters 选择不符合数据的自然分布,或者我们为了业务需求,
~~~     必须要填入与数据的自然分布不合的 n_clusters,提前让迭代停下来反而能够提升模型的表现。
参数 说明
max_iter 整数,默认300
单次运行kmeans允许的最大迭代次数
tol 浮点数,默认1e-4
两次迭代间Inertia下降的量,
如果两次迭代之间Inertia下降的值小于tol所设定的值,迭代就会停下
~~~     # 但是如果最佳簇数偏离太严重,max_iter 再大也不会有再高的轮廓系数
cluster_01 = KMeans(n_clusters =8,init='k-means++',max_iter=10).fit(X)
cluster_01.n_iter_ # 输出运行的迭代次数
silhouette_score(X,cluster_01.labels_)

~~~     # 输出参数
10
0.3253421339367222
cluster_01 = KMeans(n_clusters =8,init='k-means++',tol=1e-4).fit(X)
cluster_01.n_iter_ # 输出运行的迭代次数
silhouette_score(X,cluster_01.labels_)

~~~     # 输出参数
2
0.3268230449212373

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

posted on   yanqi_vip  阅读(19)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示