项目四教学文档:商场客户聚类与分群画像 ------ 无监督学习全流程
https://gitee.com/ghaweiuptgb/machine-learning-AI.git (代码包)
使用说明 :本文档是项目四的完整教学记录。每完成一个步骤,我会把该步骤的详细教学过程写入对应章节。
配套文件:
- 总体规划见
../机器学习实战学习路线.md- 你的个人笔记写在
README.md- 代码写在
src/train.py代码规范 :逐行注释 + 图表中文(见根目录
.cursor/rules/)讲解规范 :详细讲解 + 新名词必解释 + Mermaid 图解 + 每步提供动手任务与验收标准参考答案
目录
| 步骤 | 标题 | 状态 |
|---|---|---|
| [步骤 1](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 加载与探索 | ✅ 已完成教学 |
| [步骤 2](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 特征缩放 | ✅ 已完成教学 |
| [步骤 3](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | K-Means 初探(K=3) | ✅ 已完成教学 |
| [步骤 4](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 肘部法则选 K | ✅ 已完成教学 |
| [步骤 5](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 轮廓系数验证 | ✅ 已完成教学 |
| [步骤 6](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | PCA 二维可视化 | ✅ 已完成教学 |
| [步骤 7](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 客群画像命名 | ✅ 已完成教学 |
| [步骤 8](#步骤 标题 状态 步骤 1 加载与探索 ✅ 已完成教学 步骤 2 特征缩放 ✅ 已完成教学 步骤 3 K-Means 初探(K=3) ✅ 已完成教学 步骤 4 肘部法则选 K ✅ 已完成教学 步骤 5 轮廓系数验证 ✅ 已完成教学 步骤 6 PCA 二维可视化 ✅ 已完成教学 步骤 7 客群画像命名 ✅ 已完成教学 步骤 8 总结与局限 ✅ 已完成教学) | 总结与局限 | ✅ 已完成教学 |
步骤 1:加载与探索
状态 :✅ 已完成教学(报告见
reports/step1_data_inspection.txt)
1.1 本步目标
- 创建
project_04_clustering/目录结构 - 加载 Mall Customer Segmentation 数据集
- 剔除 CustomerID(无业务含义的编号)
- 确定聚类特征:Age、Annual Income (k$)、Spending Score (1-100)
- 初步 EDA:分布、缺失值、量纲差异
1.2 这一步在解决什么问题?
项目一~三都是有监督学习 (有标签 y:房价、欺诈、流失)。项目四进入无监督学习:
- 没有「标准答案」标签,要靠算法自己发现「谁和谁像」
- 业务目标:把客户分成几群,每群写画像,指导营销
在跑 K-Means 之前,必须先弄清:有多少客户、用哪些列算「距离」、各列数值范围差多大。
1.3 本步在整体流程中的位置
#mermaid-svg-B0IGiQeN4Q5aRehP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-B0IGiQeN4Q5aRehP .error-icon{fill:#552222;}#mermaid-svg-B0IGiQeN4Q5aRehP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-B0IGiQeN4Q5aRehP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-B0IGiQeN4Q5aRehP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-B0IGiQeN4Q5aRehP .marker.cross{stroke:#333333;}#mermaid-svg-B0IGiQeN4Q5aRehP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-B0IGiQeN4Q5aRehP p{margin:0;}#mermaid-svg-B0IGiQeN4Q5aRehP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster-label text{fill:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster-label span{color:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster-label span p{background-color:transparent;}#mermaid-svg-B0IGiQeN4Q5aRehP .label text,#mermaid-svg-B0IGiQeN4Q5aRehP span{fill:#333;color:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP .node rect,#mermaid-svg-B0IGiQeN4Q5aRehP .node circle,#mermaid-svg-B0IGiQeN4Q5aRehP .node ellipse,#mermaid-svg-B0IGiQeN4Q5aRehP .node polygon,#mermaid-svg-B0IGiQeN4Q5aRehP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-B0IGiQeN4Q5aRehP .rough-node .label text,#mermaid-svg-B0IGiQeN4Q5aRehP .node .label text,#mermaid-svg-B0IGiQeN4Q5aRehP .image-shape .label,#mermaid-svg-B0IGiQeN4Q5aRehP .icon-shape .label{text-anchor:middle;}#mermaid-svg-B0IGiQeN4Q5aRehP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-B0IGiQeN4Q5aRehP .rough-node .label,#mermaid-svg-B0IGiQeN4Q5aRehP .node .label,#mermaid-svg-B0IGiQeN4Q5aRehP .image-shape .label,#mermaid-svg-B0IGiQeN4Q5aRehP .icon-shape .label{text-align:center;}#mermaid-svg-B0IGiQeN4Q5aRehP .node.clickable{cursor:pointer;}#mermaid-svg-B0IGiQeN4Q5aRehP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-B0IGiQeN4Q5aRehP .arrowheadPath{fill:#333333;}#mermaid-svg-B0IGiQeN4Q5aRehP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-B0IGiQeN4Q5aRehP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-B0IGiQeN4Q5aRehP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B0IGiQeN4Q5aRehP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-B0IGiQeN4Q5aRehP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B0IGiQeN4Q5aRehP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster text{fill:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP .cluster span{color:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-B0IGiQeN4Q5aRehP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-B0IGiQeN4Q5aRehP rect.text{fill:none;stroke-width:0;}#mermaid-svg-B0IGiQeN4Q5aRehP .icon-shape,#mermaid-svg-B0IGiQeN4Q5aRehP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-B0IGiQeN4Q5aRehP .icon-shape p,#mermaid-svg-B0IGiQeN4Q5aRehP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-B0IGiQeN4Q5aRehP .icon-shape .label rect,#mermaid-svg-B0IGiQeN4Q5aRehP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-B0IGiQeN4Q5aRehP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-B0IGiQeN4Q5aRehP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-B0IGiQeN4Q5aRehP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 步骤1 加载探索
步骤2 标准化
步骤3~5 选K与聚类
步骤6 PCA可视化
步骤7 客群画像
步骤8 总结
1.4 名词解释(本步首次出现)
| 名词 | 是什么 | 为什么需要 | 在本项目中 | 易混淆 |
|---|---|---|---|---|
| 无监督学习 | 没有标签 y,从 X 中发现结构 | 客户分群没有「真值」 | 本项目的核心范式 | 不是分类/回归 |
| 聚类 Clustering | 把相似样本分到同一组 | 营销需要「一类人一类策略」 | 后续用 K-Means | 不是分类(无预设类别) |
| CustomerID | 客户编号 1~200 | 仅标识,与行为无关 | 不参与聚类 | 不是特征 |
| Spending Score | 商场根据行为打的 1~100 分 | 反映消费活跃度 | 聚类三维之一 | 不是真实消费金额 |
| Annual Income (k$) | 年收入(千美元) | 购买力指标 | 聚类三维之一 | 单位是 k$,不是美元 |
| 特征矩阵 X | 仅含数值特征的表格 | K-Means 输入 | shape (200, 3) | 不含 Gender(本步) |
1.5 项目目录结构
project_04_clustering/
├── 教学文档.md # 详细教学(本文件)
├── README.md # 你的学习笔记
├── data/
│ └── Mall_Customers.csv
├── src/
│ └── train.py # 主脚本
├── reports/figures/ # 图表输出
└── outputs/ # 带 Cluster 列的结果 CSV(步骤 8)
1.6 任务清单
- 创建目录结构
- 下载/加载 CSV
- 检查 CustomerID、Gender、缺失值
- 构建聚类特征矩阵
X(3 列) - 保存 3 张 EDA 图 +
step1_data_inspection.txt
1.7 运行本步
powershell
cd "d:\JavaCode\机器学习\project_04_clustering"
python src/train.py
1.8 数据集概览(你的环境)
关于「只有 200 条是不是太少?」
不是。 这是 Kaggle 上经典的 Mall Customer Segmentation 教学数据集,官方全量就是 200 行 × 5 列 (作者说明:专为学习客户分群/市场篮子分析而创建的小数据集)。
本地
Mall_Customers.csv已与 GitHub 官方镜像 逐字节一致 (MD5:270beafe...),并非我删减或手写模拟数据。若需更大规模聚类练习,可在完成本项目后换 Retail / 电商 RFM 数据集;本路线步骤 4 故意用小集便于理解 K-Means、肘部法则与 PCA。
| 项目 | 数值 |
|---|---|
| 总行数 | 200 |
| 总列数 | 5 |
| 缺失值 | 0 |
| Female / Male | 112 / 88(56% / 44%) |
| 聚类特征 X | (200, 3) |
数值列 describe 摘要:
| 统计量 | Age | Annual Income (k$) | Spending Score |
|---|---|---|---|
| mean | 38.85 | 60.56 | 50.20 |
| min~max | 18~70 | 15~137 | 1~99 |
与项目三对比 :只有 200 行、无标签;Gender 是类别列,本步聚类暂不使用(步骤 8 进阶可对比含 Gender 编码)。
1.9 为什么剔除 CustomerID?Gender 本步不用?
#mermaid-svg-aoOQwEr73EL8oHP4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aoOQwEr73EL8oHP4 .error-icon{fill:#552222;}#mermaid-svg-aoOQwEr73EL8oHP4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aoOQwEr73EL8oHP4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aoOQwEr73EL8oHP4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aoOQwEr73EL8oHP4 .marker.cross{stroke:#333333;}#mermaid-svg-aoOQwEr73EL8oHP4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aoOQwEr73EL8oHP4 p{margin:0;}#mermaid-svg-aoOQwEr73EL8oHP4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster-label text{fill:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster-label span{color:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster-label span p{background-color:transparent;}#mermaid-svg-aoOQwEr73EL8oHP4 .label text,#mermaid-svg-aoOQwEr73EL8oHP4 span{fill:#333;color:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 .node rect,#mermaid-svg-aoOQwEr73EL8oHP4 .node circle,#mermaid-svg-aoOQwEr73EL8oHP4 .node ellipse,#mermaid-svg-aoOQwEr73EL8oHP4 .node polygon,#mermaid-svg-aoOQwEr73EL8oHP4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aoOQwEr73EL8oHP4 .rough-node .label text,#mermaid-svg-aoOQwEr73EL8oHP4 .node .label text,#mermaid-svg-aoOQwEr73EL8oHP4 .image-shape .label,#mermaid-svg-aoOQwEr73EL8oHP4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-aoOQwEr73EL8oHP4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aoOQwEr73EL8oHP4 .rough-node .label,#mermaid-svg-aoOQwEr73EL8oHP4 .node .label,#mermaid-svg-aoOQwEr73EL8oHP4 .image-shape .label,#mermaid-svg-aoOQwEr73EL8oHP4 .icon-shape .label{text-align:center;}#mermaid-svg-aoOQwEr73EL8oHP4 .node.clickable{cursor:pointer;}#mermaid-svg-aoOQwEr73EL8oHP4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aoOQwEr73EL8oHP4 .arrowheadPath{fill:#333333;}#mermaid-svg-aoOQwEr73EL8oHP4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aoOQwEr73EL8oHP4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aoOQwEr73EL8oHP4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aoOQwEr73EL8oHP4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aoOQwEr73EL8oHP4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aoOQwEr73EL8oHP4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster text{fill:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 .cluster span{color:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aoOQwEr73EL8oHP4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aoOQwEr73EL8oHP4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-aoOQwEr73EL8oHP4 .icon-shape,#mermaid-svg-aoOQwEr73EL8oHP4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aoOQwEr73EL8oHP4 .icon-shape p,#mermaid-svg-aoOQwEr73EL8oHP4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aoOQwEr73EL8oHP4 .icon-shape .label rect,#mermaid-svg-aoOQwEr73EL8oHP4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aoOQwEr73EL8oHP4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aoOQwEr73EL8oHP4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aoOQwEr73EL8oHP4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 聚类特征 X
不参与聚类
CustomerID 唯一编号
Gender 本步不用
Age
Annual Income
Spending Score
与消费行为无因果
需编码;男女比例接近;步骤8可对比
K-Means 欧氏距离
1.10 量纲差异(步骤 2 预告)
Income 最大 137 ,Spending 最大 99 ,Age 最大 70 ------若不标准化,距离会被 Income 主导。步骤 2 必须 StandardScaler。
1.11 核心代码解读
(1)load_data() ------ 本地优先 + 多镜像下载
python
if DATA_PATH.exists():
return pd.read_csv(DATA_PATH)
_download_data(DATA_DOWNLOAD_URLS, DATA_PATH)
return pd.read_csv(DATA_PATH)
(2)build_cluster_feature_matrix() ------ 构建 X
python
X = df[CLUSTER_FEATURE_COLS].copy()
# ['Age', 'Annual Income (k$)', 'Spending Score (1-100)']
1.12 输出文件
| 文件 | 说明 |
|---|---|
reports/step1_data_inspection.txt |
数据检查报告 |
reports/figures/01_客户年龄分布.png |
年龄直方图 |
reports/figures/02_年收入与消费得分散点图.png |
Income vs Spending |
reports/figures/03_客户性别分布.png |
性别条形图 |
1.13 动手任务
任务 A :运行 python src/train.py,确认 200 行、5 列
任务 B :在 Python 中执行 df['Gender'].value_counts(),男女各多少人?
任务 C :执行 X = df[['Age','Annual Income (k$)','Spending Score (1-100)']],打印 X.shape
任务 D:在 README 步骤 1 写下日期和一句话:无监督与有监督有何不同?
1.14 验收标准
- 能说出本数据集无标签、属于无监督学习
- 能列出聚类用的 3 个特征列名
- 能解释 CustomerID 为何不参与聚类
- 知道 Income 量纲大,步骤 2 需标准化
1.15 动手任务与验收标准参考答案
以下为教学标准答案,便于自学对照;
README.md学习记录仍建议用自己的话写。
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | 运行后打印 200 行 × 5 列 ,缺失值 0。 |
| B | Female 112 人(56%) ,Male 88 人(44%)。 |
| C | X.shape 为 (200, 3)。 |
| D | 示例:「无监督没有标签 y,要靠算法自己分组;有监督像项目三有 Churn 0/1。」 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| 无监督 | 无 Churn 之类标签;目标是发现客户群组结构。 |
| 3 个特征 | Age 、Annual Income (k$) 、Spending Score (1-100)。 |
| CustomerID | 唯一编号 1~200,与消费行为无因果关系,不参与距离计算。 |
| 量纲 | Income 15~137,Age 18~70;不缩放时 Income 主导欧氏距离,步骤 2 用 StandardScaler。 |
1.16 常见问题
Q:为什么只有 200 条?是不是你写的假数据?
A:不是。 Kaggle 官方 Mall_Customers.csv 全量就是 200 条 。本地文件与 GitHub 官方源 MD5 完全一致。删除 data/Mall_Customers.csv 后运行 train.py 可自动重新下载。
Q:数据从哪下载?
A:运行 train.py 自动从 GitHub 下载。也可从 Kaggle Mall Segmentation 手动下载 Mall_Customers.csv。
Q:为什么不用 Gender?
A:K-Means 要数值特征;Gender 需 One-Hot。本数据集男女比例接近,三维 Age/Income/Spending 已能分出典型群组;步骤 8 可对比 4 维特征。
Q:Spending Score 是什么?
A:数据集自带的 1~100 行为评分,由商场根据客户消费行为给出,越高表示越「肯花钱」。
1.17 本步小结
| 要点 | 内容 |
|---|---|
| 数据规模 | 200 行 × 5 列,无缺失 |
| 聚类 X | 3 列数值特征,shape (200, 3) |
| 剔除 | CustomerID、Gender(本步) |
| 关键发现 | Income 量纲最大,必须标准化 |
| 下一步 | StandardScaler(步骤 2) |
1.18 学习记录(请你填写)
- 完成日期:
- 动手任务完成情况:任务 A / B / C / D
- 我对无监督学习的初印象:
- 疑问(如有):
步骤 2:特征缩放
状态 :✅ 已完成教学(报告见
reports/step2_feature_scaling.txt)
2.1 本步目标
- 理解 K-Means 基于欧氏距离,对量纲敏感
- 用 StandardScaler 将 Age、Income、Spending 缩放到均值≈0、标准差≈1
- 对比缩放前后标准差,验证 Income 不再主导距离
2.2 这一步在解决什么问题?
步骤 1 的 X 三列量纲不同:
| 特征 | 标准差(缩放前) |
|---|---|
| Age | 13.97 |
| Annual Income | 26.26(最大) |
| Spending Score | 25.82 |
若不缩放,两个客户 Income 差 10 点对距离的贡献,相当于 Age 差 10 点------但 Income 的 10 在业务上只是「10 k$」,Age 的 10 是「10 岁」,不应同等权重 。StandardScaler 让三列在同一尺度上比距离。
2.3 名词解释
| 名词 | 大白话 | 本步 |
|---|---|---|
| 欧氏距离 | 多维空间直线距离 | K-Means 分配客户到最近质心 |
| StandardScaler | 减均值、除标准差 | fit_transform(X) |
| Z-score | 标准化后的值 | 均值≈0,std≈1 |
| 量纲 | 数值的单位与范围 | Income 15~137 vs Age 18~70 |
2.4 缩放流程(Mermaid)
#mermaid-svg-DgLMdltR01LHk7I7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DgLMdltR01LHk7I7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DgLMdltR01LHk7I7 .error-icon{fill:#552222;}#mermaid-svg-DgLMdltR01LHk7I7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DgLMdltR01LHk7I7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DgLMdltR01LHk7I7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DgLMdltR01LHk7I7 .marker.cross{stroke:#333333;}#mermaid-svg-DgLMdltR01LHk7I7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DgLMdltR01LHk7I7 p{margin:0;}#mermaid-svg-DgLMdltR01LHk7I7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DgLMdltR01LHk7I7 .cluster-label text{fill:#333;}#mermaid-svg-DgLMdltR01LHk7I7 .cluster-label span{color:#333;}#mermaid-svg-DgLMdltR01LHk7I7 .cluster-label span p{background-color:transparent;}#mermaid-svg-DgLMdltR01LHk7I7 .label text,#mermaid-svg-DgLMdltR01LHk7I7 span{fill:#333;color:#333;}#mermaid-svg-DgLMdltR01LHk7I7 .node rect,#mermaid-svg-DgLMdltR01LHk7I7 .node circle,#mermaid-svg-DgLMdltR01LHk7I7 .node ellipse,#mermaid-svg-DgLMdltR01LHk7I7 .node polygon,#mermaid-svg-DgLMdltR01LHk7I7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DgLMdltR01LHk7I7 .rough-node .label text,#mermaid-svg-DgLMdltR01LHk7I7 .node .label text,#mermaid-svg-DgLMdltR01LHk7I7 .image-shape .label,#mermaid-svg-DgLMdltR01LHk7I7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-DgLMdltR01LHk7I7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DgLMdltR01LHk7I7 .rough-node .label,#mermaid-svg-DgLMdltR01LHk7I7 .node .label,#mermaid-svg-DgLMdltR01LHk7I7 .image-shape .label,#mermaid-svg-DgLMdltR01LHk7I7 .icon-shape .label{text-align:center;}#mermaid-svg-DgLMdltR01LHk7I7 .node.clickable{cursor:pointer;}#mermaid-svg-DgLMdltR01LHk7I7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DgLMdltR01LHk7I7 .arrowheadPath{fill:#333333;}#mermaid-svg-DgLMdltR01LHk7I7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DgLMdltR01LHk7I7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DgLMdltR01LHk7I7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DgLMdltR01LHk7I7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DgLMdltR01LHk7I7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DgLMdltR01LHk7I7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DgLMdltR01LHk7I7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DgLMdltR01LHk7I7 .cluster text{fill:#333;}#mermaid-svg-DgLMdltR01LHk7I7 .cluster span{color:#333;}#mermaid-svg-DgLMdltR01LHk7I7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DgLMdltR01LHk7I7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DgLMdltR01LHk7I7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-DgLMdltR01LHk7I7 .icon-shape,#mermaid-svg-DgLMdltR01LHk7I7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DgLMdltR01LHk7I7 .icon-shape p,#mermaid-svg-DgLMdltR01LHk7I7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DgLMdltR01LHk7I7 .icon-shape .label rect,#mermaid-svg-DgLMdltR01LHk7I7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DgLMdltR01LHk7I7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DgLMdltR01LHk7I7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DgLMdltR01LHk7I7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 原始 X
Income std=26
StandardScaler
fit_transform
X_scaled
三列 std≈1
步骤3 K-Means
2.5 实验结果(你的环境)
缩放前:
| 特征 | 均值 | 标准差 |
|---|---|---|
| Age | 38.85 | 13.97 |
| Annual Income (k$) | 60.56 | 26.26 |
| Spending Score | 50.20 | 25.82 |
缩放后:
| 特征 | 均值 | 标准差 |
|---|---|---|
| 三列 | ≈0 | ≈1.0025 |
scaler 学到的 mean_: 38.85, 60.56, 50.2,scale_: 13.93, 26.20, 25.76
2.6 与监督学习的区别
本项目无 train/test 划分 (无监督、全量 200 客户聚类),因此直接对全部 X 做 fit_transform。若将来对新客户聚类,应用已 fit 的 scaler 做 transform,不能对新数据重新 fit。
2.7 输出文件
| 文件 | 说明 |
|---|---|
reports/step2_feature_scaling.txt |
缩放前后统计 + scaler 参数 |
reports/figures/04_标准化前后标准差对比.png |
红=缩放前,绿=缩放后 |
reports/figures/05_标准化后三特征箱线图.png |
三列均在 0 附近 |
2.8 动手任务
任务 A :运行脚本,确认缩放后三列 std 均约 1.0
任务 B:为什么 Income std(26.26)比 Age(13.97)大?不缩放会怎样?
任务 C :在 Python 中打印 scaler.mean_ 和 scaler.scale_,与报告对照
任务 D:在 README 写一句话:树模型(项目一)要缩放吗?K-Means 呢?
2.9 验收标准
- 能解释 K-Means 为何必须缩放
- 能说出 fit_transform 后 mean≈0、std≈1
- 能解释欧氏距离对量纲敏感
- 能读标准差对比图
2.10 动手任务与验收标准参考答案
以下为教学标准答案,便于自学对照。
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | 三列 std 均为 1.0025 ,mean 为 0。 |
| B | Income 波动范围大、std 最大;不缩放时 Income 维度主导欧氏距离,Age/Spending 影响被稀释。 |
| C | mean_=[38.85, 60.56, 50.2],scale_≈[13.93, 26.20, 25.76]。 |
| D | 树模型不需要 缩放(看分裂顺序);K-Means必须缩放(算距离)。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| 为何必须缩放 | K-Means 用欧氏距离,量纲大的特征(Income)会主导距离。 |
| mean≈0 std≈1 | StandardScaler 公式 (x-mean)/std,变换后各列均值 0、标准差 1。 |
| 欧氏距离敏感 | 各维度单位不同,未缩放时「1 单位」含义不同,距离失真。 |
| 读对比图 | 缩放前 Income 柱最高;缩放后三柱均约 1(绿柱接近虚线 y=1)。 |
2.11 本步小结
| 要点 | 内容 |
|---|---|
| 方法 | StandardScaler |
| 缩放前最大 std | Income 26.26 |
| 缩放后 | 三列 std ≈1.0025 |
| 下一步 | K-Means K=3(步骤 3) |
2.12 学习记录(请你填写)
- 完成日期:
- 我对「距离与量纲」的理解:
- 疑问(如有):
文档版本:v1.1 | 最后更新:步骤 2 特征缩放教学已写入
步骤 3:K-Means 初探(K=3)
状态 :✅ 已完成教学(报告见
reports/step3_kmeans_k3.txt)
3.1 本步目标
- 在 X_scaled 上训练
KMeans(n_clusters=3, random_state=42, n_init=10) - 将簇标签 0/1/2 写回 DataFrame 的
Cluster列 - 按簇统计 原始特征均值,用一句话描述各簇画像
3.2 这一步在解决什么问题?
标准化之后,可以开始「分群」了。先用 K=3 做初探(商场营销常分 3~5 类),看看:
- 算法能否在 Income--Spending 平面上分出合理群组?
- 每群客户长什么样?
注意 :K=3 是试探,步骤 4~5 会用肘部法则和轮廓系数验证是否合适。
3.3 名词解释
| 名词 | 大白话 | 本步 |
|---|---|---|
| K-Means | 把样本分到 K 个簇,使簇内距离尽量小 | 本步核心算法 |
| 质心 centroid | 每簇的「中心点」 | kmeans.cluster_centers_ |
| inertia_ | 簇内平方和,越小越紧 | 295.21 |
| n_init | 多次随机初始化取最优 | 10,避免局部最优 |
| Cluster 标签 | 0~K-1 整数 | 写回 Cluster 列 |
3.4 K-Means 直觉(Mermaid)
#mermaid-svg-PRUH00cxcMubpqY2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PRUH00cxcMubpqY2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PRUH00cxcMubpqY2 .error-icon{fill:#552222;}#mermaid-svg-PRUH00cxcMubpqY2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PRUH00cxcMubpqY2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PRUH00cxcMubpqY2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PRUH00cxcMubpqY2 .marker.cross{stroke:#333333;}#mermaid-svg-PRUH00cxcMubpqY2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PRUH00cxcMubpqY2 p{margin:0;}#mermaid-svg-PRUH00cxcMubpqY2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PRUH00cxcMubpqY2 .cluster-label text{fill:#333;}#mermaid-svg-PRUH00cxcMubpqY2 .cluster-label span{color:#333;}#mermaid-svg-PRUH00cxcMubpqY2 .cluster-label span p{background-color:transparent;}#mermaid-svg-PRUH00cxcMubpqY2 .label text,#mermaid-svg-PRUH00cxcMubpqY2 span{fill:#333;color:#333;}#mermaid-svg-PRUH00cxcMubpqY2 .node rect,#mermaid-svg-PRUH00cxcMubpqY2 .node circle,#mermaid-svg-PRUH00cxcMubpqY2 .node ellipse,#mermaid-svg-PRUH00cxcMubpqY2 .node polygon,#mermaid-svg-PRUH00cxcMubpqY2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PRUH00cxcMubpqY2 .rough-node .label text,#mermaid-svg-PRUH00cxcMubpqY2 .node .label text,#mermaid-svg-PRUH00cxcMubpqY2 .image-shape .label,#mermaid-svg-PRUH00cxcMubpqY2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-PRUH00cxcMubpqY2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PRUH00cxcMubpqY2 .rough-node .label,#mermaid-svg-PRUH00cxcMubpqY2 .node .label,#mermaid-svg-PRUH00cxcMubpqY2 .image-shape .label,#mermaid-svg-PRUH00cxcMubpqY2 .icon-shape .label{text-align:center;}#mermaid-svg-PRUH00cxcMubpqY2 .node.clickable{cursor:pointer;}#mermaid-svg-PRUH00cxcMubpqY2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PRUH00cxcMubpqY2 .arrowheadPath{fill:#333333;}#mermaid-svg-PRUH00cxcMubpqY2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PRUH00cxcMubpqY2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PRUH00cxcMubpqY2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PRUH00cxcMubpqY2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PRUH00cxcMubpqY2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PRUH00cxcMubpqY2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PRUH00cxcMubpqY2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PRUH00cxcMubpqY2 .cluster text{fill:#333;}#mermaid-svg-PRUH00cxcMubpqY2 .cluster span{color:#333;}#mermaid-svg-PRUH00cxcMubpqY2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PRUH00cxcMubpqY2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PRUH00cxcMubpqY2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-PRUH00cxcMubpqY2 .icon-shape,#mermaid-svg-PRUH00cxcMubpqY2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PRUH00cxcMubpqY2 .icon-shape p,#mermaid-svg-PRUH00cxcMubpqY2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PRUH00cxcMubpqY2 .icon-shape .label rect,#mermaid-svg-PRUH00cxcMubpqY2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PRUH00cxcMubpqY2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PRUH00cxcMubpqY2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PRUH00cxcMubpqY2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
随机 K 个质心
每个客户→最近质心
更新质心=簇内均值
收敛?
输出 Cluster 0,1,2
3.5 实验结果(你的环境)
| 簇 | 人数 | Age | Income(k$) | Spending | 一句话画像 |
|---|---|---|---|---|---|
| 0 | 68 | 25.8 | 42.8 | 53.6 | 偏年轻、低收入、中等消费 |
| 1 | 41 | 32.9 | 87.3 | 80.0 | 偏年轻、高收入、高消费(优质客户) |
| 2 | 91 | 51.3 | 61.8 | 34.2 | 偏成熟、中等收入、低消费(需激活) |
- inertia_ = 295.21
- 散点图可见:簇 1 集中在右上(高收入高消费),簇 2 偏左下(低消费)
3.6 输出文件
| 文件 | 说明 |
|---|---|
reports/step3_kmeans_k3.txt |
簇画像 + inertia |
reports/figures/06_K3聚类_收入消费散点图.png |
颜色=簇 |
reports/figures/07_K3各簇客户人数.png |
68 / 41 / 91 |
3.7 动手任务
任务 A :运行脚本,确认三簇人数 68 / 41 / 91
任务 B:打开散点图,簇 1(高收入高消费)在图的哪个区域?
任务 C :inertia_ 越小越好吗?能单独用它选 K 吗?
任务 D:在 README 写:簇 2「低消费成熟客户」你会推什么营销?
3.8 验收标准
- 能解释 K-Means 质心与迭代直觉
- 能说出三簇各一句话画像
- 知道 K=3 是初探,后续还要选 K
- 能读 Income-Spending 聚类散点图
3.9 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | 簇 0: 68 ,簇 1: 41 ,簇 2: 91,合计 200。 |
| B | 右上方(Income 高、Spending 高,约 70k+ 收入、60+ 消费分)。 |
| C | inertia 越小簇内越紧,但 K 越大 inertia 必然越小;不能单独用选 K,需肘部法则/轮廓系数(步骤 4~5)。 |
| D | 示例:发优惠券/会员积分激活消费;或推适合 mature 客户的套餐,提升 Spending Score。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| 质心直觉 | 每簇一个中心;客户归最近质心;质心更新为簇内均值,迭代至稳定。 |
| 三簇画像 | 0 年轻低收入;1 高收高消;2 成熟低消费。 |
| K=3 初探 | 步骤 4 肘部、步骤 5 轮廓系数验证是否改 K。 |
| 散点图 | 簇 1 右上;簇 2 偏下;簇 0 偏左中。 |
3.10 本步小结
| 要点 | 内容 |
|---|---|
| K | 3 |
| inertia_ | 295.21 |
| 最大簇 | 簇 2(91 人,低消费) |
| 高价值簇 | 簇 1(41 人,高收高消) |
| 下一步 | 肘部法则 K=2~10(步骤 4) |
3.11 学习记录(请你填写)
- 完成日期:
- 我觉得最像「VIP」的簇:
- 疑问(如有):
文档版本:v1.2 | 最后更新:步骤 3 K-Means 初探教学已写入
步骤 4:肘部法则选 K
状态 :✅ 已完成教学(报告见
reports/step4_elbow_method.txt,图见08_肘部法则_inertia曲线.png)
4.1 本步目标
- 对 K=2~10 分别训练 K-Means,记录 inertia_
- 绘制肘部曲线,肉眼 + 启发式找拐点
- 讨论肘部不明显时的备选策略
4.2 这一步在解决什么问题?
步骤 3 用了 K=3,但这是「拍脑袋」初探。K 太小会欠分群,K 太大会过细、难运营。
inertia_ 随 K 增大单调下降 (K=200 时 inertia=0),所以不能选「inertia 最小」的 K,而要找边际收益递减的拐点------肘部。
4.3 名词解释
| 名词 | 大白话 | 本步 |
|---|---|---|
| inertia_ | 各点到所属质心距离平方和 | 越小簇内越紧 |
| 肘部法则 | 找曲线「弯折处」作为 K | K=2~10 扫描 |
| 边际下降 | K+1 时 inertia 少降多少 | K=3→4 降 94,K=5→6 降 34 |
4.4 扫描结果(你的环境)
| K | inertia | 较 K-1 下降 |
|---|---|---|
| 2 | 389.39 | --- |
| 3 | 295.21 | 94.17 |
| 4 | 205.23 | 89.99 |
| 5 | 168.25 | 36.98 |
| 6 | 133.87 | 34.38 |
| 7 | 117.01 | 16.86 |
| 8 | 103.87 | 13.14 |
| 9 | 93.09 | 10.78 |
| 10 | 82.39 | 10.71 |
观察:
- K=2→4 每次 inertia 大幅下降(~90)
- K=5 之后 下降明显变缓(~10~35),曲线变「平」
- 启发式肘点:K=4 ;许多 Mall 教程也常用 K=5(需步骤 5 轮廓系数确认)
4.5 肘部法则示意(Mermaid)
#mermaid-svg-Td2GBCMp6fb578wA{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Td2GBCMp6fb578wA .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Td2GBCMp6fb578wA .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Td2GBCMp6fb578wA .error-icon{fill:#552222;}#mermaid-svg-Td2GBCMp6fb578wA .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Td2GBCMp6fb578wA .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Td2GBCMp6fb578wA .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Td2GBCMp6fb578wA .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Td2GBCMp6fb578wA .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Td2GBCMp6fb578wA .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Td2GBCMp6fb578wA .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Td2GBCMp6fb578wA .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Td2GBCMp6fb578wA .marker.cross{stroke:#333333;}#mermaid-svg-Td2GBCMp6fb578wA svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Td2GBCMp6fb578wA p{margin:0;}#mermaid-svg-Td2GBCMp6fb578wA .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Td2GBCMp6fb578wA .cluster-label text{fill:#333;}#mermaid-svg-Td2GBCMp6fb578wA .cluster-label span{color:#333;}#mermaid-svg-Td2GBCMp6fb578wA .cluster-label span p{background-color:transparent;}#mermaid-svg-Td2GBCMp6fb578wA .label text,#mermaid-svg-Td2GBCMp6fb578wA span{fill:#333;color:#333;}#mermaid-svg-Td2GBCMp6fb578wA .node rect,#mermaid-svg-Td2GBCMp6fb578wA .node circle,#mermaid-svg-Td2GBCMp6fb578wA .node ellipse,#mermaid-svg-Td2GBCMp6fb578wA .node polygon,#mermaid-svg-Td2GBCMp6fb578wA .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Td2GBCMp6fb578wA .rough-node .label text,#mermaid-svg-Td2GBCMp6fb578wA .node .label text,#mermaid-svg-Td2GBCMp6fb578wA .image-shape .label,#mermaid-svg-Td2GBCMp6fb578wA .icon-shape .label{text-anchor:middle;}#mermaid-svg-Td2GBCMp6fb578wA .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Td2GBCMp6fb578wA .rough-node .label,#mermaid-svg-Td2GBCMp6fb578wA .node .label,#mermaid-svg-Td2GBCMp6fb578wA .image-shape .label,#mermaid-svg-Td2GBCMp6fb578wA .icon-shape .label{text-align:center;}#mermaid-svg-Td2GBCMp6fb578wA .node.clickable{cursor:pointer;}#mermaid-svg-Td2GBCMp6fb578wA .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Td2GBCMp6fb578wA .arrowheadPath{fill:#333333;}#mermaid-svg-Td2GBCMp6fb578wA .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Td2GBCMp6fb578wA .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Td2GBCMp6fb578wA .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Td2GBCMp6fb578wA .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Td2GBCMp6fb578wA .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Td2GBCMp6fb578wA .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Td2GBCMp6fb578wA .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Td2GBCMp6fb578wA .cluster text{fill:#333;}#mermaid-svg-Td2GBCMp6fb578wA .cluster span{color:#333;}#mermaid-svg-Td2GBCMp6fb578wA div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Td2GBCMp6fb578wA .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Td2GBCMp6fb578wA rect.text{fill:none;stroke-width:0;}#mermaid-svg-Td2GBCMp6fb578wA .icon-shape,#mermaid-svg-Td2GBCMp6fb578wA .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Td2GBCMp6fb578wA .icon-shape p,#mermaid-svg-Td2GBCMp6fb578wA .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Td2GBCMp6fb578wA .icon-shape .label rect,#mermaid-svg-Td2GBCMp6fb578wA .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Td2GBCMp6fb578wA .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Td2GBCMp6fb578wA .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Td2GBCMp6fb578wA :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} K=2~10 各训一次
记录 inertia
画曲线
找拐点/肘部
步骤5 轮廓系数复核
4.6 输出文件
| 文件 | 说明 |
|---|---|
reports/step4_elbow_method.txt |
K-inertia 表 + 推荐 K |
reports/figures/08_肘部法则_inertia曲线.png |
肘部曲线,红=推荐 K |
4.7 动手任务
任务 A:K=3 和 K=4 的 inertia 各是多少?差多少?
任务 B:为什么 K=10 的 inertia 比 K=3 小,却不能选 K=10?
任务 C:打开肘部图,K=5 附近曲线是否开始变平?
任务 D:肘部不明显时你会怎么办?(写 2 条)
4.8 验收标准
- 能解释 inertia 与 K 的关系
- 能读肘部曲线并给出推荐 K 及理由
- 知道不能单独用 inertia 选最大 K
- 知道肘部不明显时的备选(轮廓系数、业务)
4.9 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | K=3: 295.21 ;K=4: 205.23 ;差 89.99。 |
| B | K 越大簇越多、每簇越小,inertia 必然更小;K=10 过细、难解释、难运营,且过拟合分群。 |
| C | 是 。K=5 之后下降从 ~37 降到 17、13,曲线明显变缓。 |
| D | ① 用 silhouette_score(步骤 5);② 结合业务能否命名/运营各簇。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| inertia 与 K | K 增大 → inertia 减小;K=200 时 inertia=0。 |
| 推荐 K | 启发式 K=4;肉眼常看 K=4~5 为肘部;步骤 5 再确认。 |
| 不能选最大 K | inertia 单调降,无意义;要边际拐点 + 可解释性。 |
| 肘部不明显 | 轮廓系数 + 业务判断 + 看 drop 是否已很小。 |
4.10 本步小结
| 要点 | 内容 |
|---|---|
| 扫描范围 | K=2~10 |
| 启发式推荐 | K=4 |
| 步骤 3 对照 | K=3, inertia=295.21 |
| 关键拐点 | K=4→5 后下降明显放缓 |
| 下一步 | 轮廓系数(步骤 5) |
4.11 学习记录(请你填写)
- 完成日期:
- 我肉眼选的 K 及理由:
- 疑问(如有):
文档版本:v1.3 | 最后更新:步骤 4 肘部法则教学已写入
步骤 5:轮廓系数验证
状态 :✅ 已完成教学(报告见
reports/step5_silhouette_final_k.txt,图见09_轮廓系数随K变化.png、10_最终K聚类_收入消费散点图.png)
5.1 本步目标
- 对 K=2~10 计算
silhouette_score(X_scaled, labels) - 与步骤 4 肘部推荐 K=4 对比,综合选定最终 K
- 用最终 K 重新训练 K-Means,输出各簇画像与散点图
5.2 这一步在解决什么问题?
肘部法则看的是「簇内紧不紧」(inertia),但 K 越大 inertia 必然越小,拐点有时也不明显。
轮廓系数 silhouette 从另一角度衡量:每个点与自己簇有多近、与最近邻簇有多远。
- 取值约 -1~1 ,越大越好
- 可用来验证:肘部推荐的 K=4,是否也是「分群质量」较好的 K
本步结论:silhouette 在 K=6 达到最高 0.4284 ,高于 K=4 的 0.4040,故采用 K=6 作为后续 PCA 与画像的 K。
5.3 名词解释
| 名词 | 大白话 | 本步 |
|---|---|---|
| silhouette_score | 衡量「分得像不像样」的综合指标 | K=2~10 扫描 |
| a(i) | 点 i 到同簇其他点的平均距离 | 越小越「抱团」 |
| b(i) | 点 i 到最近邻簇的平均距离 | 越大越「分得开」 |
| s(i)=(b-a)/max(a,b) | 单点轮廓系数 | 全样本取平均得 silhouette |
| 最终 K | 肘部 + 轮廓 + 业务折中 | 本环境 K=6 |
5.4 扫描结果(你的环境)
| K | silhouette | inertia | 备注 |
|---|---|---|---|
| 2 | 0.3355 | 389.39 | 分太粗 |
| 3 | 0.3578 | 295.21 | 步骤 3 初探 |
| 4 | 0.4040 | 205.23 | 肘部启发式 K |
| 5 | 0.4166 | 168.25 | 介于 4 与 6 之间 |
| 6 | 0.4284 | 133.87 | silhouette 最高 |
| 7 | 0.4172 | 117.01 | 开始回落 |
| 8 | 0.4082 | 103.87 | |
| 9 | 0.4177 | 93.09 | |
| 10 | 0.4066 | 82.39 | K 过大、难运营 |
观察:
- K=4→6 silhouette 从 0.404 升到 0.428,分群「紧且分」更好
- K=7 之后 silhouette 回落,说明再细分收益变小
- 与肘部不矛盾:肘部看 inertia 拐点(约 K=4),轮廓系数允许在 4~6 间取更优
5.5 K=6 各簇画像(原始特征均值)
| 簇 | 人数 | Age | Income(k$) | Spending | 一句话 |
|---|---|---|---|---|---|
| 0 | 45 | 56.3 | 54.3 | 49.1 | 偏成熟、中等收入、中等消费 |
| 1 | 39 | 26.8 | 57.1 | 48.1 | 偏年轻、中等收入、中等消费 |
| 2 | 33 | 41.9 | 88.9 | 17.0 | 中年、高收入、低消费 |
| 3 | 39 | 32.7 | 86.5 | 82.1 | 偏年轻、高收入、高消费(VIP) |
| 4 | 23 | 25.0 | 25.3 | 77.6 | 偏年轻、低收入、高消费 |
| 5 | 21 | 45.5 | 26.3 | 19.4 | 偏成熟、低收入、低消费 |
- 最终模型:inertia_ = 133.87 ,silhouette = 0.4284
5.6 选 K 决策流(Mermaid)
#mermaid-svg-RRM1eY3cbuY40hzF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RRM1eY3cbuY40hzF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RRM1eY3cbuY40hzF .error-icon{fill:#552222;}#mermaid-svg-RRM1eY3cbuY40hzF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RRM1eY3cbuY40hzF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RRM1eY3cbuY40hzF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RRM1eY3cbuY40hzF .marker.cross{stroke:#333333;}#mermaid-svg-RRM1eY3cbuY40hzF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RRM1eY3cbuY40hzF p{margin:0;}#mermaid-svg-RRM1eY3cbuY40hzF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RRM1eY3cbuY40hzF .cluster-label text{fill:#333;}#mermaid-svg-RRM1eY3cbuY40hzF .cluster-label span{color:#333;}#mermaid-svg-RRM1eY3cbuY40hzF .cluster-label span p{background-color:transparent;}#mermaid-svg-RRM1eY3cbuY40hzF .label text,#mermaid-svg-RRM1eY3cbuY40hzF span{fill:#333;color:#333;}#mermaid-svg-RRM1eY3cbuY40hzF .node rect,#mermaid-svg-RRM1eY3cbuY40hzF .node circle,#mermaid-svg-RRM1eY3cbuY40hzF .node ellipse,#mermaid-svg-RRM1eY3cbuY40hzF .node polygon,#mermaid-svg-RRM1eY3cbuY40hzF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RRM1eY3cbuY40hzF .rough-node .label text,#mermaid-svg-RRM1eY3cbuY40hzF .node .label text,#mermaid-svg-RRM1eY3cbuY40hzF .image-shape .label,#mermaid-svg-RRM1eY3cbuY40hzF .icon-shape .label{text-anchor:middle;}#mermaid-svg-RRM1eY3cbuY40hzF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RRM1eY3cbuY40hzF .rough-node .label,#mermaid-svg-RRM1eY3cbuY40hzF .node .label,#mermaid-svg-RRM1eY3cbuY40hzF .image-shape .label,#mermaid-svg-RRM1eY3cbuY40hzF .icon-shape .label{text-align:center;}#mermaid-svg-RRM1eY3cbuY40hzF .node.clickable{cursor:pointer;}#mermaid-svg-RRM1eY3cbuY40hzF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RRM1eY3cbuY40hzF .arrowheadPath{fill:#333333;}#mermaid-svg-RRM1eY3cbuY40hzF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RRM1eY3cbuY40hzF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RRM1eY3cbuY40hzF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RRM1eY3cbuY40hzF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RRM1eY3cbuY40hzF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RRM1eY3cbuY40hzF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RRM1eY3cbuY40hzF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RRM1eY3cbuY40hzF .cluster text{fill:#333;}#mermaid-svg-RRM1eY3cbuY40hzF .cluster span{color:#333;}#mermaid-svg-RRM1eY3cbuY40hzF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RRM1eY3cbuY40hzF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RRM1eY3cbuY40hzF rect.text{fill:none;stroke-width:0;}#mermaid-svg-RRM1eY3cbuY40hzF .icon-shape,#mermaid-svg-RRM1eY3cbuY40hzF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RRM1eY3cbuY40hzF .icon-shape p,#mermaid-svg-RRM1eY3cbuY40hzF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RRM1eY3cbuY40hzF .icon-shape .label rect,#mermaid-svg-RRM1eY3cbuY40hzF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RRM1eY3cbuY40hzF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RRM1eY3cbuY40hzF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RRM1eY3cbuY40hzF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 步骤4 肘部 K=4
步骤5 扫 silhouette
K=2~10 各训一次
K=6 最高 0.4284
最终 K=6
步骤6 PCA 可视化
5.7 输出文件
| 文件 | 说明 |
|---|---|
reports/step5_silhouette_final_k.txt |
K-silhouette 表 + 最终 K + 六簇画像 |
reports/figures/09_轮廓系数随K变化.png |
silhouette 曲线,红=最终 K |
reports/figures/10_最终K聚类_收入消费散点图.png |
K=6 在 Income-Spending 平面 |
5.8 动手任务
任务 A:K=4 与 K=6 的 silhouette 各是多少?最终选哪个?为什么?
任务 B:K=6 时 silhouette 最高,但运营要分 6 类会不会太多?你会怎么折中?
任务 C :打开 10_最终K聚类_收入消费散点图.png,簇 3(高收高消)在图的什么位置?
任务 D:簇 2「高收入低消费」和簇 5「低收入低消费」营销策略应有什么不同?各写一句。
5.9 验收标准
- 能解释 silhouette 越大越好、范围约 -1~1
- 能对比肘部 K=4 与 silhouette 最优 K=6 的差异
- 能说出 K=6 时至少 3 个簇的一句话画像
- 知道最终 K 将用于步骤 6~7
5.10 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | K=4: 0.4040 ;K=6: 0.4284 。选 K=6,因 silhouette 更高、分群质量更好;K=7 已回落,6 是峰值。 |
| B | 示例:若运营只能做 4 类,可合并相似簇(如 0+1 中等收入族、2 单独、3 单独、4+5 低收族);或保留 K=6 做细粒度再映射到 4 个营销标签。 |
| C | 右上方(Income≈87k、Spending≈82,高收入高消费 VIP 区)。 |
| D | 簇 2:推高端但理性消费品类、会员权益激活(有钱但省);簇 5:推性价比、基础款、唤醒低频客户(钱少且花得少)。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| silhouette 含义 | 簇内紧、簇间分则高;0.4284 表示中等偏上质量(小数据集常见)。 |
| 与肘部关系 | 肘部 K=4 合理;silhouette 支持略增到 K=6;两者结合比单看 inertia 更稳。 |
| 三簇画像 | 例:3=高收高消 VIP;2=高收低消;5=低收低消。 |
| 后续用途 | 步骤 6 用 K=6 做 PCA 图;步骤 7 命名六类并写营销建议。 |
5.11 本步小结
| 要点 | 内容 |
|---|---|
| 扫描范围 | K=2~10 |
| silhouette 最高 | K=6(0.4284) |
| 肘部参考 | K=4(0.4040) |
| 最终选定 | K=6 |
| 最大簇 | 簇 0(45 人) |
| VIP 簇 | 簇 3(39 人,高收高消) |
| 下一步 | PCA 二维可视化(步骤 6) |
5.12 学习记录(请你填写)
- 完成日期:
- 我若只能选 K=4 会合并哪几簇:
- 疑问(如有):
文档版本:v1.4 | 最后更新:步骤 5 轮廓系数验证教学已写入
步骤 6:PCA 二维可视化
状态 :✅ 已完成教学(报告见
reports/step6_pca_visualization.txt,图见11_PCA二维聚类散点图.png)
6.1 本步目标
- 对 X_scaled 使用
PCA(n_components=2)降到二维 - 绘制 PC1--PC2 散点图,颜色 = 簇标签(K=6)
- 理解 PCA 是线性降维,用于可视化而非「唯一真理」
6.2 这一步在解决什么问题?
Income--Spending 散点图只能看 2 个特征 ,但聚类用了 Age + Income + Spending 三个维度。
人眼无法直接看 3D 空间里分群是否清晰,PCA 把三维信息线性压缩到平面,方便一眼看出各簇是否分开。
6.3 名词解释
| 名词 | 大白话 | 本步 |
|---|---|---|
| PCA | 找方差最大的方向当新坐标轴 | 3 维 → 2 维 |
| 主成分 PC1/PC2 | 第 1、2 重要的新轴 | 散点图横纵轴 |
| explained_variance_ratio_ | 该轴保留原数据多少「信息量」 | PC1 44.27% ,PC2 33.31% |
| 累计解释方差 | PC1+PC2 共保留多少 | 77.57% |
6.4 实验结果(你的环境)
| 指标 | 数值 |
|---|---|
| PC1 解释方差 | 44.27% |
| PC2 解释方差 | 33.31% |
| 累计 | 77.57% |
| 聚类 K | 6(沿用步骤 5) |
如何读图:
- 每个点 = 一位客户;同色 = 同一簇
- 若同色点成团、不同颜色分开 → 分群在整体结构上较合理
- 轴标签里的百分比 = 该主成分贡献的方差比例
6.5 PCA 在流程中的位置(Mermaid)
#mermaid-svg-kIcPM9W8wQIIGale{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kIcPM9W8wQIIGale .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kIcPM9W8wQIIGale .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kIcPM9W8wQIIGale .error-icon{fill:#552222;}#mermaid-svg-kIcPM9W8wQIIGale .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kIcPM9W8wQIIGale .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kIcPM9W8wQIIGale .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kIcPM9W8wQIIGale .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kIcPM9W8wQIIGale .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kIcPM9W8wQIIGale .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kIcPM9W8wQIIGale .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kIcPM9W8wQIIGale .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kIcPM9W8wQIIGale .marker.cross{stroke:#333333;}#mermaid-svg-kIcPM9W8wQIIGale svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kIcPM9W8wQIIGale p{margin:0;}#mermaid-svg-kIcPM9W8wQIIGale .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kIcPM9W8wQIIGale .cluster-label text{fill:#333;}#mermaid-svg-kIcPM9W8wQIIGale .cluster-label span{color:#333;}#mermaid-svg-kIcPM9W8wQIIGale .cluster-label span p{background-color:transparent;}#mermaid-svg-kIcPM9W8wQIIGale .label text,#mermaid-svg-kIcPM9W8wQIIGale span{fill:#333;color:#333;}#mermaid-svg-kIcPM9W8wQIIGale .node rect,#mermaid-svg-kIcPM9W8wQIIGale .node circle,#mermaid-svg-kIcPM9W8wQIIGale .node ellipse,#mermaid-svg-kIcPM9W8wQIIGale .node polygon,#mermaid-svg-kIcPM9W8wQIIGale .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kIcPM9W8wQIIGale .rough-node .label text,#mermaid-svg-kIcPM9W8wQIIGale .node .label text,#mermaid-svg-kIcPM9W8wQIIGale .image-shape .label,#mermaid-svg-kIcPM9W8wQIIGale .icon-shape .label{text-anchor:middle;}#mermaid-svg-kIcPM9W8wQIIGale .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kIcPM9W8wQIIGale .rough-node .label,#mermaid-svg-kIcPM9W8wQIIGale .node .label,#mermaid-svg-kIcPM9W8wQIIGale .image-shape .label,#mermaid-svg-kIcPM9W8wQIIGale .icon-shape .label{text-align:center;}#mermaid-svg-kIcPM9W8wQIIGale .node.clickable{cursor:pointer;}#mermaid-svg-kIcPM9W8wQIIGale .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kIcPM9W8wQIIGale .arrowheadPath{fill:#333333;}#mermaid-svg-kIcPM9W8wQIIGale .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kIcPM9W8wQIIGale .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kIcPM9W8wQIIGale .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kIcPM9W8wQIIGale .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kIcPM9W8wQIIGale .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kIcPM9W8wQIIGale .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kIcPM9W8wQIIGale .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kIcPM9W8wQIIGale .cluster text{fill:#333;}#mermaid-svg-kIcPM9W8wQIIGale .cluster span{color:#333;}#mermaid-svg-kIcPM9W8wQIIGale div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kIcPM9W8wQIIGale .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kIcPM9W8wQIIGale rect.text{fill:none;stroke-width:0;}#mermaid-svg-kIcPM9W8wQIIGale .icon-shape,#mermaid-svg-kIcPM9W8wQIIGale .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kIcPM9W8wQIIGale .icon-shape p,#mermaid-svg-kIcPM9W8wQIIGale .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kIcPM9W8wQIIGale .icon-shape .label rect,#mermaid-svg-kIcPM9W8wQIIGale .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kIcPM9W8wQIIGale .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kIcPM9W8wQIIGale .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kIcPM9W8wQIIGale :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} X_scaled 3维
PCA → PC1, PC2
散点图 颜色=Cluster
步骤7 回到原始特征写画像
6.6 输出文件
| 文件 | 说明 |
|---|---|
reports/step6_pca_visualization.txt |
解释方差 + 读图说明 + PCA 局限 |
reports/figures/11_PCA二维聚类散点图.png |
K=6 在 PC1--PC2 平面 |
6.7 动手任务
任务 A:PC1、PC2 各解释多少方差?累计多少?约多少信息被「丢掉」?
任务 B :PCA 图与 10_最终K聚类_收入消费散点图.png 有何不同?各适合回答什么问题?
任务 C:打开 PCA 图,簇 3(高收高消)是否与簇 5(低收低消)明显分开?
任务 D:为什么说 PCA 不能代替原始特征的 business 解释?写 1 句。
6.8 验收标准
- 能解释 PCA 是线性降维、用于可视化
- 能读 PC1/PC2 轴上的解释方差比例
- 能对比 PCA 图与 Income-Spending 图的用途
- 知道约 22% 方差未显示,解读需谨慎
6.9 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | PC1 44.27% ,PC2 33.31% ,累计 77.57% ;约 22.43% 信息未在 2D 图中显示。 |
| B | PCA 图综合三维(含 Age);Income-Spending 图直观看购买力与消费。PCA 看整体分群结构;后者看业务最关注的二维关系。 |
| C | 是。高收高消(簇 3)与低收低消(簇 5)在 PC 平面上通常分居不同区域(具体位置以你本地图为准)。 |
| D | PC1/PC2 是 Age/Income/Spending 的加权组合,无法直接说「PC1 高 = 收入高」,营销命名仍需看原始均值。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| PCA 作用 | 线性降维到 2D,便于肉眼检查聚类是否分离。 |
| 解释方差 | PC1 44%、PC2 33%、累计 78%。 |
| 与业务图对比 | PCA=全局结构;Income-Spending=业务直观。 |
| 局限 | 非线性结构可能丢失;约 22% 方差未展示;不能替代原始特征画像。 |
6.10 本步小结
| 要点 | 内容 |
|---|---|
| 方法 | PCA(n_components=2) |
| 累计解释方差 | 77.57% |
| 可视化 K | 6 |
| 用途 | 检查分群在降维空间是否清晰 |
| 下一步 | 客群画像命名 + 营销建议(步骤 7) |
6.11 学习记录(请你填写)
- 完成日期:
- PCA 图上哪两簇分得最开:
- 疑问(如有):
文档版本:v1.5 | 最后更新:步骤 6 PCA 二维可视化教学已写入
步骤 7:客群画像命名
状态 :✅ 已完成教学(报告见
reports/step7_cluster_personas.txt,图见12_各客群人数与命名.png)
7.1 本步目标
- 对每个簇统计 Age / Income / Spending 均值
- 起业务名称(如 VIP 高消族、富裕保守型)
- 写每类 1~2 句营销策略
7.2 这一步在解决什么问题?
聚类输出的是 0~5 数字标签,运营无法直接使用。
步骤 7 把数字翻译成可沟通、可行动的客群名与策略,完成「算法 → 业务」的最后一步。
7.3 六类客群画像(你的环境,K=6)
| 簇 | 业务名称 | 人数 | Age | Income | Spending | 营销要点 |
|---|---|---|---|---|---|---|
| 0 | 稳健中年族 | 45 | 56 | 54k | 49 | 家庭套餐、实用组合券 |
| 1 | 普通年轻族 | 39 | 27 | 57k | 48 | 节日促销、社交裂变 |
| 2 | 富裕保守型 | 33 | 42 | 89k | 17 | 品质背书、积分激活消费 |
| 3 | VIP 高消族 | 39 | 33 | 87k | 82 | 新品首发、会员专属礼遇 |
| 4 | 年轻月光族 | 23 | 25 | 25k | 78 | 分期、潮流联名、优惠券 |
| 5 | 低活跃族 | 21 | 46 | 26k | 19 | 基础促销、唤醒短信 |
7.4 从标签到策略(Mermaid)
#mermaid-svg-FYy6nl0FL1QGq4k3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FYy6nl0FL1QGq4k3 .error-icon{fill:#552222;}#mermaid-svg-FYy6nl0FL1QGq4k3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FYy6nl0FL1QGq4k3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .marker.cross{stroke:#333333;}#mermaid-svg-FYy6nl0FL1QGq4k3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FYy6nl0FL1QGq4k3 p{margin:0;}#mermaid-svg-FYy6nl0FL1QGq4k3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster-label text{fill:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster-label span{color:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster-label span p{background-color:transparent;}#mermaid-svg-FYy6nl0FL1QGq4k3 .label text,#mermaid-svg-FYy6nl0FL1QGq4k3 span{fill:#333;color:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .node rect,#mermaid-svg-FYy6nl0FL1QGq4k3 .node circle,#mermaid-svg-FYy6nl0FL1QGq4k3 .node ellipse,#mermaid-svg-FYy6nl0FL1QGq4k3 .node polygon,#mermaid-svg-FYy6nl0FL1QGq4k3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .rough-node .label text,#mermaid-svg-FYy6nl0FL1QGq4k3 .node .label text,#mermaid-svg-FYy6nl0FL1QGq4k3 .image-shape .label,#mermaid-svg-FYy6nl0FL1QGq4k3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-FYy6nl0FL1QGq4k3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .rough-node .label,#mermaid-svg-FYy6nl0FL1QGq4k3 .node .label,#mermaid-svg-FYy6nl0FL1QGq4k3 .image-shape .label,#mermaid-svg-FYy6nl0FL1QGq4k3 .icon-shape .label{text-align:center;}#mermaid-svg-FYy6nl0FL1QGq4k3 .node.clickable{cursor:pointer;}#mermaid-svg-FYy6nl0FL1QGq4k3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .arrowheadPath{fill:#333333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FYy6nl0FL1QGq4k3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FYy6nl0FL1QGq4k3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FYy6nl0FL1QGq4k3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster text{fill:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 .cluster span{color:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FYy6nl0FL1QGq4k3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FYy6nl0FL1QGq4k3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-FYy6nl0FL1QGq4k3 .icon-shape,#mermaid-svg-FYy6nl0FL1QGq4k3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FYy6nl0FL1QGq4k3 .icon-shape p,#mermaid-svg-FYy6nl0FL1QGq4k3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FYy6nl0FL1QGq4k3 .icon-shape .label rect,#mermaid-svg-FYy6nl0FL1QGq4k3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FYy6nl0FL1QGq4k3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FYy6nl0FL1QGq4k3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FYy6nl0FL1QGq4k3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Cluster 0~5
原始特征均值
业务命名
营销建议 1~2 句
运营可执行
7.5 输出文件
| 文件 | 说明 |
|---|---|
reports/step7_cluster_personas.txt |
完整画像表 + 各簇营销建议 |
reports/figures/12_各客群人数与命名.png |
六类人数柱状图 |
7.6 动手任务
任务 A:哪两个簇是「高收入」?他们的 Spending 有何相反之处?
任务 B:「年轻月光族」为什么 income 低但 spending 高?你会推什么产品?
任务 C :若商场只能做 4 个营销档位,你会把哪几簇合并?
任务 D:在 README 写:你最想维护的客群及理由。
7.7 验收标准
- 至少能描述 3 个簇的业务名与特征
- 每个簇有 1 句可执行的营销建议
- 理解数字 Cluster 需翻译才可用于业务
7.8 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | 簇 2、3 高收入(≈87~89k);簇 2 低消费 (17),簇 3 高消费(82)------同有钱不同花法。 |
| B | 年轻、收入有限但消费意愿强(冲动/社交消费);推潮流单品、分期、限时券,避免过度借贷风险。 |
| C | 示例:合并 0+1→「普通主流族」;2 单独「保守富裕」;3 单独「VIP」;4+5→「需激活族」或拆为「高消低收」与「双低」。 |
| D | 示例:VIP 高消族------LTV 最高,值得专属维护。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| 三簇描述 | 例:VIP 高消、富裕保守、年轻月光。 |
| 营销可执行 | 每簇策略对应具体动作(券、会员、分期等)。 |
| 标签翻译 | Cluster 是算法输出,业务名便于跨部门沟通。 |
7.9 本步小结
| 要点 | 内容 |
|---|---|
| K | 6 类均已命名 |
| 高价值 | VIP 高消族(39 人) |
| 需激活 | 富裕保守型 、低活跃族 |
| 下一步 | 总结局限 + 导出 CSV(步骤 8) |
7.10 学习记录(请你填写)
- 完成日期:
- 我会优先运营哪一类:
- 疑问(如有):
步骤 8:总结与局限
状态 :✅ 已完成教学(报告见
reports/step8_summary_and_limitations.txt,CSV 见outputs/mall_customers_clustered_k6.csv)
8.1 本步目标
- 讨论 K-Means 假设在本数据上是否大致成立
- 了解替代算法:DBSCAN 、层次聚类(不要求实现)
- 保存带
Cluster列的结果 CSV
8.2 这一步在解决什么问题?
无监督项目不能停在「图画得好看」,还要诚实讨论:
- 算法假设是否匹配数据?
- 还有哪些方法可选?
- 交付物是什么,下游怎么用?
8.3 K-Means 三条假设 vs 本数据
| 假设 | 含义 | 本数据情况 |
|---|---|---|
| 球形簇 | 簇在各方向半径相近 | Income-Spending 上大体合理,但形状未必完美球形 |
| 相似大小 | 各簇样本量接近 | 不完全成立:簇 4/5 仅 21~23 人,簇 0 有 45 人 |
| 预设 K | 需事先指定簇数 | 已用肘部 + silhouette 选 K=6 |
| 欧氏距离 | 特征等权重、线性距离 | 已 StandardScaler;Gender 未纳入 |
8.4 替代算法(了解即可)
| 算法 | 特点 | 何时考虑 |
|---|---|---|
| DBSCAN | 不需 K,可找任意形状簇与噪声 | 簇形状不规则、有离群点 |
| 层次聚类 | 树状图选 K,小样本可解释 | 需要展示「谁和谁先合并」 |
8.5 交付物
| 文件 | 说明 |
|---|---|
outputs/mall_customers_clustered_k6.csv |
原表 + Cluster 列(0~5) |
reports/step8_summary_and_limitations.txt |
项目总结与局限 |
8.6 项目四全流程回顾(Mermaid)
#mermaid-svg-APoT7MPlD1INbfB7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-APoT7MPlD1INbfB7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-APoT7MPlD1INbfB7 .error-icon{fill:#552222;}#mermaid-svg-APoT7MPlD1INbfB7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-APoT7MPlD1INbfB7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-APoT7MPlD1INbfB7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-APoT7MPlD1INbfB7 .marker.cross{stroke:#333333;}#mermaid-svg-APoT7MPlD1INbfB7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-APoT7MPlD1INbfB7 p{margin:0;}#mermaid-svg-APoT7MPlD1INbfB7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-APoT7MPlD1INbfB7 .cluster-label text{fill:#333;}#mermaid-svg-APoT7MPlD1INbfB7 .cluster-label span{color:#333;}#mermaid-svg-APoT7MPlD1INbfB7 .cluster-label span p{background-color:transparent;}#mermaid-svg-APoT7MPlD1INbfB7 .label text,#mermaid-svg-APoT7MPlD1INbfB7 span{fill:#333;color:#333;}#mermaid-svg-APoT7MPlD1INbfB7 .node rect,#mermaid-svg-APoT7MPlD1INbfB7 .node circle,#mermaid-svg-APoT7MPlD1INbfB7 .node ellipse,#mermaid-svg-APoT7MPlD1INbfB7 .node polygon,#mermaid-svg-APoT7MPlD1INbfB7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-APoT7MPlD1INbfB7 .rough-node .label text,#mermaid-svg-APoT7MPlD1INbfB7 .node .label text,#mermaid-svg-APoT7MPlD1INbfB7 .image-shape .label,#mermaid-svg-APoT7MPlD1INbfB7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-APoT7MPlD1INbfB7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-APoT7MPlD1INbfB7 .rough-node .label,#mermaid-svg-APoT7MPlD1INbfB7 .node .label,#mermaid-svg-APoT7MPlD1INbfB7 .image-shape .label,#mermaid-svg-APoT7MPlD1INbfB7 .icon-shape .label{text-align:center;}#mermaid-svg-APoT7MPlD1INbfB7 .node.clickable{cursor:pointer;}#mermaid-svg-APoT7MPlD1INbfB7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-APoT7MPlD1INbfB7 .arrowheadPath{fill:#333333;}#mermaid-svg-APoT7MPlD1INbfB7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-APoT7MPlD1INbfB7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-APoT7MPlD1INbfB7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-APoT7MPlD1INbfB7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-APoT7MPlD1INbfB7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-APoT7MPlD1INbfB7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-APoT7MPlD1INbfB7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-APoT7MPlD1INbfB7 .cluster text{fill:#333;}#mermaid-svg-APoT7MPlD1INbfB7 .cluster span{color:#333;}#mermaid-svg-APoT7MPlD1INbfB7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-APoT7MPlD1INbfB7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-APoT7MPlD1INbfB7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-APoT7MPlD1INbfB7 .icon-shape,#mermaid-svg-APoT7MPlD1INbfB7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-APoT7MPlD1INbfB7 .icon-shape p,#mermaid-svg-APoT7MPlD1INbfB7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-APoT7MPlD1INbfB7 .icon-shape .label rect,#mermaid-svg-APoT7MPlD1INbfB7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-APoT7MPlD1INbfB7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-APoT7MPlD1INbfB7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-APoT7MPlD1INbfB7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1 加载探索
2 StandardScaler
3 K=3 初探
4 肘部 K=4
5 silhouette → K=6
6 PCA 可视化
7 画像命名
8 CSV 交付
8.7 动手任务
任务 A:K-Means 在本数据上哪条假设最「不太成立」?举例。
任务 B :打开 mall_customers_clustered_k6.csv,确认有 Cluster 列且 200 行。
任务 C:用一句话向非技术同事解释「我们怎么分的群」。
任务 D:进阶:若加入 Gender One-Hot,你猜测簇标签会变很多吗?
8.8 验收标准
- 能说出 K-Means 至少 2 条假设
- 知道 DBSCAN、层次聚类的名字与用途
- 找到并打开带 Cluster 的 CSV
- 能概括项目四完整流程
8.9 动手任务与验收标准参考答案
动手任务答案
| 任务 | 参考答案 |
|---|---|
| A | 簇大小不均 :VIP 39 人 vs 低活跃 21 人;或 Gender 未用导致分群未考虑性别差异。 |
| B | CSV 应有 CustomerID、Gender、Age、Income、Spending、Cluster,共 200 行。 |
| C | 示例:「按年龄、收入、消费打分把 200 客户分成 6 类,每类有不同营销方案。」 |
| D | 本数据男女比例接近,Gender 影响可能不大,但个别簇性别比例可能变化;需实验验证。 |
验收标准答案
| 验收项 | 参考答案 |
|---|---|
| K-Means 假设 | 球形簇、相似大小、预设 K、基于距离(+ 本步缩放)。 |
| 替代算法 | DBSCAN=密度+噪声;层次=树状合并。 |
| CSV | outputs/mall_customers_clustered_k6.csv。 |
| 全流程 | 探索→缩放→初探→肘部→轮廓→PCA→画像→导出。 |
8.10 本步小结
| 要点 | 内容 |
|---|---|
| 最终 K | 6 |
| silhouette | 0.4284 |
| 交付 CSV | mall_customers_clustered_k6.csv |
| 局限 | 簇大小不均、Gender 未纳入、K-Means 形状假设 |
| 项目四 | 全部 8 步完成 |
8.11 学习记录(请你填写)
- 完成日期:
- 我对无监督学习最大的收获:
- 下一步:项目五 电影评论情感分类
文档版本:v1.6 | 最后更新:步骤 7~8 完成,项目四全部教学已写入