重生之从零开始的神经网络算法学习之路——第三篇 深入Scikit-learn(聚类问题与无监督学习)
朱元璋在建立明朝后,不仅需要管理已知的州县,更要探索未知的疆域,发现潜在的威胁与机遇。而今重生后的你,在掌握了分类问题的基本方法后,正面临着机器学习中另一个重要领域——无监督学习与聚类分析。
前情回顾
在第二篇中,你成功使用随机森林算法对鸢尾花进行了分类,掌握了分类问题的基本流程和评估方法。此刻,你站在新的起点上,准备探索机器学习中另一重要领域——无监督学习,特别是聚类分析。
聚类问题:从有监督到无监督的思维转变
与有监督学习不同,无监督学习没有预先标记的目标变量。就像当年朱元璋需要探索未知疆域并划分行政区域,而不是管理已知的州县。聚类分析的目标是发现数据中隐藏的自然分组,而不是预测已知的类别标签。
为何选择K均值算法和顾客数据集?
K均值是最经典且广泛使用的聚类算法之一,它通过迭代优化将数据划分到K个簇中,使每个数据点都属于离它最近的簇中心。顾客购物中心数据集包含了真实世界的消费者行为数据,非常适合用于市场细分和顾客分群的实际应用。
实验三:K均值聚类进行顾客分群
1. 环境准备
确保已安装必要的库:
pip install scikit-learn matplotlib numpy pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
2. 代码实现
代码可以直接拉取,远程仓库代码地址:https://gitee.com/cmx1998/Scikit-Learning.git
- 具体文件为Scikit-learn-3.py
3. 代码解析
这段代码实现了以下功能:
- 数据加载:从CSV文件加载顾客购物中心数据集
- 特征选择:选择年龄、年收入和消费得分三个特征
- 数据标准化:使用StandardScaler对特征进行标准化
- 确定最佳K值:通过肘部法则和轮廓系数确定最佳聚类数量
- 模型训练:使用K均值算法进行聚类分析
- 可视化输出:生成3D散点图和2D散点图展示聚类结果
- 导入所需模块
from sklearn.preprocessing import StandardScaler # 导入数据标准化函数
from sklearn.cluster import KMeans # 导入K均值聚类算法
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
import pandas as pd # 新增pandas库
import numpy as np
import os
- 1、加载数据集
try:
# 尝试从本地加载数据集
df = pd.read_csv('Scikit-Learning/Mall_Customers.csv')
print("成功加载本地数据集 'Mall_Customers.csv'")
except FileNotFoundError:
print("本地数据集未找到,请确保 'Mall_Customers.csv' 文件存在于Scikit-Learning目录")
print("可以从以下地址下载: https://www.kaggle.com/vjchoudhary7/customer-segmentation-tutorial-in-python")
exit()
- 2、选择特征
features = df[['Age', 'Annual Income (k$)', 'Spending Score (1-100)']]
- 3、数据标准化
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
- 4、使用肘部法则确定最佳K值
sse = [] # 保存每个K值的SSE
silhouette_scores = [] # 保存每个K值的轮廓系数
k_range = range(2, 11)
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(features_scaled)
sse.append(kmeans.inertia_) # 获取SSE
silhouette_scores.append(silhouette_score(features_scaled, kmeans.labels_))
- 5、使用最佳K值训练K均值模型
best_k = k_range[np.argmax(silhouette_scores)]
kmeans = KMeans(n_clusters=best_k, random_state=42, n_init=10)
kmeans.fit(features_scaled)
cluster_labels = kmeans.predict(features_scaled)
df['Cluster'] = cluster_labels
- 6、可视化聚类结果
# 3D散点图
fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')
for i in range(best_k):
cluster_data = df[df['Cluster'] == i]
ax.scatter(
cluster_data['Age'],
cluster_data['Annual Income (k$)'],
cluster_data['Spending Score (1-100)'],
s=50, c=colors[i], label=f'簇 {i}', alpha=0.7
)
4. 运行结果
运行代码后,你将会看到类似以下的输出:
============================================================
实验三:K均值聚类进行顾客分群
============================================================
正在加载数据集...
成功加载本地数据集 'Mall_Customers.csv'
数据集形状: (200, 5)
数据集前5行:
CustomerID Genre Age Annual Income (k$) Spending Score (1-100)
0 1 Male 19 15 39
1 2 Male 21 15 81
2 3 Female 20 16 6
3 4 Female 23 16 77
4 5 Female 31 17 40
选择特征: 'Age', 'Annual Income (k$)', 'Spending Score (1-100)'
特征数据形状: (200, 3)
正在进行数据标准化...
标准化完成!
使用肘部法则确定最佳K值...
肘部法则图已保存为 'img\customer_elbow_method.png'
根据轮廓系数选择的最佳K值为: 6 (轮廓系数 = 0.4284)
使用最佳K值(6)训练K均值模型...
聚类完成!
各簇的样本数量:
簇 0: 45 个样本
簇 1: 39 个样本
簇 2: 33 个样本
簇 3: 39 个样本
簇 4: 23 个样本
簇 5: 21 个样本
绘制3D散点图...
3D散点图已保存为 'img\customer_clusters_3d.png'
绘制2D散点图分析...
2D散点图已保存为 'img\customer_clusters_2d.png'
各簇的中心点 (原始尺度):
Age Annual Income (k$) Spending Score (1-100) Cluster
0 56.333333 54.266667 49.066667 0
1 26.794872 57.102564 48.128205 1
2 41.939394 88.939394 16.969697 2
3 32.692308 86.538462 82.128205 3
4 25.000000 25.260870 77.608696 4
5 45.523810 26.285714 19.380952 5
聚类分析完成!
============================================================
实验三顺利完成!
============================================================
同时,程序还会生成肘部法则图、3D散点图和2D散点图的可视化结果。
深入理解
1. K均值算法原理
K均值是一种基于质心的聚类算法,通过迭代过程将数据点分配到K个簇中。算法的核心步骤包括:
- 初始化:随机选择K个点作为初始质心
- 分配:将每个数据点分配到最近的质心所在的簇
- 更新:重新计算每个簇的质心(即该簇所有点的平均值)
- 迭代:重复分配和更新步骤,直到质心不再显著变化或达到最大迭代次数
2. 评估指标解读
-
SSE(Sum of Squared Errors):簇内平方和,衡量每个数据点与其所属簇质心之间的平方距离之和。SSE越小,表示簇内数据点越紧密。肘部法则通过观察SSE随K值变化的拐点来确定最佳聚类数。
-
轮廓系数(Silhouette Score):衡量聚类质量的指标,取值范围为[-1, 1]。值越接近1表示聚类效果越好,样本与同簇其他样本更相似;值越接近-1表示样本可能被分配到了错误的簇。
结果分析:从运行结果可以看出,最佳K值为6,轮廓系数为0.4284。这表明数据被分成了6个相对合理的顾客群体,虽然聚类效果不是非常理想(轮廓系数大于0.5通常被认为是较好的聚类),但对于真实世界的数据来说,这是一个合理的结果。
3. 聚类结果分析
通过对各簇中心点的分析,我们可以对6个顾客群体进行初步描述:
- 簇0(45人):中年顾客(平均56岁),中等收入(54k$),中等消费水平(49分)
- 簇1(39人):年轻顾客(平均27岁),中等偏高收入(57k$),中等消费水平(48分)
- 簇2(33人):中年顾客(平均42岁),高收入(89k$),低消费水平(17分)→ 可能是节俭的高收入人群
- 簇3(39人):青年顾客(平均33岁),高收入(87k$),高消费水平(82分)→ 可能是富裕的年轻专业人士
- 簇4(23人):年轻顾客(平均25岁),低收入(25k$),高消费水平(78分)→ 可能是追求生活品质但收入有限的年轻人
- 簇5(21人):中年顾客(平均46岁),低收入(26k$),低消费水平(19分)→ 可能是经济压力较大的中年人
这些分群结果可以为商场制定差异化营销策略提供数据支持,例如针对不同群体推出不同的促销活动或会员计划。
无监督学习:探索数据的内在结构
1. 为什么需要无监督学习?
在有监督学习中,我们依赖标注数据来训练模型。但在许多实际场景中,获取标注数据成本高昂甚至不可行。无监督学习能够帮助我们探索数据的内在结构,发现隐藏的模式和关系,就像朱元璋需要探索未知疆域并划分行政区域。
2. 聚类分析的应用场景
聚类分析在各个领域都有广泛应用:
- 市场细分:将顾客分为不同的群体,制定针对性营销策略
- 社交网络分析:发现社区结构和关键节点
- 图像分割:将图像分成具有相似特征的区域
- 异常检测:识别与大多数数据显著不同的异常点
3. 聚类算法的选择
除了K均值,还有许多其他聚类算法:
- 层次聚类:通过构建树状结构展示数据的层次分组
- DBSCAN:基于密度的聚类算法,能发现任意形状的簇并识别噪声点
- 高斯混合模型:假设数据来自多个高斯分布的混合,使用EM算法进行参数估计
遇到的挑战与解决
在完成这个聚类项目的过程中,你遇到了一些新挑战:
- 确定最佳K值:通过肘部法则和轮廓系数相结合的方法,找到了相对合理的聚类数量
- 数据标准化:理解了为什么聚类前需要对数据进行标准化,以及不同标准化方法的影响
- 结果解释:学会了如何解读聚类中心,并将数值结果转化为有业务意义的顾客分群描述
- 可视化挑战:掌握了如何通过3D散点图和2D散点图展示高维聚类结果
结语
完成了顾客分群项目后,你不仅掌握了K均值这一经典聚类算法,还深入理解了无监督学习的基本概念和应用方法。这就像朱元璋在探索未知疆域后,不仅发现了新的土地,还建立了有效的行政管理体系。
值得注意的是,聚类分析的结果解释需要结合领域知识。算法可以帮助我们发现数据中的分组,但理解这些分组的意义需要人类的智慧和经验。这个实验的价值在于让你熟悉无监督学习的基本流程和方法,为处理更复杂的现实问题打下基础。
机器学习之路如同探索未知世界,需要不断尝试新的方法和技术。无监督学习的大门已经向你敞开,前方还有更多有趣的模式和关系等待你去发现。
下集预告:第四篇将带你探索降维技术与主成分分析(PCA),学习如何在高维数据中提取最重要特征,为后续的复杂模型训练做好准备。
浙公网安备 33010602011771号