K-Means

前提知识引要:

聚类

之前我们接触的算法,都是监督学习,即训练数据是包含我们要预测的结果(训练数据中是含有样本的标签)。我们对含有标签的训练集建立模型,从而能够对未知标签的样本进行预测。与监督学习对应的,聚类属于无监督学习,即训练数据中是不含有标签的。聚类的目的是根据样本数据内部的特征,将数据划分为若干个类别,每个类别就是一个簇。结果为,使得同一个簇内的数据,相似度较大,而不同簇内的数据,相似度较小。聚类也称为“无监督的分类”。其样本的相似性是根据距离来度量的。

算法步骤:

K-Mean算法,即 均值算法,是最常见的一种聚类算法。顾名思义,该算法会将数据集分为 个簇,
每个簇使用簇内所有样本的均值来表示,我们将该均值称为“质心”。具体步骤如下:
1. 从样本中选择 个点作为初始质心。
2. 计算每个样本到各个质心的距离,将样本划分到距离最近的质心所对应的簇中。
3. 计算每个簇内所有样本的均值,并使用该均值更新簇的质心。
4. 重复步骤2与3,直到达到以下条件之一结束:
质心的位置变化小于指定的阈值。
达到最大迭代次数。

算法优点与缺点:

KMeans优点如下:
1. 理解与实现简单。
2. 可以很好的扩展到大量样本中。
3. 广泛应用于不同领域。
同时,KMeans算法也具有一定的缺点,如下:
1. 需要事先指定 值,如果 值选择不当,聚类效果可能不佳。
2. 聚类结果受初始质心的影响,可能会收敛到局部最小值。
3. 适用于凸形的数据分布,对于条形或不规则形状的数据,效果较差

算法实现:

模型数据:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = 'SimHei'
plt.rcParams['font.size'] =  12
plt.rcParams['axes.unicode_minus'] = False
np.random.seed(1)
X = np.random.randint(70,100,size=(50,2))
plt.scatter(X[:,0],X[:,1])
plt.xlabel('语文')
plt.ylabel('数学')

 模型训练与预测:

训练:

from sklearn.cluster import KMeans
Kmeans = KMeans(n_clusters=4)
Kmeans.fit(X)
print('质心:',Kmeans.cluster_centers_) 
print('标签:',Kmeans.labels_)
print('SSE:',Kmeans.inertia_)
print('迭代次数:',Kmeans.n_iter_)
print('分值:',Kmeans.score(X))

 预测

a = np.array([[76,99],[94,80]])
y_hat = Kmeans.predict(a)
print(y_hat)

数据可视化

def plot_cluster(model,train,test=None):
    color = np.array(['r','g','b','orange'])
    cc = model.cluster_centers_
    label = model.labels_
    plt.scatter(cc[:,0],cc[:,1],marker='+',s=150,c = color)
    plt.scatter(train[:,0],train[:,1],c=color[label])
    if test!=None:
        y_hat = model.predict(test)
        plot.scatter(test[:,0],test[:,1],marker='*',s=150,c=color[y_hat])
    plt.xlabel('语文')
    plt.ylabel('数学')
    plt.title(f"SSE:{model.inertia_:.2f} 迭代次数:{model.n_iter_}")
kmeans  = KMeans(n_clusters=4,init='k-means++')
kmeans.fit(X)
plot_cluster(kmeans,X)


 K-Means++

算法步骤

K-Means算法对初始质心是敏感的,不同的初始质心,可能会导致不同的聚类效果(SSE)与收敛速度。虽然随机初始化多组质心,可以缓解这一问题,但是,这通常限于聚类数量(簇)较少的情况,如果聚类数量较多,随机初始化多组质心的方式可能就不会有效了。
鉴于此,我们完全可以在选择初始质心上,进行优化,这就是K-Means++算法。

K-Means++与K-Means的区别在于选择初始质心的方式不同,对于K-Means,其使用完全随机的方式来
选择初始质心,对于K-Means++,其选择初始质心的步骤如下:
1. 从训练数据中随机选择一个样本,作为初始质心。
2. 对于任意一个非质心样本 ,计算 与现有最近质心的距离 。
3. 根据概率 来选择下一个质心 , 为非质心样本的数量。
4. 重复步骤2与3,直到选择 个质心为止。
当选择好初始质心后,剩余的计算方式,K-Means++与K-Means是相同的。

算法实现

在sckit-learn中已经实现了K-Means++算法,只需将init参数设置为k-means++(默认设置)

kmeans = KMeans(init='k-means++',n_clusters=n_clusters)

 Mini Batch K-Means

算法步骤:

K-Means算法每次迭代都会使用所有数据参与运算,当数据集较大时,该算法可能会花费较多的计算时
间。Mini Batch K-Means算法(小批量K-Means算法)是K-Means算法的一种变种,与K-Means算法
具有相同的优化目标(目标函数)。不同的是,Mini Batch K-Means算法每次迭代使用小批量训练样
本,逐批次累计的方式进行计算,这样可以大大减少计算时间。在聚类效果上,通常只会略差于K-
Means算法。
Mini Batch K-Means算法步骤如下:
1. 从数据集中随机选择部分数据,使用K-Means算法在这部分随机数据上聚类,获取质心。
2. 从数据集中随机选择部分数据,形成一个批次,将该批次数据分配给最近的质心。
3. 根据现有的数据集(当前批次数据 + 所有以前的数据)更新质心。
4. 重复步骤2与3,直到质心变化小于指定的阈值或者到达最大迭代次数为止。

算法实现:

 优化算法:

通过选择最优K值进行优化

通过肘部法则选择最优K值

####肘部法则###
sse = []
scope = range(1,10)
for k in scope:
    kmeans =  KMeans(n_clusters=k)
    kmeans.fit(x)
    sse.append(kmeans.inertia_)
plt.xticks(scope)
plt.plot(scope,sse,marker='o')

 

 

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值