ML-For-Beginners 聚类作业实战:K-Means 之外,如何为尼日利亚音乐数据选择并实现替代聚类方法
【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners
本篇文章围绕 ML-For-Beginners 仓库第 5 单元「聚类」第 2 课的作业(translations/de/5-Clustering/2-K-Means/assignment.md,对应英文原版 5-Clustering/2-K-Means/assignment.md)展开:课程已经演示了用 K-Means 对 Spotify 尼日利亚歌曲数据进行聚类,而作业要求你换一种非 K-Means 的聚类方法重新建模,并总结学习心得。读完本文,你将理解 K-Means 在什么场景下力不从心、Scikit-learn 提供了哪些替代方案、如何用层次聚类或密度聚类完成这份作业,以及如何对照评分表交付一份「文档完备」的 notebook。
作业原文解读:任务到底是什么
作业原文(德语版)的完整要求如下:
Anweisungen(任务说明):在本课中你已经学习了 K-Means 聚类。有时 K-Means 并不适合你的数据。请创建一个 notebook,使用本课的数据或来自其他来源的数据(请注明来源),展示一种不使用 K-Means的聚类方法。你学到了什么?
拆解这句话可以得到三个硬性交付物:
- 一个可运行的 notebook——建议从课程自带的 5-Clustering/2-K-Means/notebook.ipynb 出发,它已经完成了数据导入和初步清洗;
- 一种非 K-Means 的聚类方法——这是与课程形成对比的关键,也是评分表关注的焦点;
- 注明数据来源——如果使用课程数据(5-Clustering/data/nigerian-songs.csv),应说明其来自 Kaggle、由 Spotify 抓取;如果自选数据集,则必须给出出处。
课程铺垫:为什么 K-Means 可能「不适合你的数据」
作业里那句「有时 K-Means 并不适合你的数据」并非客套话,它在课程 5-Clustering/2-K-Means/README.md 中是有明确数据证据的。
K-Means 的机制与先天假设
K-Means 源于信号处理领域,通过一系列观测把数据划分为 k 个簇,每个观测被归入离它最近的「均值」即簇中心(centroid)。课程给出了三步执行流程:
- 算法从数据集中采样选出 k 个中心点;
- 循环执行:把每个样本分配给最近的质心 → 用分配到各质心的样本均值生成新质心 → 计算新旧质心之差,直到质心稳定。
课程明确指出 K-Means 的一大缺点:你必须预先确定 k 的值(簇的数量),而「肘部法(elbow method)」只能帮助估计一个合理的起点。
课程实验留下的「坏消息」
在 notebook.ipynb 中,课程用过滤后的数据(只保留 afro dancehall、afropop、nigerian pop 三种流派,并排除 popularity 为 0 的样本)做了 K-Means 建模,得到两个关键指标:
- Silhouette score(轮廓系数)≈ 0.53:该分数取值范围为 -1 到 1,越接近 1 表示簇越密集、与其他簇分离越清晰;接近 0 表示簇互相重叠、样本紧贴决策边界。0.53 处于中间地带,说明「数据对这种聚类方式并不是特别合适」。
- Accuracy(准确率)不佳:将聚类标签与真实流派标签比对后,正确标记的样本占比很低,且散点图中簇的形状混杂。
课程给出的解释是:这组数据过于不平衡、特征之间相关性太弱、列与列之间的方差(variance)过大,难以聚出干净的簇。所谓方差,即「与均值之差的平方的平均值」——本数据集的数值围绕均值发散得有点过头。这是作业布置的动机所在:当数据形状不满足 K-Means 的球形簇假设时,就该换算法了。
方法选型:Scikit-learn 里 K-Means 之外的世界
作业要求「展示一种不同的聚类方法」,而选型依据就在前一课 5-Clustering/1-Visualize/README.md 中。该课 README 给出了 Scikit-learn 支持的主要聚类方法与适用场景对照表(摘录如下):
| 方法名称 | 适用场景 |
|---|---|
| K-Means | 通用目的,归纳式(inductive) |
| Affinity propagation(亲和传播) | 多而大小不均的簇,归纳式 |
| Mean-shift(均值漂移) | 多而大小不均的簇,归纳式 |
| Spectral clustering(谱聚类) | 少而均匀的簇,直推式(transductive) |
| Ward hierarchical clustering(Ward 层次聚类) | 多而受约束的簇,直推式 |
| Agglomerative clustering(凝聚聚类) | 多而受约束的簇、非欧氏距离,直推式 |
| DBSCAN | 非平坦几何、大小不均的簇,直推式 |
| OPTICS | 非平坦几何、密度不一的簇,直推式 |
| Gaussian mixtures(高斯混合模型) | 平坦几何,归纳式 |
| BIRCH | 含离群点的大数据集,归纳式 |
从概念分类看,非 K-Means 方法大致归为四类(同样出自该课 README):
- 层次聚类(Hierarchical clustering):按对象之间距离的远近逐层合并或分裂形成簇,Scikit-learn 的
AgglomerativeClustering即属此类; - 基于分布的聚类(Distribution-based clustering):以统计建模为核心,计算数据点属于某簇的概率再行分配,高斯混合模型(GMM)是代表;
- 基于密度的聚类(Density-based clustering):按数据点的密度(彼此聚集程度)分簇,离群点视为噪声,DBSCAN、Mean-shift、OPTICS 属于此类;
- 基于网格的聚类(Grid-based clustering):对多维数据划网格、按单元格分簇。
对照本作业的数据特性(簇的边界模糊、存在噪声与离群点),层次聚类、DBSCAN、高斯混合模型是三个最合适的候选,因为它们不像 K-Means 那样强依赖「k 值 + 球形簇」的设定。
实战指引:三种非 K-Means 方案的 notebook 写法
下面的代码框架基于课程 notebook 已完成的预处理(读取 5-Clustering/data/nigerian-songs.csv、过滤出三种流派、用LabelEncoder把artist_top_genre编码为数值、选取 popularity / danceability / acousticness / loudness / energy 等特征列),可作为完成作业的参考起点(建议在 Jupyter 中逐格运行并补充文字说明)。
方案 A:层次聚类(Agglomerative Clustering)
层次聚类不需要预设 k,可以先绘制树状图(dendrogram)观察簇的自然结构,再决定切分位置:
from sklearn.cluster import AgglomerativeClustering from sklearn import metrics # 基于课程 notebook 中的特征矩阵 X 进行聚类 agg = AgglomerativeClustering(n_clusters=3) agg_labels = agg.fit_predict(X) # 与 K-Means 一样用轮廓系数评估 score = metrics.silhouette_score(X, agg_labels) print("Agglomerative silhouette score:", score)如果不想手动指定n_clusters,还可以用scipy.cluster.hierarchy绘制树状图,观察哪个高度「切割」能形成合理分组——这与 K-Means 必须先用肘部法猜 k 形成鲜明对比。
方案 B:基于密度的 DBSCAN
DBSCAN 自动发现任意形状的簇,并把稀疏区域标记为噪声,天然不惧怕本数据的离群点:
from sklearn.cluster import DBSCAN # eps 控制邻域半径,min_samples 控制成为核心点的最少样本数 db = DBSCAN(eps=0.5, min_samples=5) db_labels = db.fit_predict(X) # 注意:DBSCAN 可能把样本标为 -1(噪声),评估前需先统计非噪声样本占比 n_noise = list(db_labels).count(-1) print("Noise points:", n_noise, "of", len(db_labels))eps与min_samples是 DBSCAN 的两个核心参数,直接影响簇的粒度与噪声比例,可以在 notebook 中做小范围网格尝试并记录结果。
方案 C:高斯混合模型(Gaussian Mixture)
GMM 用多个高斯分布拟合数据,输出的是「样本属于各簇的概率」而非硬标签,适合簇形状偏椭圆的场景:
from sklearn.mixture import GaussianMixture from sklearn import metrics gmm = GaussianMixture(n_components=3, random_state=0) gmm_labels = gmm.fit_predict(X) score = metrics.silhouette_score(X, gmm_labels) print("GMM silhouette score:", score)无论如何都要做的三步收尾
- 与原实验对比:用同一份特征矩阵 X 和同一指标(silhouette score)与 K-Means 的 0.53 对照,回答「新方法是否改善了簇的质量」;
- 可视化:沿用课程中的
plt.scatter(df['popularity'], df['danceability'], c=labels)散点图画法,直观对比三种方法的簇形状; - 如实总结局限:不要为了「更好看」而夸大结论——如果新方法同样受制于数据方差与类不平衡,把它写进「What did you learn?」反而是加分项。
评分表解读:怎样才算「Vorbildlich(模范)」
作业附带的评分表(Rubric)是三档制,重点不在方法多高级,而在文档化程度:
| 标准 | 模范(Vorbildlich) | 合格(Angemessen) | 待改进(Verbesserungswürdig) |
|---|---|---|---|
| — | 提交一个文档完备的聚类模型 notebook | 提交一个缺乏良好文档和/或不完整的 notebook | 提交不完整的工作 |
对照此表,交付前请自查四点:
- 每个代码格前有 Markdown 说明:解释「为什么选这个方法、参数为何这么设」;
- 数据来源与预处理记录完整:注明数据集出处(课程数据来自 5-Clustering/data/nigerian-songs.csv,源于 Kaggle/Spotify),并交代过滤、编码步骤;
- 有评估指标与对比结论:至少给出 silhouette score 或噪声占比等可量化结果,并和 K-Means 基线对照;
- 无未运行的单元格、无报错输出:确保 notebook 从上到下可以一键顺序执行。
学习要点:这份作业真正想让你理解什么
结合课程 5-Clustering/2-K-Means/README.md 的「Variance」一节与挑战(Challenge)部分,这份作业的核心学习目标是:
- 没有万能聚类算法:K-Means 是最常用的方法,但它要求预设 k、偏好球形且等方差的簇,对离群点和量纲敏感;
- 指标会「说话」:silhouette score(0.53)和簇的散点形状已经提前预告了 K-Means 的不适配,学会读指标比盲目调参更重要;
- 特征工程能救场:课程挑战提示——对数据做标准化(standard scaling)后,虽然轮廓系数可能下降,但肘部图的「折点」会变得更平滑,因为不缩放的数据会让低方差特征占据过高权重;同理,换列、去离群点、加样本权重都能改变聚类结果;
- 对比才有意义:只有把非 K-Means 方法的结果放回 K-Means 的基线上比较,才能真正回答「为什么有时 K-Means 不合适」。
延伸阅读与参考资源
- 课程正文:5-Clustering/2-K-Means/README.md(K-Means、肘部法、轮廓系数、方差概念的完整讲解)
- 方法选型基础:5-Clustering/1-Visualize/README.md(Scikit-learn 聚类方法对照表与概念分类)
- 实验起点:5-Clustering/2-K-Means/notebook.ipynb(含数据导入、三种流派过滤、K-Means 与轮廓系数计算)
- 数据集:5-Clustering/data/nigerian-songs.csv(530 行、16 列 Spotify 尼日利亚歌曲特征)
- 解答参考:5-Clustering/2-K-Means/solution/notebook.ipynb(课程官方解法 notebook,可与自己的实现对照)
- 作业原文(英文):5-Clustering/2-K-Means/assignment.md
【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考