Plotly+Pandas+Sklearn:实现用户聚类分群!

2023-11-03 16:30

本文主要是介绍Plotly+Pandas+Sklearn:实现用户聚类分群!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是辰哥~

很多读者问过我:有没有一些比较好的数据分析、数据挖掘的案例?答案是当然有,都在Kaggle上啦。

今天决定开始分享一篇关于聚类的案例,使用的是:超市用户细分数据集。为了方便大家练习,公众号后台回复 211202,即可领取本数据集~

ab3b2785452105751ecc121b0d948375.png

下面分享的是排名Top1的Notebook源码,欢迎参考学习~

一、导入库

# 数据处理
import numpy as np
import pandas as pd
# KMeans聚类
from sklearn.cluster import KMeans# 绘图库
import matplotlib.pyplot as plt
import seaborn as sns
import plotly as py
import plotly.express as px
import plotly.graph_objects as go
py.offline.init_notebook_mode(connected = True)

二、数据EDA

导入数据

首先我们导入数据集:

df62a67081f0716b4357d9ebd764357f.png

我们发现数据中存在5个属性字段,分别是顾客ID、性别、年龄、平均收入、消费等级

数据探索

1、数据形状shape

df.shape# 结果
(200,5)

总共是200行,5列的数据

2、缺失值情况

df.isnull().sum()# 结果
CustomerID                0
Gender                    0
Age                       0
Annual Income (k$)        0
Spending Score (1-100)    0
dtype: int64

可以看到:全部字段都是完整的,没有缺失值

3、数据类型

df.dtypes# 结果
CustomerID                 int64
Gender                    object
Age                        int64
Annual Income (k$)         int64
Spending Score (1-100)     int64
dtype: object

字段类型中,除了性别Gender是字符串,其他都是int64的数值型

4、描述统计信息

描述统计信息主要是查看数值型的数据的相关统计参数的值,比如:个数、中值、方差、最值、四分位数等

9f2dd34ba3e124f012897b01375c6af2.png

为了后续数据处理方便和展示,处理两点:

# 1、设置绘图风格
plt.style.use("fivethirtyeight")# 2、取出重点分析的3个字段
cols = df.columns[2:].tolist()
cols
# 结果
['Age', 'Annual Income (k$)', 'Spending Score (1-100)']

三、3个属性直方图

查看'Age'、 'Annual Income (k$)'、 'Spending Score (1-100)'的直方图,观察整体的分布情况:

# 绘图
plt.figure(1,figsize=(15,6))  # 画布大小
n = 0for col in cols:n += 1 # 子图位置plt.subplot(1,3,n)  # 子图plt.subplots_adjust(hspace=0.5,wspace=0.5)  # 调整宽高sns.distplot(df[col],bins=20)  # 绘制直方图plt.title(f'Distplot of {col}')  # 标题
plt.show()  # 显示图形
75230b5324f420c12e9509717a5b3041.png

四、性别因素

性别人数统计

查看本数据集中男女各有多少人。后续会考虑性别对整体的分析是否有影响。

fc32dde6aaf68b91594b1a41cde9d9c9.png

不同性别下的数据分布

sns.pairplot(df.drop(["CustomerID"],axis=1),hue="Gender",  # 分组字段aspect=1.5)
plt.show()
748c751e8ab12c17e3fc504738097605.png

通过上面的双变量分布图,我们观察到:性别因素对其他3个字段的影响不大

不同性别下年龄和平均收入的关系

plt.figure(1,figsize=(15,6))  # 绘图大小for gender in ["Male", "Female"]:plt.scatter(x="Age", y="Annual Income (k$)", # 指定两个分析的字段data=df[df["Gender"] == gender],  # 待分析的数据,某个gender下s=200,alpha=0.5,label=gender  # 散点的大小、透明度、标签分类)# 横纵轴、标题设置 
plt.xlabel("Age")  
plt.ylabel("Annual Income (k$)")
plt.title("Age vs Annual Income w.r.t Gender")
# 显示图形
plt.show()
503dced558d9c359368425e41eb7cf73.png

不同性别下平均收入和消费得分的关系

plt.figure(1,figsize=(15,6))for gender in ["Male", "Female"]:  # 解释参考上面plt.scatter(x = 'Annual Income (k$)',y = 'Spending Score (1-100)',data=df[df["Gender"] == gender],s=200,alpha=0.5,label=gender)plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)') 
plt.title("Annual Income vs Spending Score w.r.t Gender")
plt.show()
cdeae76821515f66cd4abe97bbf36caa.png

不同性别下的数据分布情况

通过小提琴图和分簇散点图来观察数据分布情况:

# 分簇散点图:Swarmplots
# 小提琴图:violinplotplt.figure(1,figsize=(15,7))
n = 0for col in cols:n += 1  # 子图顺序plt.subplot(1,3,n)  # 第n个子图plt.subplots_adjust(hspace=0.5,wspace=0.5)  # 调整宽高# 绘制某个col下面的两种图形,通过Gender进行分组显示sns.violinplot(x=col,y="Gender",data=df,palette = "vlag") sns.swarmplot(x=col, y="Gender",data=df)# 轴和标题设置plt.ylabel("Gender" if n == 1 else '')plt.title("Violinplots & Swarmplots" if n == 2 else '')plt.show()

结果如下:

  • 查看到不同Gender下不同字段的分布情况

  • 观察是否有离群点、异常值等

8e7118c45d6daaa22e7d31ec51148eb4.png

五、属性相关性分析

主要是观察属性两两之间的回归性:

cols = ['Age', 'Annual Income (k$)', 'Spending Score (1-100)']  # 这3个属性的相关性分析
plt.figure(1,figsize=(15,6))
n = 0for x in cols:for y in cols:n += 1  # 每循环一次n增加,子图移动一次plt.subplot(3,3,n)  # 3*3的矩阵,第n个图形plt.subplots_adjust(hspace=0.5, wspace=0.5)  # 子图间的宽、高参数sns.regplot(x=x,y=y,data=df,color="#AE213D")  # 绘图的数据和颜色plt.ylabel(y.split()[0] + " " + y.split()[1] if len(y.split()) > 1 else y)plt.show()

具体图形为:

f47beebd6caa9f73300c84795bbbf004.png

上图表明两点:

  • 主对角线是自身和自身的关系,成正比例

  • 其他图形是属性间的,有数据的散点分布,同时还有模拟的相关趋势图

六、两个属性间的聚类

在这里不具体讲解聚类算法的原理和过程,默认有基础

K值选取

我们通过绘制数据的ELBOW图来确定k值。资料大放送:

1、来自官网的参数解释:https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html

2、中文解释参考:https://blog.csdn.net/qq_34104548/article/details/79336584

df1 = df[['Age' , 'Spending Score (1-100)']].iloc[:,:].values  # 待拟合数据
inertia = []   # 空列表,用来存储到质心的距离之和for k in range(1,11):  # k值的选取默认是在1-10之间,经验值是5或者10algorithm = (KMeans(n_clusters=k,  # k值init="k-means++",  # 初始算法选择n_init=10,  # 随机运行次数max_iter=300,  # 最多迭代次数tol=0.0001,  # 容忍最小误差random_state=111,  # 随机种子algorithm="full"))  # 算法选择 auto、full、elkanalgorithm.fit(df1)  # 拟合数据inertia.append(algorithm.inertia_)  # 质心之和
43c907c29c38f5d47b2ced0ab198cdda.png

绘制出K值的变化和质心距离之和的关系:

plt.figure(1,figsize=(15,6))
plt.plot(np.arange(1,11), inertia, 'o')  # 数据绘制两次,标记不同
plt.plot(np.arange(1,11), inertia, '-', alpha=0.5)plt.xlabel("Choose of K")
plt.ylabel("Interia")
plt.show()
c6f096e5241adb88e39e2eda086b78eb.png

最终我们发现:k=4是比较合适的。于是采用k=4来进行数据的真实拟合过程

聚类建模

algorithm = (KMeans(n_clusters=4,  # k=4init="k-means++",n_init=10,max_iter=300,tol=0.0001,random_state=111,algorithm="elkan"))
algorithm.fit(df1)  # 模拟数据

数据进行了fit操作之后,我们得到了标签label和4个质心:

labels1 = algorithm.labels_  # 分类的结果(4类)
centroids1 = algorithm.cluster_centers_  # 最终质心的位置print("labels1:", labels1)
print("centroids1:", centroids1)
f8e7638c3f0b1a0f43be9accd8a41fcb.png

为了展示原始数据的分类效果,官网的案例是下面的操作,我个人觉得有些繁琐:

dfc92fb35c9ff9f115a98ec40886077a.png 10e5565982454d590a450dc00fc265f9.png

进行数据合并:

eba69f016ca068225ca288f9862dde53.png

展示分类效果:

plt.figure(1,figsize=(14,5))
plt.clf()Z = Z.reshape(xx.shape)plt.imshow(Z,interpolation="nearest",extent=(xx.min(),xx.max(),yy.min(),yy.max()),cmap = plt.cm.Pastel2, aspect = 'auto', origin='lower')plt.scatter(x="Age",y='Spending Score (1-100)', data = df , c = labels1 , s = 200)plt.scatter(x = centroids1[:,0], y =  centroids1[:,1], s = 300 , c = 'red', alpha = 0.5)plt.xlabel("Age")
plt.ylabel("Spending Score(1-100)")plt.show()
04dd254bc0440dcabbbda0550c9c965d.png

如果是我,怎么做?当然是使用Pandas+Plolty来完美解决:

a822b9079d42c1966a0e88dfef9651fd.png 737b8a73cc7752c9f95c361000336802.png

看下分类可视化的结果:

px.scatter(df3,x="Age",y="Spending Score(1-100)",color="Labels",color_continuous_scale="rainbow")
61aba842748b533e74a0ab72ec6f1809.png

上面的过程是根据Age和Spending Score(1-100)来进行聚类。在官网上基于同样的方法还进行了:Annual Income (k$)和Spending Score (1-100)字段的聚类。

效果如下,分成了5个类:

411919ce06515420dd4580a77d28bbc8.png

七、3个属性的聚类

根据Age 、 Annual Income 、 Spending Score来进行聚类,最终绘制成3维图形。

K值选取

方法都是相同的,只不过选取了3个字段(上面是某2个)

X3 = df[['Age' , 'Annual Income (k$)' ,'Spending Score (1-100)']].iloc[: , :].values  # 选取3个字段的数据
inertia = []
for n in range(1 , 11):algorithm = (KMeans(n_clusters = n,init='k-means++', n_init = 10 ,max_iter=300, tol=0.0001,  random_state= 111  , algorithm='elkan') )algorithm.fit(X3)   # 拟合数据inertia.append(algorithm.inertia_)

绘制肘图确定k:

plt.figure(1 , figsize = (15 ,6))
plt.plot(np.arange(1 , 11) , inertia , 'o')
plt.plot(np.arange(1 , 11) , inertia , '-' , alpha = 0.5)
plt.xlabel('Number of Clusters') , plt.ylabel('Inertia')
plt.show()
24bfafb59dc41e4cc025be5731dde20a.png

我们最终选取k=6来聚类

建模拟合

algorithm = (KMeans(n_clusters=6,  # 确定的k值init="k-means++",n_init=10,max_iter=300,tol=0.0001,random_state=111,algorithm="elkan"))
algorithm.fit(df2)labels2 = algorithm.labels_
centroids2 = algorithm.cluster_centers_print(labels2)
print(centroids2)

得到标签和质心:

labels2 = algorithm.labels_
centroids2 = algorithm.cluster_centers_

绘图

3维的聚类我们最终选择plotly来展示:

df["labels2"] = labels2trace = go.Scatter3d(x=df["Age"],y= df['Spending Score (1-100)'],z= df['Annual Income (k$)'],mode='markers',marker = dict(color=df["labels2"],size=20,line=dict(color=df["labels2"],width=12),opacity=0.8)
)data = [trace]
layout = go.Layout(margin=dict(l=0,r=0,b=0,t=0),title="six Clusters",scene=dict(xaxis=dict(title="Age"),yaxis = dict(title  = 'Spending Score'),zaxis = dict(title  = 'Annual Income'))
)fig = go.Figure(data=data,layout=layout)fig.show()

下面就是最终的聚类效果:

1ed4e0bc98d369384d56f8b2df709cf5.png ebf1c1a67ededf75b320af91d4e02858.png

公众号后台回复 211202

即可领取本数据集~

fbbdc41019897dd3d935e23cd5c49161.png

干货推荐

e391b877bad487bd8b9d4550b091dc02.png

80fbff0e45cd15ac32156a11f0aace42.png

利用可视化神器 Plotly 绘制酷炫图表


c456cf1205318c051a6d9bc427d4285d.png

5 分钟,使用内网穿透快速实现远程桌面


e2ec9ace2d8a93180272cf1aa7a74e95.png

利用Selenium实现网站自动签到

这篇关于Plotly+Pandas+Sklearn:实现用户聚类分群!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/339455

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、