基于Python的Kmeans聚类分析介绍及实践

基于Python的Kmeans聚类分析介绍及实践

  • 这是一篇学习的总结笔记
  • 参考自《从零开始学数据分析与挖掘》 [中]刘顺祥 著
  • 完整代码及实践所用数据集等资料放置于:Github

聚类算法是依据已知的数据集,将高度相似的样本集中到各自的簇中。例如,借助于电商平台用户的历史交易数据,将用户划分为不同的价值等级(如VIP、高价值、潜在价值、低价值等);依据经度、纬度、交通状况、人流量等数据将地图上的娱乐场所划分为不同的区块(如经济型、交通便捷型、安全型等);利用中国各城市的经济、医疗状况等数据将其划分为几种不同的贫富差距等级(如划分一二三四线城市等)。
如上,聚类算法不仅可以将数据集实现分割,还可以用于异常点的检测,即远离任何簇的样本我们可以视为异常点(离群),而这些异常的样本往往在某些场景下我们要特别关注。如:①信用卡交易的异常,当用户频繁进行奢侈品的交易时可能意味着某种欺诈行为的出现(土豪请忽略);②社交平台中的访问异常,当某个用户频繁地对网站进行访问时(如在1秒钟内访问了上千次),我们可以假设该用户在进行网络爬虫;③电商平台交易异常:一张银行卡被用于上百个ID的支付,并且这些交易订单的送货地址都在某个相近的区域,则可能暗示“黄牛”的出现。总之,我们有很大概率能从离群点中挖掘出我们所需要的信息。
聚类算法是比较典型的无监督学习算法,在数据挖掘领域,能实现聚类的算法有很多。本篇介绍其中的一种——Kmeans聚类算法,该算法利用距离远近的思想将目标数据划分为指定的k个簇,簇内样本越相似,表明聚类效果越好(同样我们尽可能使簇间样本不相似,以避免产生“模棱两可”的现象,这点我们在后面会进行介绍)。重要的内容如下:

  • Kmeans聚类的思想和原理
  • 如何利用数据本身选出合理的k个簇
  • Kmeans聚类的应用实战

无监督学习

现实生活中常常会有这样的问题:缺乏足够的先验知识,因此难以人工标注类别或进行人工类别标注的成本太高。很自然地,我们希望计算机能代我们完成这些工作,或至少提供一些帮助。根据类别未知(没有被标记)的训练样本解决模式识别中的各种问题,称之为无监督学习。
——百度百科

Kmeans聚类

之所以称为Kmeans,是因为该算法可以将数据集划分为指定的k个簇,并且簇的中心点由各簇样本的均值计算所得。首先我们需要知道Kmeans实现聚类的思想和原理。

Kmeans的思想

Kmeans聚类算法的思路通俗易懂,通过不断计算各样本点与簇中心的距离,直到收敛为止,具体步骤如下:

  1. 从数据中随机挑选k个样本点作为原始的簇中心
  2. 计算剩余样本与簇中心的距离,并把各样本标记为离k个簇中心最近的类别
  3. 重复计算各簇中样本点的均值,并以均值作为新的k个簇中心
  4. 重复2、3步骤,直到簇中心的变化趋势趋于稳定,形成最终的k个簇

我们结合下图来理解此过程

在这里插入图片描述

对各个子图做详细说明如下:

  1. 从样本点中随机挑选两个数据点作为初始的簇中心,如图中所示的两个五角星
  2. 将其余样本点与这两个簇中心分别计算距离(距离的测度可以有多种,常见的有欧氏距离、曼哈顿距离等),然后将每个样本点划分到离簇中心(五角星)最近的簇中,即图中用虚线隔开的两部分
  3. 计算两个簇内样本的均值,得到新的簇中心,即图中的两个新的五角星

以新的簇中心不断重复以上三个步骤,得到的簇中心会趋于稳定,最终得到理想的聚类效果,如图9所示。

Kmenas聚类算法的思想比较简单,Python提供了实现该算法的模块——sklearn,我们只需要调用其子模块cluster中的Kmeans类即可,该“类”的语法和参数含义如下:

Kmeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001,
        precompute_distances='auto', verbose=0, random_state=None, 
        copy_x=True, n_jobs=1, algorithm='auto')
  • n_clusters:用于指定聚类的簇数
  • init:用于指定初始的簇中心的设置方法,如果为’k-means++’,则表示设置的初始簇中心相距较远;如果为’random’则表示从数据集中随机挑选k个样本作为初始簇中心;如果为数组,则表示用户指定具体的初始簇中心
  • n_init:用于指定Kmeans算法的运行次数,每次运行时都会选择不同的初始簇中心,目的是防止算法收敛于局部最优,默认为10
  • max_iter:用于指定单次运行的迭代次数,默认为300
  • tol:用于指定算法的收敛阈值,默认为0.0001
  • precompute_distances:bool类型参数,是否在算法运行之前计算样本之间的距离,默认为’auto’,表示当样本量与变量个数的乘积大于1200万时不计算样本之间的距离
  • verbose:通过该参数设置算法返回日志信息的频度,默认为0,表示不输出日志信息;如果为1,就表示每隔一段时间返回日志信息
  • random_state:用于指定随机数生成器的种子
  • copy_X:bool类型参数,当参数precompute_distances为True时有效,如果该参数为True,就表示提前计算距离时不改变原始数据,否则会修改原始数据
  • n_jobs:用于指定算法运行时的CPU数量,默认为1,如果为-1,就表示使用所有可用的CPU
  • algorithm:用于指定Kmeans的实现算法,可以选择’auto’‘full’和’elkan’,默认为’auto’,表示自动根据数据特征选择运算的算法
Kmeans的原理

上面提到,对于指定的k个簇,簇内样本越相似,聚类效果越好,我们可以根据这个结论为Kmeans聚类算法构造目标函数。该目标函数的思想是:所有簇内样本的离差平方和之和达到最小。(我们可以这么理解:如果某个簇内样本很相似,则簇内的离差平方和会非常小(另一种理解是:簇内方差小)),对于所有簇而言,我们就是要寻求使得所有簇的离差平方和总和最小的划分。
根据上面思想,我们可以构造如下目标函数: J ( c 1 , c 2 , . . . c k ) = ∑ j = 1 k ∑ i n j ( x i − c j ) 2 J(c_1,c_2,...c_k)=\sum^{k}_{j=1}\sum^{n_j}_{i}(x_i-c_j)^2 J(c1,c2,...ck)=j=1kinj(xicj)2其中, c j c_j cj表示第 j j j个簇的簇中心, x i x_i xi是第 j j j个簇中的样本, n j n_j nj是第 j j j个簇的样本总量。对于该目标函数而言, c j c_j cj是未知的参数,如果要求地目标函数的最小值,得先知道参数 c j c_j cj的值。由于目标函数函数 J J J为一个凸函数,我们可以通过求导的方式获取合理的参数 c j c_j cj的值,具体步骤如下:
步骤①:对目标函数求导 ∂ J ∂ c j = ∑ j = 1 k ∑ i n j ( x i − c j ) 2 ∂ c j = ∑ i n j ( x i − c j ) 2 ∂ c j = ∑ i = 1 n j − 2 ( x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值