当前位置: 首页 > news >正文

Python大数据分析——Kmeans聚类分析

Python大数据分析——Kmeans聚类分析

  • 介绍
  • 步骤
  • 数学分析
    • 目标函数
    • K值选择
      • 拐点法
      • 轮廓系数法
  • 函数
  • 示例
    • 已知k值的情况——iris聚类
    • 未知k值的情况——NBA球员分类

介绍

对于有监督的数据挖掘算法而言,数据集中需要包含标签变量(即因变量y的值)。但在有些场景下,并没有给定的y值,对于这类数据的建模,一般称为无监督的数据挖掘算法,最为典型的当属聚类算法。
Kmeans聚类算法利用距离远近的思想将目标数据聚为指定的k个簇,进而使样本呈现簇内差异小,簇间差异大的特征。

步骤

  1. 从数据中随机挑选k个样本点作为原始的簇中心
  2. 计算剩余样本与簇中心的距离,并把各样本标记为离k个簇中心最近的类别
  3. 重新计算各簇中样本点的均值,并以均值作为新的k个簇中心
  4. 不断重复第二步和第三步,直到簇中心的变化趋于稳定,形成最终的k个簇
    在这里插入图片描述

数学分析

目标函数

在Kmeans聚类模型中,对于指定的k个簇,只有簇内样本越相似,聚类效果才越好。基于这个思想,可以理解为簇内样本的离差平方和之和达到最小即可。进而可以行生出Kmeans聚类的目标函数:
在这里插入图片描述
其中,cj表示第j个簇的簇中心,xi属于第j个簇的样本i,nj表示第j个簇的样本总量。对于该目标函数而言,cj是未知的参数,要想求得目标函数的最小值,得先知道参数cj的值。

我们对目标函数求偏导:
在这里插入图片描述
令其导数为0:
在这里插入图片描述

K值选择

拐点法

簇内离差平方和拐点法的思想很简单,就是在不同的k值下计算簇内离差平方和,然后通过可视化的方法找到“拐点”所对应的k值。当折线图中的斜率由大突然变小时,并且之后的斜率变化缓慢,则认为突然变化的点就是寻找的目标点,因为继续随着簇数k的增加,聚类效果不再有大的变化。

也就是在变换最大的处,就是我们要找的类别数,也就是K值:
在这里插入图片描述
自定义函数:

def k_SSE(X, clusters):# 选择连续的K种不同的值K = range(1,clusters+1)# 构建空列表用于存储总的簇内离差平方和TSSE = []for k in K:# 用于存储各个簇内离差平方和SSE = []kmeans = KMeans(n_clusters=k)kmeans.fit(X)# 返回簇标签labels = kmeans.labels_# 返回簇中心centers = kmeans.cluster_centers_# 计算各簇样本的离差平方和,并保存到列表中for label in set(labels):SSE.append(np.sum((X.loc[labels == label,]-centers[label,:])**2))# 计算总的簇内离差平方和TSSE.append(np.sum(SSE))

轮廓系数法

该方法综合考虑了簇的密集性与分散性两个信息,如果数据集被分割为理想的k个簇,那么对应的簇内样本会很密集,而族间样本会很分散。轮廓系数的计算公式可以表示为:
在这里插入图片描述
其中,a(i)体现了簇内的密集性,代表样本i与同簇内其他样本点距离的平均值;b(i)反映了簇间的分敬性,它的计算过程是,样本i与其他非同簇样本点距离的平均值,然后从平均值中挑选出最小值。
当S(i)接近于-1时,说明样本i分配的不合理,需要将其分配到其他簇中;当S(i)近似为0时,说明样本落在了模糊地带,即簇的边界处;当S(i)近似为1时,说明样本i的分配是合理的。
所以我们希望的是ai,也就是类内越小越好;bi,也就是类间,越大越好。

假设数据集被拆分为4个簇,样本i对应的a(i)值就是所有C1中其他样本点与样本i的距离平均值;样本i对应的b(i)值分两步计算,首先计算该点分别到C2、C3和C4中样本点的平均距离,然后将三个平均值中的最小值作为b(i)的度量。
在这里插入图片描述

# 构造自定义函数
def k_silhouette(X, clusters):K = range(2,clusters+1)# 构建空列表,用于存储不同簇数下的轮廓系数S = []for k in K:kmeans = KMeans(n_clusters=k)kmeans.fit(X)labels = kmeans.labels_# 调用子模块metrics中的silhouette_score函数,计算轮廓系数S.append(metrics.silhouette_score(X, labels, metric='euclidean'))

当这个值最大,接近于1的时候,就是我们选择的K的值:
在这里插入图片描述

函数

KMeans(n_clusters=8, init=‘k-means++’, n_init=10, max_iter=300, tol=0.0001)
n_clusters:用于指定聚类的簇数
init:用于指定初始的簇中心设置方法,如果为’k-means++‘,则表示设置的初始簇中心之间相距较远;如果为’random’,则表示从数据集中随机挑选k个样本作为初始簇中心;如果为数组,则表示用户指定具体的簇中心
n_init:用于指定Kmeans算法运行的次数,每次运行时都会选择不同的初始簇中心,目的是防止算法收敛于局部最优,默认为10
max_iter:用于指定单次运行的迭代次数,默认为300
tol:用于指定算法收敛的阈值,默认为0.0001

示例

已知k值的情况——iris聚类

首先我们通过已知k值的情况下,通过有y标签的,画出的图像;对比我们聚类得到的图像,验证我们的方法是否良好。

  1. 导入包读取数据集
# 导入第三方包
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans# 读取iris数据集
iris = pd.read_csv(r'D:\pythonProject\data\iris.csv')
# 查看数据集的前几行
iris.head()

输出:
在这里插入图片描述

  1. 构建Kmeans模型,对其标签结果进行分析
# 提取出用于建模的数据集X
X = iris.drop(labels = 'Species', axis = 1)
# 构建Kmeans模型
kmeans = KMeans(n_clusters = 3)
kmeans.fit(X)
# 聚类结果标签
X['cluster'] = kmeans.labels_
# 各类频数统计
X.cluster.value_counts()

输出:
在这里插入图片描述

  1. 首先来看我们Kmeans模型,聚类得到的分布
# 导入第三方模块
import seaborn as sns# 三个簇的簇中心
centers = kmeans.cluster_centers_
# 绘制聚类效果的散点图
sns.lmplot(x = 'Petal_Length', y = 'Petal_Width', hue = 'cluster', markers = ['^','s','o'], data = X, fit_reg = False, scatter_kws = {'alpha':0.8}, legend_out = False)
plt.scatter(centers[:,2], centers[:,3], marker = '*', color = 'black', s = 130)
plt.xlabel('Petal_Length')
plt.ylabel('Petal_Width')
# 图形显示
plt.show()

在这里插入图片描述

  1. 再来看我们原始分布是什么样子
# 增加一个辅助列,将不同的花种映射到0,1,2三种值,目的方便后面图形的对比
iris['Species_map'] = iris.Species.map({'virginica':0,'setosa':1,'versicolor':2})
# 绘制原始数据三个类别的散点图
sns.lmplot(x = 'Petal_Length', y = 'Petal_Width', hue = 'Species_map', data = iris, markers = ['^','s','o'],fit_reg = False, scatter_kws = {'alpha':0.8}, legend_out = False)
plt.xlabel('Petal_Length_old')
plt.ylabel('Petal_Width_old')
# 图形显示
plt.show()

在这里插入图片描述
我们通过对比发现基本上是差不多的,这说明我们的Kmeans模型十分有效,一般情况下我们是不知道K值的,也没用y标签,下面我们讲正常情况下的聚类例子。

未知k值的情况——NBA球员分类

  1. 导入功能包,读取数据
# 导入第三方包
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn import metrics # 轮廓系数包# 读取球员数据
players = pd.read_csv(r'D:\pythonProject\data\players.csv')
players.head()

在这里插入图片描述

  1. 查看数据分布
# 绘制得分与命中率的散点图
sns.lmplot(x = '得分', y = '命中率', data = players, fit_reg = False, scatter_kws = {'alpha':0.8, 'color': 'steelblue'})
plt.rcParams['font.family'] = ['SimHei'] # matplotlib显示中文字
plt.show()

在这里插入图片描述

  1. 构造拐点法函数
# 构造自定义函数,用于绘制不同k值和对应总的簇内离差平方和的折线图
def k_SSE(X, clusters):# 选择连续的K种不同的值K = range(1,clusters+1)# 构建空列表用于存储总的簇内离差平方和TSSE = []for k in K:# 用于存储各个簇内离差平方和SSE = []kmeans = KMeans(n_clusters=k)kmeans.fit(X)# 返回簇标签labels = kmeans.labels_# 返回簇中心centers = kmeans.cluster_centers_# 计算各簇样本的离差平方和,并保存到列表中for label in set(labels):SSE.append(np.sum((X.loc[labels == label,]-centers[label,:])**2))# 计算总的簇内离差平方和 TSSE.append(np.sum(SSE))# 中文和负号的正常显示plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']plt.rcParams['axes.unicode_minus'] = False# 设置绘图风格plt.style.use('ggplot')# 绘制K的个数与GSSE的关系plt.plot(K, TSSE, 'b*-')plt.xlabel('簇的个数')plt.ylabel('簇内离差平方和之和')# 显示图形plt.show()
  1. 构造轮廓系数法
# 构造自定义函数,用于绘制不同k值和对应轮廓系数的折线图
def k_silhouette(X, clusters):K = range(2,clusters+1)# 构建空列表,用于存储个中簇数下的轮廓系数S = []for k in K:kmeans = KMeans(n_clusters=k)kmeans.fit(X)labels = kmeans.labels_# 调用字模块metrics中的silhouette_score函数,计算轮廓系数S.append(metrics.silhouette_score(X, labels, metric='euclidean'))# 中文和负号的正常显示plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']plt.rcParams['axes.unicode_minus'] = False# 设置绘图风格plt.style.use('ggplot')    # 绘制K的个数与轮廓系数的关系plt.plot(K, S, 'b*-')plt.xlabel('簇的个数')plt.ylabel('轮廓系数')# 显示图形plt.show()
  1. 对数据进行标准化处理,然后寻找K值
    对数据进行标准化后,首先来看拐点法:
from sklearn import preprocessing
# 数据标准化处理
X = preprocessing.minmax_scale(players[['得分','罚球命中率','命中率','三分命中率']])
# 将数组转换为数据框
X = pd.DataFrame(X, columns=['得分','罚球命中率','命中率','三分命中率'])
# 使用拐点法选择最佳的K值
k_SSE(X, 15)

在这里插入图片描述
我们发现3之后变换就没那么大了,那么3可能就是我们要选的值。
我们再看轮廓系数法:

# 使用轮廓系数选择最佳的K值
k_silhouette(X, 10)

在这里插入图片描述
但因为其数值特别小,我们人为是不可靠的,一般只有轮廓系数比较接近于1时,才是比较靠谱的

  1. 通过得到的K值进行聚类分析
# 将球员数据集聚为3类
kmeans = KMeans(n_clusters = 3)
kmeans.fit(X)
# 将聚类结果标签插入到数据集players中
players['cluster'] = kmeans.labels_
# 构建空列表,用于存储三个簇的簇中心
centers = []
for i in players.cluster.unique():centers.append(players.loc[players.cluster == i,['得分','罚球命中率','命中率','三分命中率']].mean())
# 将列表转换为数组,便于后面的索引取数
centers = np.array(centers)# 绘制散点图
sns.lmplot(x = '得分', y = '命中率', hue = 'cluster', data = players, markers = ['^','s','o'],fit_reg = False, scatter_kws = {'alpha':0.8}, legend = False)
# 添加簇中心
plt.scatter(centers[:,0], centers[:,2], c='k', marker = '*', s = 180)
plt.xlabel('得分')
plt.ylabel('命中率')
# 图形显示
plt.show()

在这里插入图片描述

注意:在Pandas的早期版本中,ix 是一个方便的索引器,允许用户通过标签和整数位置来索引DataFrame的行和列。然而,随着Pandas版本的更新,为了简化API和提高代码的可读性,ix 索引器在Pandas 0.20.0版本中被弃用,并在后续版本中完全移除。因此,如果你尝试在较新版本的Pandas中使用 ix,你将会遇到一个 AttributeError。所以我们要改为.loc或者.iloc

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 智驭灌区,科技领航—— 高效灌区信息化系统管理平台
  • 【面试常问之网络】网络故障排查方面
  • AtCoder Regular Contest 180 C. Subsequence and Prefix Sum (dp好题 辅助数组)
  • Go语言实现依赖注入
  • Git代码管理规范
  • 负载均衡详细概念介绍之(四层和七层实现)
  • 微信小程序怎样实现前后台交互?
  • Git命令从入门到精通
  • 在Debian 8上安装Git的方法
  • Apache HTTPD 换行漏洞(CVE-2017-15715)
  • Qt题目知多少-3
  • Redis的Bitmaps结构常用命令总结
  • vue框架的安全设计
  • 后端学习笔记(5)--查询
  • 在哪些行业中,3D 技术发挥了重要作用?
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • Android单元测试 - 几个重要问题
  • axios 和 cookie 的那些事
  • Bytom交易说明(账户管理模式)
  • interface和setter,getter
  • js写一个简单的选项卡
  • Python学习之路16-使用API
  • ReactNative开发常用的三方模块
  • spring boot 整合mybatis 无法输出sql的问题
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Vue ES6 Jade Scss Webpack Gulp
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 服务器从安装到部署全过程(二)
  • 回顾 Swift 多平台移植进度 #2
  • 记一次删除Git记录中的大文件的过程
  • 跨域
  • 利用jquery编写加法运算验证码
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 聊一聊前端的监控
  • 如何选择开源的机器学习框架?
  • 数据科学 第 3 章 11 字符串处理
  • Mac 上flink的安装与启动
  • ​比特币大跌的 2 个原因
  • #define,static,const,三种常量的区别
  • #includecmath
  • #在 README.md 中生成项目目录结构
  • $NOIp2018$劝退记
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (6)设计一个TimeMap
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)Google的Objective-C编码规范
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)Sublime Text3配置Lua运行环境
  • (转)母版页和相对路径
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .NET BackgroundWorker
  • .NET delegate 委托 、 Event 事件,接口回调