【机器学习:K-Means】

1、聚类算法简介

聚类算法是一类无监督学习方法,旨在将数据划分为若干组(簇),使得同一簇内的样本相似度高,而不同簇间的样本差异大。计算样本之间相似度常用的方式是欧式距离;聚类算法的目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式。

常见聚类算法主要划分为:

  1. 基于划分的聚类:K-means算法->按照质心(一个簇的中心位置,通过均值计算)分类
  2. 基于层次的聚类:DIANA(自顶向下)AGNES(自底向上)
  3. 基于密度的聚类: DBSCAN算法
  4. 基于图的聚类: 谱聚类(Spectral Clustering)

2、K-Means

2.1、算法介绍

K-Means是一种常用的聚类算法,算法的步骤大致为:

  1. 事先确定常数K ,常数K意味着最终的聚类类别数
  2. 随机选择 K 个样本点作为初始聚类中心
  3. 计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别
  4. 根据每个类别中的样本点,重新计算出新的聚类中心点(平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第 3 步过程,直到聚类中心不再变化

K-Mean算法也可以说是一种EM(Expectation-Maximization)算法,它的问题描述为:
输入N个样本{xi}i=1∼N\{x_i\}_{i=1\sim N}{xi}i=1N,输出N个样本类别{Zi}i=1∼N\{Z_i\}_{i=1\sim N}{Zi}i=1N,其中Zi=1,2,3......K{Z_i = 1,2,3......K}Zi=123......K
① 首先,随机化μ1,μ2,......μkμ_1,μ_2,......μ_kμ1,μ2,......μk
② E-Step:
Zi=argmink∣∣xi−μk∣∣(离谁近属于谁)Z_i = arg\underset {k}{min}||x_i-μ_k|| (离谁近属于谁)Zi=argkmin∣∣xiμk∣∣(离谁近属于谁)
③ M-Step:
y={Nk=∑i=1NI(Zi=k)(N个样本中有多少个属于第k类)μk=1Ni∑i=1Nxi(μk是第k类样本的均值)(1)y= \begin{cases} N_k=\sum\limits_{i=1}^N I (Z_i=k)(N个样本中有多少个属于第k类)\\ μ_k=\frac{1}{N_i}\sum\limits_{i=1}^N x_i(μ_k是第k类样本的均值)\quad \end{cases} \tag{1}y=Nk=i=1NI(Zi=k)N个样本中有多少个属于第k类)μk=Ni1i=1Nxiμk是第k类样本的均值)(1)

④ 回到 ②,直到收敛
优化目标:E=min∑i=1K∑x∈Cidist(Ci,x)2(Ci是簇中心)E = min\sum\limits_{i=1}^K \sum\limits_{x\in{C_i}}dist(C_i,x)^2(C_i是簇中心)E=mini=1KxCidist(Ci,x)2Ci是簇中心)

2.2、评估方法、K值选择

误差平方和SSE (The sum of squares due to error) :
SSE越小聚类效果越好;模型的inertia_ 属性即为SSE值。

在这里插入图片描述

在这里插入图片描述
Ci表示簇C_i 表示簇Ci表示簇
k表示聚类中心的个数k 表示聚类中心的个数k表示聚类中心的个数
p表示某个簇内的样本p 表示某个簇内的样本p表示某个簇内的样本
m表示质心点m 表示质心点m表示质心点

“肘”方法 (Elbow method):
“肘” 方法通过 SSE 确定 n_clusters 的值,即确定K值。
在这里插入图片描述

步骤
1、对于n个点的数据集,迭代计算 k from 1 to n,每次聚类完成后计算 SSE
2、SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。
3、SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值。
4、在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。

SC轮廓系数法(Silhouette Coefficient):
轮廓系数法考虑簇内的内聚程度(Cohesion),簇外的分离程度(Separation)
在这里插入图片描述

上图是轮廓系数计算方法;最后计算所有样本的平均轮廓系数,轮廓系数的范围为:[-1, 1],SC值越大聚类效果越好。

API:

from sklearn.metrics import silhouette_score()

CH轮廓系数法(Calinski-Harabasz Index):
CH 系数考虑簇内的内聚程度、簇外的离散程度、质心的个数。
类别内部数据的距离平方和越小越好,类别之间的距离平方和越大越好。聚类的种类数越少越好。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

API:

from sklearn.metrics import calinski_harabasz_score ()

3、DBSCAN算法

DBSCAN 算法 (Density-Based Spatial Clustering of Applications with Noise)步骤:

核心对象 (Core Point)
若某个点的 r 邻域内点的数量不小于 MinPts,则该点为核心点。

ε-邻域 (ε-neighborhood)
以点为中心、半径为 ε(算法设定的距离阈值)的区域。

直接密度可达 (Directly Density-Reachable)
对于点 pq:若

  • pq 的 ε 邻域内
  • q 是核心点
    则称 pq 直接密度可达。

密度可达 (Density-Reachable)
若存在一系列点 q₀, q₁, …, qₖ,使得对于任意 i(1 ≤ i ≤ k),点 qᵢqᵢ₋₁ 直接密度可达,则称 q₀qₖ 密度可达。这是直接密度可达的传播链。

密度相连 (Density-Connected)
若存在核心点 p,使得点 q 和点 k 都是从 p 密度可达的,则称 qk 是密度相连的。

边界点 (Border Point)
属于某一个类簇的非核心点。它位于核心点的 ε 邻域内,但其自身邻域内点数不足 MinPts,因此“不能发展下线”。

噪声点 (Noise Point)
不属于任何类簇的点。从任何核心点出发,该点都是密度不可达的。

参数选择建议

  1. 确定 MinPts 的参考值

    • 对于二维数据集,通常取 MinPts = 4
    • 更一般地,可取 MinPts ≥ 维度 + 1(至少为 3)
    • 值越小,模型越敏感,易形成小簇;值越大,对噪声越鲁棒,但可能忽略小簇
  2. 确定 ε (半径) 的经验方法

    • 计算数据集中每个点到其第 k 个最近邻的距离(k 距离),k 一般取 MinPts
    • 将所有点的 k 距离按从小到大排序,绘制 k 距离曲线
    • 在曲线中找到拐点(“肘部”)对应的距离值,作为 ε 的参考值
    • 一般 ε 取小一些,并通过多次实验调整
  3. 调参流程建议

    • 先固定 MinPts(如 4),尝试不同 ε
    • 观察聚类结果,若大部分点被标记为噪声,则 ε 可能过小;若所有点聚成一类,则 ε 可能过大
    • 结合 k 距离曲线和实际业务需求综合确定

算法特点总结

特点说明
无需指定簇数自动发现任意形状的簇
抗噪声能力强可识别并排除噪声点
对参数敏感ε 和 MinPts 需仔细调优
处理密度不均对密度差异大的数据集效果可能不佳

代码示例

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
from sklearn.metrics import silhouette_score, calinski_harabasz_score

data = make_blobs(n_samples=1000, n_features=2, centers=[[1,1],[3,2],[5,3],[7,6]],
                  cluster_std=[1, 0.5, 1.5, 1.2], random_state=6)
x = data[0]
y = data[1]

k_list = [i for i in range(2,11)]
sse_list = []
sc_list = []
ch_list = []
for k in k_list:
    model = KMeans(n_clusters=k)
    y_pred = model.fit_predict(x)
    sse_list.append(model.inertia_)
    sc_list.append(silhouette_score(x, y_pred))
    ch_list.append(calinski_harabasz_score(x, y_pred))

fig = plt.figure(figsize=(10,10), dpi=60)
fig.add_subplot(311)
plt.plot(k_list, sse_list)
plt.title("SSE")

fig.add_subplot(312)
plt.plot(k_list, sc_list)
plt.title("sc")

fig.add_subplot(313)
plt.plot(k_list, ch_list)
plt.title("ch")

plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值