零基础学习Kmeans聚类算法的原理与实现过程
内容导入:
聚类是无监督学习的典型例子,聚类也能为企业运营中也发挥者巨大的作用,比如我们可以利用聚类对目标用户进行群体分类,把目标群体划分成几个具有明显特征区别的细分群体,从而可以在运营活动中为这些细分群体采取精细化、个性化的运营和服务;还可以利用聚类对产品进行分类,把企业的产品体系进一步细分成具有不同价值、不同目的的多维度的产品组合,在此基础分别制定和相应的开发计划、运营计划和服务规划。这都将提升运营的效率和商业效果。
聚类方法分为基于划分的聚类、基于层次的聚类、基于密度的聚类、基于网络的聚类、基于模型的聚类以及基于模糊的聚类,今天我们就从基于划分的聚类开始讲解聚类算法,什么是基于划分的聚类呢?其原理即需要将一堆散点进行聚类,聚类目标是“类内的点足够近,类间的点足够远”,而你需要做的就是(1)确定聚类数目;(2)挑选初始中心点;(3)迭代重置中心点直到满足“类内的点足够近,类间的点足够远”,典型的基于划分的聚类就是K-means算法。
K-means算法流程
经典的K-means算法
假设要将无标签数据集:
聚成k个簇C1,C2,…, Ck,最小化损失函数:
但是完成这个过程需要遍历所有可能的簇划分,这将带来大量的计算,而K-means是利用贪心策略求得近似解的方法,经典K-means算法流程如下:
(1)随机地选择k个对象,每个对象初始地代表了一个簇的中心;
(2)对剩余的每个对象,根据其与各簇中心的距离,将它赋给最近的簇;
(3)重新计算每个簇的平均值,更新为新的簇中心;
(4)不断重复2、3,直到达到某个终止条件。
这个终止条件可以是:没有(或最小数目)对象被重新分配给不同的聚类、没有(或最小数目)聚类中心再发生变化、误差平方和局部最小。
K-means算法的改进K-means++算法
因K-means算法的聚类结果会受到初始点的的选取的影响,有人提出了K-means++改进了初始点的选取过程:
(1)随机选取一个样本点作为第一个聚类中心
(2)计算每个样本点与当前已有聚类中心的最短距离,即:
则某样本点选为下一个簇中心的概率为
python实现K-means
在scikit-learn中的KMeans类实现了这一算法,下面我们来简单介绍一下Kmeans类的主要参数及方法:
KMeans的主要参数
n_clusters:int,可选,默认值8,行成的簇数以及中心数
init:{'k-means ++','random'或ndarray},默认值'k-means ++'
'k-means ++':以'k-means ++'方法选择初始中心
'random':随机选择初始中心
ndarray (nclusters, nfeatures):给定初始中心
n_init:int ,默认值 10,用不同的初始化质心运行算法的次数
max_iter : int, 默认值 300,最大的迭代次数
tol:float,默认值 1e-4 与inertia结合来确定收敛条件。
precompute_distances : {'auto', True, False},预计算距离,计算速度更快但占用更多内存。
'auto':如果 样本数乘以聚类数大于 12million 的话则不预计算距离。
True:总是预先计算距离。
False:永远不预先计算距离。
random_state : int, RandomState instance 或者None (默认), 确定质心初始化的随机数生成。使用整数使随机性具有确定性。
copy_x:boolean,默认值True 。当我们precomputing distances时,将数据中心化会得到更准确的结果。
True,原始数据不会被改变,确保X是C连续的
False,修改原始数据,并在函数返回之前放回原始数据,但是可能会通过减去然后加上数据均值来引入较小的数值差异,在这种情况下,也不会确保数据是C连续的,这可能会导致 大幅放缓。
n_jobs:int, 指定计算所用的进程数。内部原理是同时进行n_init指定次数的计算。
'None':除非在:obj:joblib.parallel_backend上下文中,否则表示1。
'-1': means using all processors.
algorithm : "auto", "full" or "elkan", 默认="auto"
'full': 经典的EM风格算法
'elkan':使用三角不等式的'elkan'会更有效,但不支持稀疏数据
'auto':密集数据选择'elkan',为稀疏数据选择'full'。
KMeans的主要方法
fit:训练Kmeans聚类
fit_predict:计算聚类中心并预测每个样本的聚类索引。
predict:预测,依据与聚类中心的远近进行类别预测
KMeans聚类实例:
本文仅展现聚类的过程及代码,可视化的代码不再展现
为了更好的可视化聚类效果,我们使用如下图所示的二维数据进行聚类:
Kmeans最优聚类数目的确定
我们知道Kmeans方法需要我们给出聚类数目,但是一般情况下我们无法直接给出一个很合适的聚类数目,因此我们需要确定最优的聚类数目,常见的确定最优聚类数的方法有手肘法和轮廓系数法。
下面我们就来介绍一下这两个方法的思想以及python实现确认最优聚类数目的过程。
手肘法:定义聚类的误差平方和
,随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小,当k小于最优聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达最优聚类数后,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的最优聚类数。
python计算不同聚类数目下误差平方和的代码如下:
SSE = []
for i in range(1,8):
km=KMeans(n_clusters=i)
km.fit(x)
y1=km.predict(x)
SSE.append(km.inertia_)
print("k="+str(i)+"时Kmeans的误差平方和:",km.inertia_)
'''
输出结果:
k=1时Kmeans的误差平方和: 9289.822973786537
k=2时Kmeans的误差平方和: 4081.729006176964
k=3时Kmeans的误差平方和: 2049.521363130263
k=4时Kmeans的误差平方和: 1258.109982411505
k=5时Kmeans的误差平方和: 1030.7046088439135
k=6时Kmeans的误差平方和: 891.9218511797383
k=7时Kmeans的误差平方和: 777.4389345859881
以聚类数目k为横坐标,误差平方和为纵坐标,绘制折线图如下图所示:
我们可以看到聚类数目到达4后,再增加k值,SSE下降幅度减小,SSE趋于平缓,所以我们可以确定聚类数目为4.
轮廓系数:轮廓系数的计算方法如下:
计算 a(i) = average(i向量到所有它属于的簇中其它点的距离),称为簇内不相似度
计算 b(i) = min (i向量到与它相邻最近的一簇内的所有点的平均距离),称为簇间不相似度
那么i向量轮廓系数就为:
所有点的轮廓系数的平均值,即聚类结果的总的轮廓系数。
轮廓系数的取值在[-1,1]之间,越趋近于1代表内聚度和分离度都相对较优,即聚类效果越好。(当簇内只有一点时,我们定义轮廓系数s(i)为0)
python计算不同聚类数目下轮廓系数的代码如下:
from sklearn import metrics
SC=[]
for i in range(2,8):
km=KMeans(n_clusters=i)
km.fit(x)
y1=km.predict(x)
sc=metrics.silhouette_score(x,y1)
SC.append(sc)
ch=metrics.calinski_harabaz_score(x,y1)
CH.append(ch)
print("k="+str(i)+"时Kmeans的轮廓系数:", sc)
'''
输出结果:
k=2时Kmeans的轮廓系数: 0.5104346420008198
k=3时Kmeans的轮廓系数: 0.5564101841418961
k=4时Kmeans的轮廓系数: 0.5707892750326952
k=5时Kmeans的轮廓系数: 0.47190247374410116
k=6时Kmeans的轮廓系数: 0.475091206758774
k=7时Kmeans的轮廓系数: 0.4198657590150086
以聚类数目k为横坐标,轮廓系数和为纵坐标,绘制折线图如下图所示:
我们可以看到k=4时轮廓系数最高,故最优聚类数目为4。
接下来我们在看一下不同聚类数目下的聚类的CH指标:
CH=[]
for i in range(2,8):
km=KMeans(n_clusters=i)
km.fit(x)
y1=km.predict(x)
ch=metrics.calinski_harabaz_score(x,y1)
CH.append(ch)
print("k="+str(i)+"时Kmeans的CH指标:", ch)
'''
输出结果:
k=2时Kmeans的CH指标: 1656.1868658421492
k=3时Kmeans的CH指标: 2290.942499540155
k=4时Kmeans的CH指标: 2757.8670074800625
k=5时Kmeans的CH指标: 2594.294350251559
k=6时Kmeans的CH指标: 2437.2529863724803
k=7时Kmeans的CH指标: 2359.025076485279
我们再看看之前介绍一个新的聚类的度量指标——CH指标,CH指标是数据集的分离度与紧密度的比值,以各类中心点与数据集的中心点的距离平方和来度量数据集的分离度,以类内各点与其类中心的距离平方和来度量数据的紧密度。聚类效果越好,类间差距应该越大,类内差距越小,即类自身越紧密,类间越分散,CH指标值越大聚类效果越好。
不同聚类数目下CH指标值的折线图如下:
从图中我们也可以发现聚类数目4的聚类效果最好,最后我们以最优聚类数目进行聚类,并可视化聚类结果如下图所示:
从图中我们可以看出数据被聚为四类,类内较紧密,类间较分散,聚类效果很好。(此时的误差平方和为:1258.109982,轮廓系数为:0.570789,CH指标为:2757.867)
K-means的优点与缺点
优点:对于大型数据集也是简单高效、时间复杂度、空间复杂度低。
缺点:数据集大时结果容易局部最优;需要预先设定K值,对最先的K个中心点选取很敏感;对噪声和离群值非常敏感;只用于数值型数据;不能解决非凸(non-convex)数据。
零基础学习Kmeans聚类算法的原理与实现过程的更多相关文章
- K-Means聚类算法的原理及实现【转】
[转]http://www.aboutyun.com/thread-18178-1-1.html 问题导读:1.如何理解K-Means算法?2.如何寻找K值及初始质心?3.如何应用K-Means算法处 ...
- K-Means 聚类算法原理分析与代码实现
前言 在前面的文章中,涉及到的机器学习算法均为监督学习算法. 所谓监督学习,就是有训练过程的学习.再确切点,就是有 "分类标签集" 的学习. 现在开始,将进入到非监督学习领域.从经 ...
- Kmeans聚类算法原理与实现
Kmeans聚类算法 1 Kmeans聚类算法的基本原理 K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.K-means算法的基本思想是:以空间中k个点为中心进行聚类,对 ...
- 第十三篇:K-Means 聚类算法原理分析与代码实现
前言 在前面的文章中,涉及到的机器学习算法均为监督学习算法. 所谓监督学习,就是有训练过程的学习.再确切点,就是有 "分类标签集" 的学习. 现在开始,将进入到非监督学习领域.从经 ...
- 【转】K-Means聚类算法原理及实现
k-means 聚类算法原理: 1.从包含多个数据点的数据集 D 中随机取 k 个点,作为 k 个簇的各自的中心. 2.分别计算剩下的点到 k 个簇中心的相异度,将这些元素分别划归到相异度最低的簇.两 ...
- 转载: scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法
版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...
- 03-01 K-Means聚类算法
目录 K-Means聚类算法 一.K-Means聚类算法学习目标 二.K-Means聚类算法详解 2.1 K-Means聚类算法原理 2.2 K-Means聚类算法和KNN 三.传统的K-Means聚 ...
- 用scikit-learn学习K-Means聚类
在K-Means聚类算法原理中,我们对K-Means的原理做了总结,本文我们就来讨论用scikit-learn来学习K-Means聚类.重点讲述如何选择合适的k值. 1. K-Means类概述 在sc ...
- HTML5零基础学习Web前端需要知道哪些?
HTML零基础学习Web前端网页制作,首先是要掌握一些常用标签的使用和他们的各个属性,常用的标签我总结了一下有以下这些: html:页面的根元素. head:页面的头部标签,是所有头部元素的容器. b ...
随机推荐
- VUE+ElementUI创建项目
1.官网下载node,安装node.js环境 安装完成后进入cmd,输入node -v和npm -v查看node和npm是否安装成功及对应的版本 2.全局安装vue-cli:cnpm install ...
- Three.js学习1_快速入门
快速上手, 搭建第一个3D场景 最重要的一步, 先下载three.js, 引入网页中 <script src="./three.js"></script> ...
- okhttp3 示例
1.GET请求 private fun httpGetDemo() { //1.请求参数 val url = httpHost + "/api/test?arg1=xxx" //2 ...
- 【pytest】teardown里的yield和addfinalizer
在之前介绍pytest中的fixture用法的文章中https://zhuanlan.zhihu.com/p/87775743,提到了teardown的实现. 最近在翻pytest官方文档的时候,又发 ...
- 数据库系统第一章【绪论】(B站视频)
目录 数据库系统第一章[绪论](B站视频) 一.绪论 数据库的四大基本概念 数据 数据库 数据库管理系统 主要功能 数据库系统 数据管理 我的理解 数据系统的特点 数据结构化 数据系统的共享性 数据独 ...
- C006:多项式求值 horner法则
代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { float x; do{ printf("E ...
- 初探nmap
nmap 也就是Network Mapper用来扫描电脑开发的端口 主要功能: 探测主机在线情况 扫描主机开发端口和对应的大概服务命令: nmap 127.0.0.1 查看该主机开放的端口和端.端口类 ...
- java 将map转为实体类
使用反射将map转为对象,如果不使用反射的话需要一个get一个set写起来麻烦,并且不通用,所以写了一个通用的方法将map集合转为对象,直接看代码,注释也都挺清楚的 public static < ...
- ui自动化--xpath
xpath //*代表从根节点,查找所有匹配到的元素.在filepath中输入后回车,会发现整个页面所有元素都被虚线选中 //表示跟节点 []代表要用属性定位 @表示要用什么属性 定位完成后,对应页面 ...
- python基础:内置函数zip,map,filter
一.zip zip,就是把俩list,合并到一起,如果想同时循环2个list的时候,可以用zip,会帮你轮流循环两个list 比如: l1=[1,2,3,4,5] l2=['a','b','c','d ...