【Python数据分析】数据挖掘建模——聚类分析

聚类算法是在没有给定划分类别的情况下,根据数据相似度进行样本分组的一种方法,是一种无监督学习方法。聚类的输入是一组未被标记的样本,聚类根据数据自身的距离或相似度将他们划分为若干组,划分的原则是组内样本最小而组间距离最大化。

常用的聚类方法有:

【Python数据分析】数据挖掘建模——聚类分析

常见的聚类分析算法有:

【Python数据分析】数据挖掘建模——聚类分析

这里主要介绍一下最常用的K-Means聚类算法

一、K-Means聚类算法简介

K-Means算法是典型的基于距离的非层次聚类算法,在最小化误差函数的基础上将数据划分为预定的类数k,采用距离作为相似性评价指标,即认为两个对象的距离越近,其相似度就越大。

1.算法过程

(1)从n个样本数据中随机选取k个对象作为初始聚类中心;

(2)分别计算每个样本到各个聚类中心的距离,将对象分配到距离最近的聚类中;

(3)所欲对象分配完后,重新计算k个聚类的中心;

(4)与前一次计算得到的k个聚类中心比较,如果聚类中心发生变化,转至步骤(2),否则转至步骤(5);

(5)当质心不发生变化时,停止并输出聚类结果。

2.聚类算法的优缺点

2.1 优点

  • 容易理解,聚类效果不错,虽然是局部最优, 但往往局部最优就够了;
  • 处理大数据集的时候,该算法可以保证较好的伸缩性;
  • 当簇近似高斯分布的时候,效果非常不错;
  • 算法复杂度低。

2.2 缺点

  • K 值需要人为设定,不同 K 值得到的结果不一样;
  • 对初始的簇中心敏感,不同选取方式会得到不同结果;
  • 对异常值敏感;
  • 样本只能归为一类,不适合多分类任务;
  • 不适合太离散的分类、样本类别不平衡的分类、非凸形状的分类。

参考:【机器学习】K-means(非常详细) – 知乎

聚类的结果可能依赖于初始聚类中心的随机选择,使得结果严重偏离全局最优分类。因此,在实践中为了得到较好的结果,通常选择不同的初始聚类中心,多次运行k-means算法。在计算k个聚类中心的时候,对于连续数据,聚类中心取该簇的均值但是当样本的某些属性是分类变量时,均值可能无定义,此时可以使用k-众数方法。

3.相似性的度量

对于连续属性,要先对各属性值进行零-均值规范,再进行距离的计算。度量样本之间的相似性最常用的是欧几里得距离、曼哈顿距离和闵可夫斯基距离。

【Python数据分析】数据挖掘建模——聚类分析

4.目标函数

使用误差平方和SSE作为度量聚类质量的目标函数。

【Python数据分析】数据挖掘建模——聚类分析

【Python数据分析】数据挖掘建模——聚类分析的聚类中心【Python数据分析】数据挖掘建模——聚类分析的计算公式

【Python数据分析】数据挖掘建模——聚类分析

其中 k表示聚类簇的个数,

【Python数据分析】数据挖掘建模——聚类分析表示第i个簇,x代表样本,【Python数据分析】数据挖掘建模——聚类分析表示簇【Python数据分析】数据挖掘建模——聚类分析的聚类中心,n表示数据集中样本的个数,【Python数据分析】数据挖掘建模——聚类分析表示第i个簇中样本的个数。

二、用Python实现K-Means聚类算法

1、导入数据并进行标准化

import pandas as pd
inputfile = './Python数据分析与挖掘实战(第2版)/chapter5/demo/data/consumption_data.xls'
data = pd.read_excel(inputfile,index_col = 'Id')
data

数据如下:

【Python数据分析】数据挖掘建模——聚类分析

该数据集表示餐饮客户的消费行为特征

k = 3   #聚类的类别
iteration = 500  #聚类最大循环次数
data_zs = 1.0*(data-data.mean())/data.std()   #数据标准化
data_zs

2.构建kmeans模型

from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration, random_state = 1234) #分类为k,并发数为4
model.fit(data_zs)

【Python数据分析】数据挖掘建模——聚类分析

<strong>n_clusters: </strong>&#x7C07;&#x7684;&#x4E2A;&#x6570;&#xFF0C;&#x5373;&#x4F60;&#x60F3;&#x805A;&#x6210;&#x51E0;&#x7C7B;

<strong>init:</strong> &#x521D;&#x59CB;&#x7C07;&#x4E2D;&#x5FC3;&#x7684;&#x83B7;&#x53D6;&#x65B9;&#x6CD5;

<strong>n_init:</strong> &#x83B7;&#x53D6;&#x521D;&#x59CB;&#x7C07;&#x4E2D;&#x5FC3;&#x7684;&#x66F4;&#x8FED;&#x6B21;&#x6570;&#xFF0C;&#x4E3A;&#x4E86;&#x5F25;&#x8865;&#x521D;&#x59CB;&#x8D28;&#x5FC3;&#x7684;&#x5F71;&#x54CD;&#xFF0C;&#x7B97;&#x6CD5;&#x9ED8;&#x8BA4;&#x4F1A;&#x521D;&#x59CB; 10 &#x4E2A;&#x8D28;&#x5FC3;&#xFF0C;&#x5B9E;&#x73B0;&#x7B97;&#x6CD5;&#xFF0C;&#x7136;&#x540E;&#x8FD4;&#x56DE;&#x6700;&#x597D;&#x7684;&#x7ED3;&#x679C;&#x3002;

<strong>max_iter:</strong> &#x6700;&#x5927;&#x8FED;&#x4EE3;&#x6B21;&#x6570;&#xFF08;&#x56E0;&#x4E3A;kmeans&#x7B97;&#x6CD5;&#x7684;&#x5B9E;&#x73B0;&#x9700;&#x8981;&#x8FED;&#x4EE3;&#xFF09;

<strong>tol:</strong> &#x5BB9;&#x5FCD;&#x5EA6;&#xFF0C;&#x5373;kmeans&#x8FD0;&#x884C;&#x51C6;&#x5219;&#x6536;&#x655B;&#x7684;&#x6761;&#x4EF6;

<strong>precompute_distances:</strong>&#x662F;&#x5426;&#x9700;&#x8981;&#x63D0;&#x524D;&#x8BA1;&#x7B97;&#x8DDD;&#x79BB;&#xFF0C;&#x8FD9;&#x4E2A;&#x53C2;&#x6570;&#x4F1A;&#x5728;&#x7A7A;&#x95F4;&#x548C;&#x65F6;&#x95F4;&#x4E4B;&#x95F4;&#x505A;&#x6743;&#x8861;&#xFF0C;&#x5982;&#x679C;&#x662F; True &#x4F1A;&#x628A;&#x6574;&#x4E2A;&#x8DDD;&#x79BB;&#x77E9;&#x9635;&#x90FD;&#x653E;&#x5230;&#x5185;&#x5B58;&#x4E2D;&#xFF0C;auto &#x4F1A;&#x9ED8;&#x8BA4;&#x5728;&#x6570;&#x636E;&#x6837;&#x672C;&#x5927;&#x4E8E;featurs * samples &#x7684;&#x6570;&#x91CF;&#x5927;&#x4E8E; 12e6 &#x7684;&#x65F6;&#x5019; False , False &#x65F6;&#x6838;&#x5FC3;&#x5B9E;&#x73B0;&#x7684;&#x65B9;&#x6CD5;&#x662F;&#x5229;&#x7528;Cpython &#x6765;&#x5B9E;&#x73B0;&#x7684;

<strong>verbose:</strong> &#x5197;&#x957F;&#x6A21;&#x5F0F;&#xFF08;&#x4E0D;&#x592A;&#x61C2;&#x662F;&#x5565;&#x610F;&#x601D;&#xFF0C;&#x53CD;&#x6B63;&#x4E00;&#x822C;&#x4E0D;&#x53BB;&#x6539;&#x9ED8;&#x8BA4;&#x503C;&#xFF09;

<strong>random_state:</strong> &#x968F;&#x673A;&#x751F;&#x6210;&#x7C07;&#x4E2D;&#x5FC3;&#x7684;&#x72B6;&#x6001;&#x6761;&#x4EF6;&#x3002;

<strong>copy_x: </strong>&#x5BF9;&#x662F;&#x5426;&#x4FEE;&#x6539;&#x6570;&#x636E;&#x7684;&#x4E00;&#x4E2A;&#x6807;&#x8BB0;&#xFF0C;&#x5982;&#x679C; True &#xFF0C;&#x5373;&#x590D;&#x5236;&#x4E86;&#x5C31;&#x4E0D;&#x4F1A;&#x4FEE;&#x6539;&#x6570;&#x636E;&#x3002; bool &#x5728;scikit - learn &#x5F88;&#x591A;&#x63A5;&#x53E3;&#x4E2D;&#x90FD;&#x4F1A;&#x6709;&#x8FD9;&#x4E2A;&#x53C2;&#x6570;&#x7684;&#xFF0C;&#x5C31;&#x662F;&#x662F;&#x5426;&#x5BF9;&#x8F93;&#x5165;&#x6570;&#x636E;&#x7EE7;&#x7EED;copy &#x64CD;&#x4F5C;&#xFF0C;&#x4EE5;&#x4FBF;&#x4E0D;&#x4FEE;&#x6539;&#x7528;&#x6237;&#x7684;&#x8F93;&#x5165;&#x6570;&#x636E;&#x3002;&#x8FD9;&#x4E2A;&#x8981;&#x7406;&#x89E3;Python &#x7684;&#x5185;&#x5B58;&#x673A;&#x5236;&#x624D;&#x4F1A;&#x6BD4;&#x8F83;&#x6E05;&#x695A;&#x3002;

<strong>n_jobs:</strong> &#x5E76;&#x884C;&#x8BBE;&#x7F6E;

<strong>algorithm:</strong> kmeans&#x7684;&#x5B9E;&#x73B0;&#x7B97;&#x6CD5;&#xFF0C;&#x6709;&#xFF1A; 'auto' , &#x2018;full ', &#x2018;elkan' , &#x5176;&#x4E2D; &#x2018;full'&#x8868;&#x793A;&#x7528;EM&#x65B9;&#x5F0F;&#x5B9E;&#x73B0;

&#x867D;&#x7136;&#x6709;&#x5F88;&#x591A;&#x53C2;&#x6570;&#xFF0C;&#x4F46;&#x662F;&#x90FD;&#x5DF2;&#x7ECF;&#x7ED9;&#x51FA;&#x4E86;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x4E00;&#x822C;&#x4E0D;&#x9700;&#x8981;&#x53BB;&#x4F20;&#x5165;&#x8FD9;&#x4E9B;&#x53C2;&#x6570;,&#x53C2;&#x6570;&#x7684;&#x3002;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x5B9E;&#x9645;&#x9700;&#x8981;&#x6765;&#x8C03;&#x7528;&#x3002;

&#x53C2;&#x8003;&#xFF1A;https://www.jb51.net/article/129821.htm

3.结果展示

#简单打印结果
r1 = pd.Series(model.labels_).value_counts()  #统计各类别数目
r2 = pd.DataFrame(model.cluster_centers_)  #找出聚类中心
r = pd.concat([r2,r1],axis =1)  #得到聚类中心对应的类别下的数目

r.columns = list(data.columns) + ['类别数目']    #重命名表头
print(r)

得到结果如下,显示了每个特征在每个簇下的中心位置。

【Python数据分析】数据挖掘建模——聚类分析

详细输出原始数据及其类别

r = pd.concat([data, pd.Series(model.labels_,index =data.index)],axis =1)
r.columns = list(data.columns) + ['聚类类别']

【Python数据分析】数据挖掘建模——聚类分析

我们还可以用聚类结果可视化工具——TSNE将数据进行降维并在二维或者三维空间展示出来。

使用TSNE进行数据降维并展示聚类结果
from sklearn.manifold import TSNE
tsne = TSNE()
tsne.fit_transform(data_zs)  # 进行数据降维
tsne.embedding_可以获得降维后的数据
print('tsne.embedding_: \n', tsne.embedding_)
tsn = pd.DataFrame(tsne.embedding_, index=data.index)  # 转换数据格式

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

不同类别用不同颜色和样式绘图
color_style = ['r.', 'go', 'b*']
for i in range(k):
    d = tsn[r[u'聚类类别'] == i]
    # dataframe格式的数据经过切片之后可以通过d[i]来得到第i列数据
    plt.plot(d[0], d[1], color_style[i], label='聚类' + str(i+1))
plt.legend()
plt.show()

结果如下:

【Python数据分析】数据挖掘建模——聚类分析

【Python数据分析】数据挖掘建模——聚类分析

Original: https://blog.csdn.net/weixin_41168304/article/details/122747347
Author: 阿丢是丢心心
Title: 【Python数据分析】数据挖掘建模——聚类分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/549756/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球