ML-For-Beginners 聚类模块实战:用 K-Means 与数据可视化分析尼日利亚音乐品味

发布时间:2026/9/10 3:54:07
ML-For-Beginners 聚类模块实战:用 K-Means 与数据可视化分析尼日利亚音乐品味 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聚类Clustering是机器学习中一类典型的无监督学习任务它自动在无标签数据中寻找彼此相似的对象并将其归入称为簇cluster的组别。本篇文章以 ML-For-Beginners 开源课程的第五模块5-Clustering为核心完整讲解聚类的概念体系、Scikit-learn 支持的聚类算法选型以及一个贯穿两节课的真实项目——用 Spotify 尼日利亚歌曲数据探索听众的音乐品味。读完本文你将掌握如何对无标签数据进行探索性可视化、如何用 K-Means 建立聚类模型、如何用轮廓系数silhouette score与肘部法elbow method评估和调优聚类效果。聚类无监督学习的核心任务聚类是一种机器学习任务它寻找彼此相似的对象并将这些对象归入被称为簇的组。聚类与其他机器学习方法最大的区别在于整个过程自动发生。事实上可以公允地说聚类是监督学习的对立面——它假设数据集没有标签或输入没有与预定义的输出匹配然后使用各种算法在无标签数据中筛选并按照识别出的模式输出分组。聚类的应用场景非常广泛市场细分判断哪些年龄群体购买哪些商品异常检测在信用卡交易数据中发现欺诈行为医学影像在一系列医学扫描中圈定肿瘤区域搜索结果分组按购物链接、图片或评论聚合搜索结果大数据集降维分析在构建其他模型之前先用聚类了解数据隐私保护数据被组织成簇后可分配一个簇 ID用簇 ID 而非更具识别性的原始数据来引用数据点。有趣的是聚类分析起源于 1930 年代的人类学与心理学领域。当你的数据已带有标签时此前课程中学过的分类技术通常更合适但当你要对无标签数据分组时聚类是发现模式的绝佳途径。区域主题尼日利亚听众的音乐品味本模块的区域主题是为尼日利亚听众的音乐品味建立聚类模型。尼日利亚多元的人口拥有同样多元的音乐品味。课程使用从 Spotify 抓取的数据数据集 5-Clustering/data/nigerian-songs.csv原始来源为 Kaggle基于 Spotify 数据观察在尼日利亚流行的音乐。该数据集包含每首歌曲的以下特征特征含义danceability舞蹈性评分0~1acousticness声学性原声程度0~1loudness响度dBspeechiness语音性含歌词说话成分的多少0~1popularity流行度评分energy能量0~1instrumentalness器乐性0~1liveness现场感0~1tempo速度BPMtime_signature拍号length时长毫秒release_date发行年份这个数据集共 530 条记录、16 列。在本模块的课程中我们将发现这些数据中隐藏的模式——它是否会按歌曲的可舞性水平聚拢出某种尼日利亚听众的品味倾向本模块共包含两节课对应仓库中的两个子目录引入聚类数据可视化与探索——对应 Notebook 5-Clustering/1-Visualize/notebook.ipynbK-Means 聚类——对应 Notebook 5-Clustering/2-K-Means/notebook.ipynb。选择合适的聚类算法Scikit-learn 方法总览Scikit-learn 提供了大量执行聚类的方法选择哪种取决于你的具体用例。根据官方文档每种方法都有各自的优势。下表是课程中给出的、Scikit-learn 支持的聚类方法及其适用场景的简化对照表方法名适用场景K-Means通用目的归纳式inductiveAffinity propagation亲和传播多而形状不规则的簇归纳式Mean-shift均值漂移多而形状不规则的簇归纳式谱聚类Spectral clustering少量、均匀的簇转导式transductiveWard 层次聚类多而受限的簇转导式凝聚聚类Agglomerative clustering多而受限、非欧几里得距离的簇转导式DBSCAN非平面几何、形状不规则的簇转导式OPTICS非平面几何、密度变化的形状不规则簇转导式高斯混合Gaussian mixtures平面几何归纳式BIRCH含离群点的大数据集归纳式要真正读懂这张表需要理解几个关键术语转导式 vs 归纳式transductive vs inductive转导式推理由观测到的训练实例推导直接映射到特定测试实例归纳式推理则从训练实例推导出通用规则再将这些规则应用于测试实例。课程中的例子假设数据集中部分对象是黑胶唱片、部分是CD还有一部分是空白的。若采用归纳式方法训练一个寻找黑胶唱片和CD的模型再把标签套到无标签数据上——这种方法在遇到真正是磁带的对象时会分类困难。而转导式方法直接对相似对象分组再给整组贴一个标签此时簇可能反映的是圆形音乐物件与方形音乐物件。非平面 vs 平面几何non-flat vs flat geometry源自数学术语指用平面欧几里得还是非平面非欧几里得几何方法测量点间距离。欧几里得距离被量化为两点之间线段的长度非欧几里得距离则沿曲线测量。如果你的数据可视化后看起来并不处于一个平面上可能需要专门的算法处理。距离distances簇由其距离矩阵定义。欧几里得簇由点值的平均值定义包含一个质心centroid或中点距离即到该质心的距离非欧几里得距离则引用簇中心点clustroid——即离其他点最近的点clustroid 可以有多种定义方式。受限constrained受限聚类在无监督方法中引入了半监督学习——点之间的关系被标记为cannot link或must-link从而对数据集施加某些规则。例如如果让算法自由处理一批无标签或半标签数据它可能把圆形音乐物件方形音乐物件三角形物件和蛋糕聚在一起如果给它一些约束物件必须是塑料做的物件必须能播放音乐就能约束算法做出更好的选择。密度density被视为嘈杂的数据被认为是稠密的。其各簇内点与点之间的距离经考察可能或密或疏因此需要用合适的聚类方法分析这类数据。课程提到K-Means 与 HDBSCAN 算法在处理含不规则簇密度的嘈杂数据集时表现不同。五类主流聚类算法现存超过 100 种聚类算法具体采用哪种取决于数据性质。课程着重讨论了以下几种主要类别层次聚类Hierarchical clustering如果一个对象依据其与邻近对象而非较远对象的接近程度被归类那么簇将根据其成员到其他对象的距离形成。Scikit-learn 的凝聚聚类即属于层次聚类。质心聚类Centroid clustering这种流行的算法需要选择k即要形成的簇的数量然后算法确定簇的中心点并围绕该点收集数据。K-Means 聚类是质心聚类的流行版本。中心点由最近的均值决定由此得名簇的平方距离被最小化。基于分布的聚类Distribution-based clustering基于统计建模聚焦于确定一个数据点属于某个簇的概率并据此分配。高斯混合方法属于此类。基于密度的聚类Density-based clustering数据点根据其密度或彼此聚集的程度被分配到簇中远离群体的点被视为离群点或噪声。DBSCAN、Mean-shift 和 OPTICS 属于此类。基于网格的聚类Grid-based clustering对于多维数据集创建网格并将数据划分到网格的单元格之间从而形成簇。第一课实操数据探索与可视化聚类技术非常依赖正确的可视化第一课的目标就是在动手聚类之前先充分了解数据的性质从而判断该用哪种聚类方法。课程对应的 Notebook 位于 5-Clustering/1-Visualize/notebook.ipynb。安装依赖并加载数据首先安装Seaborn包以获得良好的数据可视化能力然后加载歌曲数据!pip install seaborn import matplotlib.pyplot as plt import pandas as pd df pd.read_csv(../data/nigerian-songs.csv) df.head()数据加载后前几行记录如下部分namealbumartistartist_top_genrerelease_datelengthpopularitydanceabilityacousticnessenergyinstrumentalnesslivenessloudnessspeechinesstempotime_signatureSparkyMandy The JungleCruel Santinoalternative rb2019144000480.6660.8510.420.5340.11-6.6990.0829133.0155shuga rushEVERYTHING YOU HEARD IS TRUEOdunsi (The Engine)afropop202089488300.710.08220.6830.0001690.101-5.640.36129.9933LITT!LITT!AYLØindie rb2018207758400.8360.2720.5640.0005370.11-7.1270.0424130.0054Confident / Feeling CoolEnjoy Your LifeLady Donlinigerian pop2019175135140.8940.7980.6110.0001870.0964-4.9610.113111.0874wanted yourare.Odunsi (The Engine)afropop2018152049250.7020.1160.8330.910.348-6.0440.0447105.1154检查数据质量调用info()查看 DataFrame 的结构信息df.info()输出显示RangeIndex: 530 entries, 0 to 529共 16 列其中name、album、artist、artist_top_genre为 object 类型release_date、length、popularity、time_signature为 int64其余 8 列为 float64总内存占用约 66.4 KB。接着检查是否存在空值df.isnull().sum()输出显示所有 16 列的非空计数均为 0数据没有缺失值。再用describe()查看统计摘要df.describe()关键统计信息包括popularity的均值约 17.5、中位数 13、最小值 0说明存在未获得评分的歌曲后续需要剔除danceability的均值约 0.74范围 0.255~0.966loudness的范围为 -19.362~0.582 dBtempo范围为 61.695~206.007 BPM。思考既然聚类是不需要标签的无监督方法为什么还要带着标签查看数据因为在数据探索阶段标签是有用的但它们并不是聚类算法运行所必需的——你完全可以去掉列标题只用列号引用数据。分析最受欢迎的流派用条形图找出最受欢迎的流派取前 5 名import seaborn as sns top df[artist_top_genre].value_counts() plt.figure(figsize(10,7)) sns.barplot(xtop[:5].index,ytop[:5].values) plt.xticks(rotation45) plt.title(Top genres,color blue)注意图中若出现名为 Missing 的流派表示 Spotify 尚未对其进行分类应当剔除。同时前三大流派afro dancehall、afropop、nigerian pop远远主导了该数据集。因此课程进一步过滤数据只保留这三个流派并去掉popularity为 0 的记录这些歌曲没有流行度评级可视为噪声df df[(df[artist_top_genre] afro dancehall) | (df[artist_top_genre] afropop) | (df[artist_top_genre] nigerian pop)] df df[(df[popularity] 0)] top df[artist_top_genre].value_counts() plt.figure(figsize(10,7)) sns.barplot(xtop.index,ytop.values) plt.xticks(rotation45) plt.title(Top genres,color blue)相关性分析快速检验数据之间是否存在特别强的相关性corrmat df.corr(numeric_onlyTrue) f, ax plt.subplots(figsize(12, 9)) sns.heatmap(corrmat, vmax.8, squareTrue)从相关性热图可以观察到唯一较强的相关性存在于energy与loudness之间——这并不令人意外因为响亮的音乐通常相当有能量。除此之外各特征间的相关性相对较弱。这正是聚类算法可以发挥作用的场景数据维度间没有强线性结构但可能存在非线性或局部的聚集模式。注意相关性并不意味着因果性我们拥有的是相关的证据而不是因果的证据。数据分布与散点图用jointplot绘制三个流派在popularity与danceability两个轴上的分布sns.set_theme(styleticks) g sns.jointplot( datadf, xpopularity, ydanceability, hueartist_top_genre, kindkde, )该示例使用 KDE核密度估计图用连续的概率密度曲线表示数据便于在存在多个分布时解读数据。结果显示三个流派在流行度和可舞性方面大致松散地聚合在一起存在围绕某个一般收敛点的同心圆分布。要在这些松散对齐的数据中确定簇将是一项挑战。再绘制普通散点图sns.FacetGrid(df, hueartist_top_genre, height5) \ .map(plt.scatter, popularity, danceability) \ .add_legend()散点图显示了类似的收敛模式。一般来说在聚类中你会用散点图来展示数据的簇所以掌握这种可视化类型非常有用。第一课的结论是带着这些过滤后的数据进入下一课用 K-Means 聚类去发现数据中那些以有趣方式重叠的组。第一课的课后任务5-Clustering/1-Visualize/assignment.md要求研究不同的散点图制作方法与库在一个 Notebook 中记录至少五个有良好文档说明的散点图并解释你的发现。第二课实操用 K-Means 建立聚类模型第二课学习如何使用 Scikit-learn 和前面导入的尼日利亚音乐数据集创建簇覆盖 K-Means 的基础知识并引入四个核心概念轮廓系数、肘部法、惯性inertia、方差variance。Notebook 位于 5-Clustering/2-K-Means/notebook.ipynb其中包含了上一课完成的数据导入与初步清洗。K-Means 的原理K-Means 聚类是一种源自信号处理领域的方法用于通过一系列观测将数据划分partition为k个簇。每个观测都致力于将给定数据点分组到离它最近的均值即簇的中心点。簇可以被可视化为Voronoi 图图中包含一个点或种子及其对应的区域。K-Means 的聚类过程按照一个三步流程执行算法从数据集中抽样选择 k 个中心点然后迭代以下步骤将每个样本分配给最近的中心点取所有被分配给先前中心点的样本的平均值创建新的中心点计算新旧中心点之间的差异并重复迭代直到中心点稳定下来。K-Means 的一个缺点是你必须事先确定k中心点的数量。幸运的是肘部法可以帮助估算一个好的 k 起始值。观察数据中的离群点首先再次审视歌曲数据用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)这些数据有点嘈杂通过箱线图观察每一列可以看到离群点的存在。你也可以遍历数据集移除这些离群点但那会让数据变得相当贫乏。课程选择暂时保留它们。特征选择与标签编码为聚类练习选择量纲相近的列并将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是输入特征矩阵y是真实流派标签用于事后对照评估聚类效果。训练第一个 K-Means 模型已知数据集中剥离出 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输出是一个数组为 DataFrame 的每一行给出预测的簇编号0、1 或 2。用轮廓系数评估聚类质量使用该数组计算轮廓系数from sklearn import metrics score metrics.silhouette_score(X, y_cluster_kmeans) score轮廓系数在 -1 到 1 之间取值。接近 1 的分数意味着簇既紧密又与相邻簇分离良好接近 0 的值表示簇之间重叠样本非常接近相邻簇的决策边界。本例中我们的得分是0.53属于中等水平。这提示这些数据并非特别适合这种聚类方式但课程选择继续推进。肘部法与 WCSS/惯性接下来导入KMeans并启动聚类过程通过循环尝试 1~10 个簇计算每个 k 值的 WCSSfrom 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 到 10 个簇。random_state决定用于初始化中心点的随机数生成来源Scikit-learnKMeans文档设定固定值可保证结果可复现。WCSS即within-cluster sums of squares簇内平方和衡量一个簇内所有点到簇中心点的平方平均距离。惯性inertiaK-Means 算法试图选择使惯性最小化的中心点惯性是簇内部一致性的度量。每次迭代的该值被追加到wcss变量中。k-meansScikit-learn 中可用的k-means优化它初始化中心点时让它们总体上彼此远离可能比随机初始化产生更好的结果。然后使用肘部法绘制 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变量绘制图表观察肘部的拐点它指示最优簇的数量。对于该数据拐点确实出现在 3 处——之前假设的 3 个簇是正确的选择。可视化簇并评估准确率再次以 3 个簇运行聚类并将簇以散点图展示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()对照真实标签检查模型的准确率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)))这个模型的准确率并不理想而簇的形状给出了原因这些数据过于不平衡、相关性太弱列值之间的方差过大无法形成良好的簇。事实上形成的簇很可能受到我们上面定义的三个流派类别的强烈影响或偏差。这是一次有教育意义的尝试在 Scikit-learn 的文档中可以看到像这样簇边界不清晰的模型存在方差问题。方差问题与改进方向方差被定义为与均值之差的平方的平均值。在本聚类问题的语境中它指数据集中数字往往偏离均值过多的趋势。这是一个思考如何修正问题的好时机对数据做更多的调整使用其他列换一种算法课程给出的关键提示是尝试缩放scale数据以进行归一化并测试其他列。Notebook 中有被注释掉的代码可以通过添加标准缩放standard scaling让各数据列在取值范围上更接近。你会发现当数据不缩放时方差较小的数据会获得更大的权重。值得注意的权衡是——数据经缩放后虽然轮廓分数会下降但肘部图的拐点会变得更加平滑清晰。第二课的课后挑战5-Clustering/2-K-Means/assignment.md建议花时间调整 Notebook 中的参数尝试进一步清洗数据例如移除离群点、使用权重给予特定数据点更多权重或尝试不同的聚类方法看看能否改善模型。挑战为生产环境梳理聚类算法作为第一课的挑战任务请整理一份你会在生产环境中遇到并使用的不同聚类算法清单并思考聚类试图解决哪些类型的问题在应用聚类算法之前理解数据集的本质是一个好习惯不同聚类算法面对不同类型数据时的行为差异很大。第二课还提供了一个 K-Means 模拟器思路可视化样本点并确定它们的中心点通过调整数据的随机性、簇的数量和中心点的数量直观感受数据如何被分组。小结通过本模块两节课的完整实战我们完成了以下闭环理解聚类本质自动化的无监督任务与监督学习相对适用于无标签数据算法选型掌握 Scikit-learn 十种聚类方法的适用场景理解转导式/归纳式、平面/非平面几何、受限聚类与密度等核心概念数据探索用info()、isnull()、describe()完成数据质量检查用条形图、相关性热图、KDE 联合分布图与 FacetGrid 散点图完成可视化判断建模与评估用 LabelEncoder 编码类别特征、K-Means 聚类、轮廓系数定量评估、肘部法确定 k 值并最终认识到数据太不平衡、方差过大这一真实问题的存在及其改进方向数据缩放、换列、换算法。整个流程体现了机器学习工程中一条重要的经验法则先理解数据再选择算法用可视化驱动决策用指标验证假设。你也可以在仓库对应的两个 Notebook 与翻译文档translations/da/5-Clustering/中继续深入研读每一处代码细节。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考