k-means聚类算法python实现,kmeans聚类算法实例数据

  k-means聚类算法python实现,kmeans聚类算法实例数据

  K-means是一种发现给定数据集的K个聚类的算法,即把数据集聚集成K个类的算法。下面这篇文章主要介绍用Python进行K-Means聚类的相关信息,有需要的朋友可以参考一下。

  00-1010 K-Means聚类算法介绍K-Means聚类算法的基本原理实现过程开始做简单的聚类数据导入数据探索开始聚类并查看输出结果。K-Means聚类算法的评价指标是真实标签已知,而真实标签未知。实际案例:基于轮廓系数的最佳n_clusters结果比较及优化方案选择。

  

目录

 

  K-means也称为K-Means聚类算法,属于机器学习算法中的聚类算法,之一,而聚类算法属于无监督学习。在业务上,往往结合实际需求和业务逻辑理解来完成建模;

  无监督学习:训练时只需要特征矩阵X和不需要标签

  

K-Means聚类算法介绍

 

  K-Means聚类算法是聚类算法家族的典型代表,也是最简单的算法。接下来,我们将简要介绍聚类算法的基本原理:

  将一组具有N个样本的特征矩阵X分成K个没有交集的簇,每个簇包含多个数据,每个数据代表一个样本,同一簇中的数据被算法认为是同一类;

  n:假设样本数;k:假设集群数;聚类:类似于集合,也可以通俗地理解为一个组,不同的组等于不同的分类;

  一个聚类中所有数据的均值称为这个聚类的质心,质心的维数与特征矩阵X的维数相同,比如特征矩阵X是三维数据集,质心是三维坐标,以此类推到更高维;

  

K-Means聚类算法基础原理

 

  1 .从n个样本中随机抽取k个样本作为初始质心;

  第二步:开始遍历除质心以外的所有采样点,并将其分配到最近的质心。将每个质心和赋给它的样本点视为一个聚类(或一个分类),从而完成第一次聚类;

  步骤3,对于每个聚类,重新计算该聚类中所有样本点的平均值,并将结果作为新的质心;

  步骤四,比较新旧质心是否再次发生变化,如果是,则根据新质心从步骤二开始重复,如果不是,则完成聚类;

  关键点:不断搜索样本点的质心,然后更新质心,直到质心不再变化;

  

K-Means聚类算法实现流程

 

  说明:本文实际案例使用Jupyter环境运行(安装使用可百度);

  

开始做一个简单的聚类

 

  在数据分析之前,第一步是导入数据。可以使用pandas中的read_csv函数导入数据。

  首先,导入所需的类,并使用read_csv函数导入案例数据:

  将numpy作为np导入

  进口熊猫作为pd

  data=PD . read _ CSV(r d : Machine _ learning k means client _ data . CSV )

  #在pandas中使用read_csv函数导入数据集后,默认格式为DataFrame。

  #直接查看当前数据集的样子

  data.head()

  当数据打开时,它将看起来像这样:

  交易量,最近交易时间

  0 76584.92 294 64

  任何人

   94581.00 232 1
2 51037.60 133 1
3 43836.00 98 1
4 88032.00 95 2

# 若表头项为中文时,可能出现乱码情况,请自行百度解决,或直接修改为英文;

  

  

 

  

数据探索

 

  先探索数据类型:

  

# 探索数据类型

 

  

  • 共8011个数据样本,3个维度列(2个整数、1个浮点数),且无缺失数据;

  • 数据背景:从三个维度获取所有用户交易180天内交易数据(数据获取、清洗规则在此不作详细说明);

  • 第一列:索引(read_csv函数导入数据时会自动生成索引,若数据集本身自带索引,可设置参数index_=0,代表数据集中第一列为索引);

  • 第二列:180天内交易额,浮点数;

  • 第三列:180天内成交单量,整数;

  • 第四列:最近成交订单的日期与当前日期差,整数(180内无数据按照180运算);

 

  由于sklearn中K-Means聚类算法仅支持二维数组运算,所以要先将数据集转化为二维数组:

  

data = np.array(data,type(float))

 

  查看数组结构:

  

# 查看数组结构

 

  

 

  

开始聚类

 

  数据集导入完成后,现在调用sklearn完成简单的聚类:

  

from sklearn.cluster import KMeans

 

  

  • 参数n_clusters:
    设定聚类的目标簇数量,本次聚类先用5个簇尝试;

  • 参数random_state:
    设定随机数种子,若不设定则每次聚类时都会使用不同的随机质心;

  • 接口fit():
    使用数据集对模型进行训练;

  • 属性labels_:
    查看训练后,每一样本的预测分类结果;

 

  

 

  

查看输出结果

 

  查看输出结果的数组结构:

  

# 查看预测结果的数据结构

 

  分类结果的数组结构为(8011,),刚好对应着8011个样本的预测分类结果;

  再次确认目标分类结果只有5类,可以使用numpy中的unique()函数实现:

  

# 查看数组中存在的类别(对一维数组去重)

 

  输出结果0~4中分别代表着5个不同的分类;

  查看预测结果中每一分类的数量:

  

# 查看每一分类结果的数量

 

  分类为0的数据占比较大(约88%),这部分数据数据实际行业应用中的长尾数据,这类用户对平台几乎没有任何价值贡献;

  

 

  

聚类质心

 

  聚类质心代表每一个分类簇的中心,某种意义上讲,质心坐标可以代表着这一个簇的普遍特征,质心可以通过调用属性cluster_centers_来查看:

  

# 查看质心

 

  输出结果中分别对应着0~4五种分类的普遍数据特征;

  

 

  

K-Means聚类算法的评估指标

 

  当我们完成聚类建模后,怎么知道聚类的效果好不好,这时我们便需要「评估指标」来评价模型的优劣,并根据此来调整参数;

  对于聚类算法的评估指标,从大方向上区分为两种:真实标签已知与真实标签未知;

  

 

  

真实标签已知

 

  即我们对于每一个样本的标签Y都是已知的,但是这种情况在实际的业务中几乎是不存在的,若标签已知,使用分类算法(如随机森林、SVM等)在各个方面来说都会更加合适;

  

  • 调整兰德系数:

 

  在sklearn中的类为sklearn.metrics.adjusted_rand_score(y_true, y_pred)

  

y_true:代表测试集中一个样本的真实标签;

 

  y_pred:使用测试集中样本调用预测接口的预测结果(上文中使用的cluster.labels_);

  

 

  调整兰德系数的取值在[-1,1]:数值越接近1越好,大于0时聚类效果较为优秀,小于0时代表簇内差异巨大甚至相互独立,模型几乎不可用;

  由于案例数据集中真实标签是未知的,故不在此展示;

  

 

  

真实标签未知

 

  即我们对每一个样本的标签Y都是未知的,我们事先不知道每一个样本是属于什么分类,这种情况才是符合我们实际业务中真实使用聚类算法的场景;

  

  • 轮廓系数系数:

 

  在sklearn中的类为:

  返回轮廓系数的均值:sklearn.metrics.silhouette_score(X, y_pred);

  返回数据集中每个样本自身的轮廓系数:sklearn.metrics.silhouette_sample(X, y_pred);

  轮廓系数的取值在(-1,1):

  对于某一样本点来说,当值越接近1时就代表自身与所在的簇中其他样本越相似,并且与其他簇中的样本不相似,而当值越接近-1时则代表与上述内容相反;综述,轮廓系数越接近1越好,负数则表示聚类效果非常差;

  那接下来看看轮廓系数在刚才的聚类中效果如何:

  

# 导入轮廓系数所需要的库

 

  本次聚类的轮廓系数为0.84,表示聚类效果良好;

  样本轮廓系数的数据结构可以看出:数组中每一个输出结果对应着每一个样本的轮廓系数,共8011个;

  

  • 卡林斯基-哈拉巴斯指数:

 

  sklearn中的类:sklearn.metrics.calinski_haabasz_score (X, y_pred);

  卡林斯基-哈拉巴斯指数的数值无上限,且对于模型效果来说越高越好,而由于无上限的特性,导致只能用作对比,而无法快速知晓模型效果是否好;

  可以看看轮廓系数在刚才的聚类中效果如何:

  

# 调用所需要的类

 

  输出的结果为31778,那究竟效果如何?因为没有对照组,所以无法得知,如果有兴趣的小伙伴可以在调整参数的时候使用对照组试试效果;

  

 

  

实用案例:基于轮廓系数来选择最佳的n_clusters

 

  需要绘制轮廓系数分布图,先导入所需用到的库:

  

import matplotlib.pyplot as plt

 

  绘制轮廓系数分布图

  使用for循环分别对2~8个簇的情况画出轮廓系数分布图:

  

for n_clusters in [2,3,4,5,6,7,8]:

 

  

 

  

结果对比

 

  输出结果:

  簇数为 2 ,轮廓系数均值为 0.9348704011138467:

  

 

  簇数为3,轮廓系数均值为0.8889120986545176:

  

 

  簇数为4,轮廓系数均值为0.8432045328349393:

  

 

  簇数为 5 ,轮廓系数均值为 0.8397653971050274:

  

 

  簇数为 6 ,轮廓系数均值为 0.8217141668609508:

  

 

  簇数为 7 ,轮廓系数均值为 0.7995236853252528:

  

 

  簇数为 8 ,轮廓系数均值为 0.7995236853252528:

  

 

  从本次的输出结果中可知,当簇数量为2时,会存在最大的轮廓系数均值,是否簇数量为2就是最佳的参数呢?

  答案必须是否定的,我们可以通过轮廓系数分部图看到,基本上每一个图内都会有一片面积很大的块,这就是长尾数据带来的,因为他们基本都集中在一个点上,所以导致整体轮廓系数均值被平均得很大,这样的状况也是很多实际业务数据中常常会碰到的;

  

 

  

优化方案选择

 

  既然由于长尾数据对轮廓系数带来较大偏差,那咱们的思路可以把长尾数据剔除掉,仅计算非长尾数据(数据分析需要在不同的具体场景下有不同的思路,以下仅是一种思路举例);

  当簇数量为3时:

  

# 实例化,训练模型

 

  长尾数据所在的簇为0,计算非长尾数据的轮廓系数均值:

  

cluster_labels = clusterer.labels_

 

  当簇数量为4时:

  

# 实例化,训练,并查看结果分布

 

  当簇数量为5时:

  

# 实例化,训练,并查看结果分布

 

  当簇数量为6时:

  

# 实例化,训练,并查看结果分布

 

  当簇数量为7时:

  

# 实例化,训练,并查看结果分布

 

  当簇数量为8时:

  

# 实例化,训练,并查看结果分布

 

  对比上述结果,当n_clusters=6时,轮廓系数均值存在最大值0.5043;

  这时查看质心的坐标:

  

# 设置参数n_clusters=6再次训练模型

 

  从结果可得(数据结果为科学计数法),6个类别客户的画像特征分别对应着:

  

  • 分类0——6806位——占比85%:
    交易额:251元,平均单量:0.6单,最近交易时间:152天前;

  • 分类1——36位——占比0.4%:
    交易额:43637元,平均单量:48单,最近交易时间:21天前;

  • 分类2——99位——占比1.2%:
    交易额:22325元,平均单量:27单,最近交易时间:17天前;

  • 分类3——252位——占比3.1%:
    交易额:11549元,平均单量:17单,最近交易时间:20天前;

  • 分类4——19位——占比0.2%:
    交易额:75703元,平均单量:78单,最近交易时间:15天前;

  • 分类5——799位——占比10%:
    交易额:4256元,平均单量:7单,最近交易时间:44天前;

 

  到此这篇关于利用Python实现K-Means聚类的文章就介绍到这了,更多相关Python实现K-Means聚类内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: