打响Kaggle第一枪
很多读者问过我:有没有一些比较好的数据分析、数据挖掘的案例?答案是当然有,都在Kaggle上啦。
只是你要花时间去学习,甚至是去打比赛。Peter本身是没有参赛经验,但是也会经常去逛Kaggle,学习赛题中大佬们的解题思路和方法。
为了记录大佬们的好方法,更是为了提升自己,Peter决定开启一个专栏:Kaggle案例分享。
后面会不定期更新案例分析,思路都来自网上的大佬们,尤其是Top1的分享,Peter主要是负责:整理思路、学习技术。
今天决定开始分享一篇关于聚类的案例,使用的是:超市用户细分数据集,官网地址请移步:超市
为了方便大家练习,公众号后台回复超市,即可领取本数据集~
下面分享的是排名Top1的Notebook源码,欢迎参考学习~
导入库
1 | # 数据处理 |
数据EDA
导入数据
首先我们导入数据集:
我们发现数据中存在5个属性字段,分别是顾客ID、性别、年龄、平均收入、消费等级
数据探索
1、数据形状shape
1 | df.shape |
总共是200行,5列的数据
2、缺失值情况
1 | df.isnull().sum() |
可以看到:全部字段都是完整的,没有缺失值
3、数据类型
1 | df.dtypes |
字段类型中,除了性别Gender是字符串,其他都是int64的数值型
4、描述统计信息
描述统计信息主要是查看数值型的数据的相关统计参数的值,比如:个数、中值、方差、最值、四分位数等
为了后续数据处理方便和展示,处理两点:
1 | # 1、设置绘图风格 |
3个属性直方图
查看’Age’、 ‘Annual Income (k$)’、 'Spending Score (1-100)'的直方图,观察整体的分布情况:
1 | # 绘图 |
性别因素
性别人数统计
查看本数据集中男女各有多少人。后续会考虑性别对整体的分析是否有影响。
不同性别下的数据分布
1 | sns.pairplot(df.drop(["CustomerID"],axis=1), |
通过上面的双变量分布图,我们观察到:性别因素对其他3个字段的影响不大
不同性别下年龄和平均收入的关系
1 | plt.figure(1,figsize=(15,6)) # 绘图大小 |
不同性别下平均收入和消费得分的关系
1 | plt.figure(1,figsize=(15,6)) |
不同性别下的数据分布情况
通过小提琴图和分簇散点图来观察数据分布情况:
1 | # 分簇散点图:Swarmplots |
结果如下:
- 查看到不同Gender下不同字段的分布情况
- 观察是否有离群点、异常值等
属性相关性分析
主要是观察属性两两之间的回归性:
1 | cols = ['Age', 'Annual Income (k$)', 'Spending Score (1-100)'] # 这3个属性的相关性分析 |
1 | plt.figure(1,figsize=(15,6)) |
具体图形为:
上图表明两点:
- 主对角线是自身和自身的关系,成正比例
- 其他图形是属性间的,有数据的散点分布,同时还有模拟的相关趋势图
两个属性间的聚类
在这里不具体讲解聚类算法的原理和过程,默认有基础
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
1 | df1 = df[['Age' , 'Spending Score (1-100)']].iloc[:,:].values # 待拟合数据 |
绘制出K值的变化和质心距离之和的关系:
1 | plt.figure(1,figsize=(15,6)) |
最终我们发现:k=4是比较合适的。于是采用k=4来进行数据的真实拟合过程
聚类建模
1 | algorithm = (KMeans(n_clusters=4, # k=4 |
数据进行了fit操作之后,我们得到了标签label和4个质心:
1 | labels1 = algorithm.labels_ # 分类的结果(4类) |
为了展示原始数据的分类效果,官网的案例是下面的操作,我个人觉得有些繁琐:
进行数据合并:
展示分类效果:
1 | plt.figure(1,figsize=(14,5)) |
如果是我,怎么做?当然是使用Pandas+Plolty来完美解决:
看下分类可视化的结果:
1 | px.scatter(df3,x="Age",y="Spending Score(1-100)",color="Labels",color_continuous_scale="rainbow") |
上面的过程是根据Age和Spending Score(1-100)来进行聚类。在官网上基于同样的方法还进行了:Annual Income (k$)和Spending Score (1-100)字段的聚类。
效果如下,分成了5个类:
3个属性的聚类
根据Age 、 Annual Income 、 Spending Score来进行聚类,最终绘制成3维图形。
K值选取
方法都是相同的,只不过选取了3个字段(上面是某2个)
1 | X3 = df[['Age' , 'Annual Income (k$)' ,'Spending Score (1-100)']].iloc[: , :].values # 选取3个字段的数据 |
绘制肘图确定k:
1 | plt.figure(1 , figsize = (15 ,6)) |
我们最终选取k=6来聚类
建模拟合
1 | algorithm = (KMeans(n_clusters=6, # 确定的k值 |
得到标签和质心:
1 | labels2 = algorithm.labels_ |
绘图
3维的聚类我们最终选择plotly来展示:
1 | df["labels2"] = labels2 |
下面就是最终的聚类效果: