Kmeans学习笔记

文章介绍了K-means聚类的基本原理,包括设置初始簇中心,计算样本点与簇中心的距离,更新簇中心直至收敛。K-means的优点是简单快速,但对k值选择和异常值敏感。文章通过代码展示了如何用Python实现K-means,并提出了评估聚类效果的轮廓系数和兰德系数,用于确定最佳k值。
摘要由CSDN通过智能技术生成

一、基本原理

将m个样本数据分为K个簇(类别)

每个类别至少有一个样本

流程:

1、首先人为给定k个簇中心(你想分几类),簇中心可以理解为各个类别的代表(一般是随机初始化的) ------随机挑几个代表

2、逐个计算每个样本到簇中心的距离,把离簇中心距离近的归为一类。-------先随波逐流

3、计算每个簇内的均值,更新簇中心。-------换能力强的代表

4、循环迭代步骤3直到达标。-------------不断选出能力更强的代表,直到带领的团队业绩达标

动态演示:

在这里插入图片描述

问题来了业绩是否达标看什么?

损失函数:

∑ i = 0 n min ⁡ μ j ∈ C ( ∣ ∣ x i − μ j ∣ ∣ 2 ) \sum\limits_{i=0}^{n}\underset{\mu_j \in C}\min(||x_i - \mu_j||^2) i=0nμjCmin(∣∣xiμj2)

  • 其中 μ j = 1 ∣ C j ∣ ∑ x ∈ C j x \mu_j = \frac{1}{|C_j|}\sum\limits_{x \in C_j}x μj=Cj1xCjx是簇的均值向量,或者说是质心。

  • 其中 ∣ ∣ x i − μ j ∣ ∣ 2 ||x_i - \mu_j||^2 ∣∣xiμj2代表每个样本点到均值点的距离(其实也是范数)。

意思就是:团队足够团结—>平均水平就提高—>业绩提高

优缺点:

优点:简单、快速、适用于常规的数据集

缺点:k值难确定、对异常值敏感、对初始值敏感(初始的代表,不同的初始代表将演变成最终不同的团队)、对某些分布聚类效果不好

在这里插入图片描述

上面这种簇分布情况就不适合用kmeans,kmeans会把它聚类成:(基于距离)

在这里插入图片描述

二、代码实现并展示效果演示

参考:
手敲实现kmeans

三、Kmeans的评估指标

Kmeans一开始要人为的给定一个k值,但对于样本是什么样的分布我们并不清楚,此时要怎么确定一个合适的k值?

指定不同的k值,看根据评估指标的优劣来选择合适的k值。

1、轮廓系数

针对某个样本的轮廓系数s为:
s = b − a m a x ( a , b ) s= \frac{b - a}{max(a, b)} s=max(a,b)ba

a:某个样本与其所在簇内其他样本的平均距离------->是否团结

b:某个样本与其他簇样本的平均距离--------->与其它对于越不同,越特别

当a = 0,时,S = 1。说明,S越接近1聚类的效果越好!

聚类总的轮廓系数SC为: S C = 1 N ∑ i = 1 N s i SC = \frac{1}{N}\sum\limits_{i = 1}^Ns_i SC=N1i=1Nsi所有样本的 s i s_i si的均值称为聚类结果的轮廓系数,是该聚类是否合理、有效的度量。

代码:
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.metrics import silhouette_score #轮廓系数
import warnings
warnings.filterwarnings("ignore")

# 创建数据
# 假数据,数据X划分成3类
plt.figure(figsize=(8,4))
X,y = datasets.make_blobs(centers=3)
plt.scatter(X[:,0],X[:,1],c = y)

在这里插入图片描述

# 指定不同的k,寻找最佳聚类类别数目
plt.rcParams['font.family'] = 'STKaiti'
plt.rcParams["font.size"]= 20
plt.figure(figsize=(4,3))
scores = []
for k in range(2,7):
    keams = KMeans(n_clusters=k)
    keams.fit(X)
    y_pre = keams.predict(X)
    score = silhouette_score(X,y_pre)
    scores.append(score)
plt.plot(range(2,7),scores,color='green')
index = np.argmax(scores)
plt.scatter(range(2,7)[index],scores[index],color='red',s=50)
print("轮廓系数最大的k值:",range(2,7)[index])

plt.xticks(np.arange(2, 7, step=1))
plt.xlabel("K值")
plt.ylabel("轮廓系数",c='red')
轮廓系数最大的k值: 3

在这里插入图片描述

2、兰德系数

RI = a + b C 2 n s a m p l e s \text{RI} = \frac{a + b}{C_2^{n_{samples}}} RI=C2nsamplesa+b

用C表示实际的类别划分,K表示聚类结果。

定义a 为在C中被划分为同一类,在K中被划分为同一簇的实例对数量

定义b为在C中被划分为不同类别,在K中被划分为不同簇的实例对数量

兰德系数范围是[0,1]

调整兰德系数为:

ARI = RI − E [ RI ] max ⁡ ( RI ) − E [ RI ] \text{ARI} = \frac{\text{RI} - E[\text{RI}]}{\max(\text{RI}) - E[\text{RI}]} ARI=max(RI)E[RI]RIE[RI]

范围为[-1,1]

代码

#用调整兰德系数选k值
from sklearn.metrics import adjusted_rand_score# 调整兰德系数
score = []
plt.figure(figsize=(4,3))
for i in range(2,7):
    kmeans = KMeans(n_clusters=i)
    kmeans.fit(X)
    y_ = kmeans.predict(X)# 预测类别 == 标签
    score.append(adjusted_rand_score(y,y_))
plt.plot(range(2,7),score)
plt.xticks(np.arange(2, 7, step=1))
plt.xlabel('K值')
plt.ylabel('调整兰德系数',c = 'red')

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学AI不秃头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值