
ML-For-Beginners 实战用 Scikit-learn 对尼日利亚音乐数据集做 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-Clustering/2-K-Means」一课的完整技术指南围绕课程仓库中的 translations/en/5-Clustering/2-K-Means/README.md 与配套 notebook.ipynb 展开。你将学会用 Scikit-learn 对上一课清洗好的尼日利亚音乐数据执行 K-Means 聚类掌握 Silhouette 评分、肘部法则Elbow Method、WCSS/Inertia、Variance 等核心概念并能够通过箱线图、散点图对聚类结果进行诊断与优化。读完本文你将具备一套完整的「数据检查 → 特征编码 → 聚类建模 → 指标评估 → 结果可视化 → 问题定位」的无监督学习实战流程。K-Means 聚类原理与三步迭代流程K-Means 是一种源自信号处理领域的聚类技术用于根据一系列观测将数据划分成 k 个簇。每个观测都会被分配到离它最近的均值即簇的中心点附近从而形成分组。在课程中聚类结果可以被可视化为 Voronoi 图——由一个个种子点seed及其对应的区域构成K-Means 的核心过程遵循一个三步迭代流程算法先从数据集中采样选出 k 个中心点然后进入循环将每个样本分配到最近的质心centroid对分配给同一旧质心的所有样本求均值生成新的质心计算新旧质心之间的差异重复以上步骤直到质心趋于稳定。这个「分配-更新-收敛」的循环正是 Scikit-learn 中KMeans.fit()在底层反复执行的动作以 notebook.ipynb 中km.fit(X)为例fit 过程结束后质心收敛模型即可用于predict输出每个样本的簇编号。K-Means 最大的局限在于你必须预先定义 k质心数量。幸运的是后文介绍的肘部法则可以帮助你估计一个较好的初始 k 值。课程还指出聚类方法的选择取决于数据本身——上一课 5-Clustering/1-Visualize/README.md 中列出了 K-Means、Affinity propagation、Mean-shift、DBSCAN、Gaussian mixtures 等多种方法及适用场景K-Means 是其中最通用的一种。前置准备数据集与运行环境本课的工作基于课程目录下的 notebook.ipynb 文件它承接了上一课的数据导入与初步清洗结果。数据来源是 5-Clustering/data/nigerian-songs.csv包含 530 行、16 列字段包括name、album、artist、artist_top_genre、release_date、length、popularity、danceability、acousticness、energy、instrumentalness、liveness、loudness、speechiness、tempo、time_signature。在上一课中已经完成了关键清洗剔除artist_top_genre为Missing的记录仅保留afro dancehall、afropop、nigerian pop三个主流流派删除popularity为 0 的记录即未参与排名的噪声数据。notebook 中加载数据的代码如下import matplotlib.pyplot as plt import pandas as pd import seaborn as sns df pd.read_csv(../../data/nigerian-songs.csv) df.head()运行前需要确保环境中已安装pandas、matplotlib、seaborn以及scikit-learnnotebook 第一步即通过pip install seaborn完成依赖准备。练习一数据准备——用箱线图检查离群值聚类效果对数据的分布形态非常敏感因此在建模前先观察每个特征的分布。对数据框的每一列调用boxplot()绘制箱线图plt.figure(figsize(20,20), dpi200) plt.subplot(4,3,1) sns.boxplot(x popularity, data df) plt.subplot(4,3,2) sns.boxplot(x acousticness, data df) plt.subplot(4,3,3) sns.boxplot(x energy, data df) plt.subplot(4,3,4) sns.boxplot(x instrumentalness, data df) plt.subplot(4,3,5) sns.boxplot(x liveness, data df) plt.subplot(4,3,6) sns.boxplot(x loudness, data df) plt.subplot(4,3,7) sns.boxplot(x speechiness, data df) plt.subplot(4,3,8) sns.boxplot(x tempo, data df) plt.subplot(4,3,9) sns.boxplot(x time_signature, data df) plt.subplot(4,3,10) sns.boxplot(x danceability, data df) plt.subplot(4,3,11) sns.boxplot(x length, data df) plt.subplot(4,3,12) sns.boxplot(x release_date, data df)通过逐列观察箱线图可以发现数据存在一定噪声离群值。当然你可以选择手动剔除这些离群点但那样会导致数据量大幅缩水本课暂时保留它们。接下来选择量纲相近的列用于聚类并用LabelEncoder将artist_top_genre编码为数值from sklearn.preprocessing import LabelEncoder le LabelEncoder() X df.loc[:, (artist_top_genre,popularity,danceability,acousticness,loudness,energy)] y df[artist_top_genre] X[artist_top_genre] le.fit_transform(X[artist_top_genre]) y le.transform(y)这里X是用于聚类的特征矩阵6 个特征y是流派标签。需要注意K-Means 是无监督算法y在聚类阶段并不参与训练只用于后续评估聚类结果与真实流派标签的吻合程度。由于数据集中保留了 3 个流派先用 3 个簇建立初步模型from sklearn.cluster import KMeans nclusters 3 seed 0 km KMeans(n_clustersnclusters, random_stateseed) km.fit(X) # Predict the cluster for each data point y_cluster_kmeans km.predict(X) y_cluster_kmeans输出是一个数组其中每个元素是数据框中每一行对应的预测簇编号0、1 或 2。接着用这个数组计算轮廓系数Silhouette Scorefrom sklearn import metrics score metrics.silhouette_score(X, y_cluster_kmeans) score深入理解 Silhouette Score轮廓系数轮廓系数是衡量聚类质量的核心指标取值范围为 -1 到 1接近 1簇内部密集且与其他簇分离良好——这是理想状态接近 0簇之间存在重叠样本紧邻相邻簇的决策边界接近 -1样本很可能被分配到了错误的簇。本课数据计算出的轮廓系数约为0.53处于中等水平说明该数据并不特别适合这种聚类方式但课程选择继续推进以便完整演示流程并分析原因。补充参考仓库中同课的 R 实现 5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb 使用cluster包的silhouette()函数计算平均轮廓宽度得到约0.549的分数同样处于中间水平——两种语言实现得出的结论一致该数据集的簇边界并不清晰。练习二构建模型——WCSS、Inertia 与 k-means接下来系统性地评估不同 k 值下的聚类质量。引入KMeans对 k1 到 10 逐一建模并记录每次的 inertiafrom sklearn.cluster import KMeans wcss [] for i in range(1, 11): kmeans KMeans(n_clusters i, init k-means, random_state 42) kmeans.fit(X) wcss.append(kmeans.inertia_)这段代码中的几个关键概念range(1, 11)聚类过程的迭代次数即尝试 k1 到 k10 共 10 种簇数量random_state控制质心初始化的随机数生成设为固定值如 42可保证结果可复现WCSSWithin-Cluster Sum of Squares簇内平方和度量一个簇内所有点到簇质心的距离平方平均值Inertia惯性K-Means 算法致力于选择使 inertia 最小化的质心inertia 是簇内部一致性的度量。每次迭代后inertia 的值被追加到wcss列表中k-meansScikit-learn 提供的质心初始化优化策略它让初始质心彼此大体上相距较远通常比完全随机初始化得到更好的结果。肘部法则Elbow Method确定最优 k 值之前假设 k3 是基于数据中有 3 个流派的直觉但直觉需要验证。用前面积累的wcss绘制折线图plt.figure(figsize(10,5)) sns.lineplot(xrange(1, 11), ywcss, markero, colorred) plt.title(Elbow) plt.xlabel(Number of clusters) plt.ylabel(WCSS) plt.show()图中 WCSS 随 k 增大而下降曲线出现弯折bend的位置对应的 k 就是最优簇数量。从结果看拐点确实出现在3附近——之前的猜测得到了验证从 R 实现 lesson_15-R.ipynb 的表述看WCSS 从 1 到 2、2 到 3 时下降明显之后衰减放缓肘部出现在约 3 个簇处印证了数据中存在两到三个分离得较好的簇群这一判断。练习三显示聚类结果并评估准确率用 k3 重新拟合模型并把结果绘制成散点图from sklearn.cluster import KMeans kmeans KMeans(n_clusters 3) kmeans.fit(X) labels kmeans.predict(X) plt.scatter(df[popularity],df[danceability],c labels) plt.xlabel(popularity) plt.ylabel(danceability) plt.show()用popularity与danceability两个维度着色展示聚类结果然后检查模型准确率labels kmeans.labels_ correct_labels sum(y labels) print(Result: %d out of %d samples were correctly labeled. % (correct_labels, y.size)) print(Accuracy score: {0:0.2f}. format(correct_labels/float(y.size)))这里的逻辑是把 K-Means 输出的簇标签与真实的流派编码y逐一比对统计一致的数量。结果显示模型准确率并不理想而散点图的形状揭示了原因数据过于不均衡、特征间相关性弱、各列取值范围差异过大导致难以有效聚类。事实上形成的簇很可能被我们预先定义的 3 个流派类别严重左右——这正是 K-Means 面对标签泄漏式先验时的典型表现。按照 Scikit-learn 官方文档的归类这种簇边界模糊不清的模型存在Variance方差问题。Variance聚类失败的根本原因方差的定义是与均值之差的平方的平均值。在本聚类问题中它意味着数据集中的数值偏离均值过远、分布过于发散。数据不均衡、特征相关性弱、列间量纲差异大三者叠加使得基于欧氏距离的 K-Means 难以找到紧凑且分离的簇结构。那么如何修正课程给出了几条思考方向进一步清洗数据例如剔除离群值换用不同的特征列改用其他聚类算法对数据进行标准化scaling使其分布归一化。挑战尝试用标准化改进聚类课程挑战环节建议你在 notebook 中调整参数尝试提升模型准确率例如进一步清洗数据如删除离群值使用样本权重让某些样本在聚类中占有更大权重对特征做标准化。notebook 中已经预留了被注释掉的标准化代码StandardScaler与scaler.fit_transform(X)。需要留意一个反直觉的现象加入标准化后轮廓系数反而下降而肘部曲线的拐折变得更平滑。这是因为不缩放数据时方差较小的特征如popularity会因数值量级小而失去影响一旦标准化所有特征被拉到同一尺度原本主导聚类的特征被稀释簇结构反而变得不那么清晰。也就是说K-Means 对特征尺度敏感缩放与否取决于你对哪些特征应该主导聚类的取舍。这正是数据科学家需要反复实验调参的原因。延伸学习与课后作业课程提供了一份 K-Means 交互式模拟器可在其中调整数据的随机性、簇数量与质心数量帮助直观理解数据如何被分组另推荐了斯坦福大学 CS221 课程的 K-Means 讲义作为自学材料课后作业 5-Clustering/2-K-Means/assignment.md 要求你换一种非 K-Means 的聚类方法例如层次聚类、DBSCAN 或高斯混合模型用本课或其他来源的数据构建一个文档完备的聚类 notebook并总结学到了什么——这提醒我们K-Means 并不总是合适的选择理解多种聚类方法的适用场景可回顾上一课的算法对比表同样重要仓库中的 solution/notebook.ipynb 提供了本课的完整参考答案R 语言学习者可对照 lesson_15-R.ipynb其中还特别建议使用多个nstart随机起点运行 K-Means以规避局部最优解加深理解。小结本课完整演示了 K-Means 聚类的实战链路从箱线图检查离群值、用 LabelEncoder 编码类别特征到设置 k、计算轮廓系数、用肘部法则验证 k 的选择再到散点图可视化与准确率评估最后定位到 Variance 问题并提出标准化等改进方向。核心结论值得牢记轮廓系数 0.53 与中等准确率表明这套音乐数据在流派簇的假设下并不适合 K-Means——聚类算法不会自动发现你心中的标签数据形态、特征尺度与 k 的选择共同决定了结果的质量。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考