查看原文
其他

物以类聚——浅述k-means聚类算法

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:陈   鼎,中南财经政法大学统计与数学学院

本文编辑:寇晓璇

技术总编:王子一

Python云端课程来啦!

      寒雪梅中尽,春风柳上归。新的一年,正值开学之际,为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!原价2400元的Python编程培训课程,现在仅需100元即可通过腾讯课堂参与学习。详细培训大纲及报名方式请查看推文Python云端课程福利大放送!0基础也能学~或点击文末阅读原文直接报名呦~另外,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦!
k-means聚类是一种迭代求解的聚类分析法,是非常经典的非监督学习算法。它将样本集合划分为k个子集,构成k个不同的类,并将所有样本分到k个类内,使得每个样本到其所属的类的中心距离达到最小。该方法是聚类算法中最常用的一种方法,具有简单、求解速度快等优点。

01


非监督学习与监督学习


在介绍k-means算法的基本原理时,需要先理解非监督学习与监督学习的本质区别。监督学习是从标注数据中学习预测模型的机器学习问题,其最大特点是在进行计算前数据本身已经具有了标签。非监督学习则是从无标注数据中学习预测模型的机器学习问题,在进行计算前数据本身并不含有标签信息,只有其本身的特征信息。k-means则是无监督学习的一种算法,在进行聚类之前我们并不知道每个样本数据属于哪个类,只能通过先验信息人为给定一个类别个数k,并通过算法来判断每个样本数据之间的相似性,相似的便归为一类,不相似的便区分开来,在聚类完成后,再通过具体结果来分析每个类有何潜在特点。

02


模型


给定样本数据X={},代表第i个样本数据的特征向量,具有m维。k-means的目标则是将上述n个样本划分到k(k<n)个类中。每个类互斥且所有类的集合构成样本数据集X。

03


策略


k-means聚类方法的策略是使得通过损失函数最小化选取一个最佳的划分准则C。

首先,定义样本之间的距离为欧式距离的平方:
其次,定义损失函数为每个样本与样本所属的类的中心点的距离的总和:
其中,表示第l个类的中心点。k均值聚类就是求解一个划分准则,使得上述损失函数达到最小。从直观上看,越靠的近的样本之间的欧式距离越小,相似的样本聚成一类,可以使得损失函数最小,从而达到聚类的目的。但是,n个不同的样本分到k个不同的类,所有可能的分法个数将是指数级的,因此利用上述损失函数来求解最优解是NP困难问题,在现实生活中一般采用迭代的方式来求解。

04


算法


k-means聚类的求解使用迭代的方法,其具体步骤如下:
首先,初始化。随机选择k个样本点作为初始的聚类中心。
其次,计算余下每个样本到聚类中心点的距离,并将其归为与中心点最近的类中,构成新的聚类结果。
进而,计算新的类中心。对于当前新的聚类结果,计算每个类中的样本均值,并将其作为新的聚类中心。
重复上述步骤,直至迭代收敛或符合停止条件。

05


代码实现

在sklearn库中,k-means聚类方法的API为sklearn.cluster.KMeans,其主要参数及意义如下表所示:
参数参数类型及取值范围解释说明
n_clusters
int,默认取值为8
形成的簇数以及生成的质心数
init
{'k-means++','random', ndarry,callable}
初始化方法。默认是'k-means++'。means++:选择的初始均值向量之间都距离比较远,效果较好;random:随机选择K个样本最为初始均值向量
tol
float
算法收敛的阈值。默认为1e-4
max_iter
int
最大迭代次数。默认为300

在实例中,本文将以经典的鸢尾花数据集为例,简要实现对一组数据的聚类过程。鸢尾花数据集包含3个类别共150条样本数据,每个类别各有50个样本个数,每个样本具有4个特征:花萼长度,花萼宽度,花瓣长度,花瓣宽度。首先,调用相关的库,并利用sklearn.datasets导入数据集:

1from sklearn.cluster import KMeans
2from sklearn.datasets import load_iris
3from matplotlib import pyplot as plt
4import pandas as pd
5import numpy as np
6from mpl_toolkits.mplot3d import Axes3D
7from sklearn.metrics import silhouette_score
8
9iris = load_iris() # 实例化
10data = iris.data # 我们只需要数据集的特征,不需要数据集的标注

实例化k-means方法,设定k=3,并进行计算:

1km = KMeans(n_clusters=3)
2km.fit(data)
3predict = km.predict(data)

提取鸢尾花数据集的前三个特征,绘制三维散点图,查看聚类效果:

1color_list  = ['orange','green','blue']
2color = [color_list[i] for i in predict]
3
4x = data[:, 0]
5y = data[:, 1]
6z = data[:, 2]
7
8# 绘制散点图
9fig = plt.figure()
10ax = Axes3D(fig)
11ax.scatter(x, y, z,color=color)
12
13# 添加坐标轴
14ax.set_zlabel('petal length (cm)')
15ax.set_ylabel('sepal width (cm)')
16ax.set_xlabel('sepal length (cm)')
17plt.show()

聚类效果显示如下。直观来看,k-means算法的聚类效果较好。

图1.聚类效果展示

最后,计算该聚类方法的轮廓系数,查看聚类效果好坏。其中,轮廓系数公式如下:

其中,每个点i为已经聚类的样本,为i到其它族群的所有样本的平均距离,为i到自身族群的平均距离。最终计算出所有样本点的轮廓系数的平均值作为聚类效果好坏的指标。sci的值介于-1到1之间,若sci小于0,说明聚类效果不佳,若sci越大,则代表聚类效果越好。

调用方法,评估该算法的聚类效果:

1score = silhouette_score(X=data,labels=predict) # 评判聚类效果
2print(score)
得出最终结果为0.55。事实上,大多数聚类算法的轮廓系数很难超过0.7。在不知道事先要将样本分为几类时,轮廓系数也是确定类别个数的良好指标。

06


总结

k-means是一种迭代式的聚类算法,直观易懂且十分实用。但其缺点是容易收敛到局部最优解,无法达到全局最优。


对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!


往期推文推荐

我在哪里?调用高德API获取地址经纬度信息

超级简单的条件函数,轻松生成虚拟变量

Python云端课程福利大放送!0基础也能学~

【爬虫实战】“我们,继续新故事”——爬取LOL英雄皮肤

“人像动漫化”—Python实现抖音特效

跨框架合并数据|frlink的用法,你get到了吗

《唐探3》做错了什么?|来自150万字影评的证据

爬虫俱乐部年度总结|《请回答2020》

春节假期临近,来爬爬豆瓣看看有什么好剧
putdocx生成Word文档so easy!

模糊匹配我只用这一招!

利用tushare获取财务数据

爬虫实战|Selenium爬取微信公众号标题与链接

轻轻一点,就知有没有|rqrs命令介绍

强大的正则表达式

自动群发邮件(二)——附带附件

自动群发邮件--email和smtplib基本模块的使用

批量处理变量名和标签的小方法

计算工作日的小能手——workdays

Seminar | 企业错报与银行贷款合同

Seminar | 共同基金行业的性别歧视
Seminar | 来自女儿的塑造:高管、女性社会化与企业社会责任

小贴士:Markdown的基本语法

听说相貌也能量化 | 调用百度人脸检测API实现颜值打分

列出指定属性的变量|findname命令比ds命令

新一代的标签转码小能手

关于我们 


微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存