Scikit-learn 1.4.2 GMM 实战3步完成鸢尾花数据集聚类与概率可视化鸢尾花数据集是机器学习领域的经典案例但如何用概率视角解读其分类特性本文将用Scikit-learn 1.4.2最新版本的高斯混合模型GMM带您实现从数据加载到三维概率可视化的完整流程。不同于传统硬聚类方法GMM能给出每个数据点属于各类别的概率分布这对理解数据重叠区域特别有价值。1. 环境准备与数据理解在开始建模前我们需要配置合适的工具链并深入理解数据特性。现代Python数据科学栈为我们提供了高效的工具组合# 核心工具库 import numpy as np import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # Scikit-learn组件 from sklearn.datasets import load_iris from sklearn.mixture import GaussianMixture from sklearn.preprocessing import StandardScaler # 可视化扩展 import seaborn as sns plt.style.use(seaborn-v0_8-whitegrid)鸢尾花数据集包含150个样本每个样本有4个特征萼片长度、萼片宽度、花瓣长度、花瓣宽度和对应的品种标签。我们先进行探索性分析iris load_iris() X iris.data y iris.target features iris.feature_names target_names iris.target_names print(f特征矩阵形状: {X.shape}) print(f特征名称: {features}) print(f目标类别: {target_names})通过pairplot可以直观看到各类别的分布情况df pd.DataFrame(X, columnsfeatures) df[species] [target_names[i] for i in y] sns.pairplot(df, huespecies, palettehusl, height2.5) plt.show()关键观察花瓣长度和宽度呈现明显的类别可分性萼片特征存在较多重叠区域setosa与其他两类线性可分versicolor和virginica在部分特征空间有重叠2. GMM模型构建与训练Scikit-learn的GaussianMixture类提供了完整的GMM实现。我们需要重点关注三个核心参数n_components混合高斯成分数量covariance_type协方差矩阵类型init_params初始化策略2.1 数据预处理虽然GMM对数据尺度不敏感但标准化能提升EM算法的收敛速度scaler StandardScaler() X_scaled scaler.fit_transform(X) # 保留标准化参数用于后续逆变换 mean_vec scaler.mean_ scale_vec scaler.scale_2.2 模型训练与组件选择通过BIC贝叶斯信息准则确定最优成分数n_components_range range(1, 8) bic_values [] for n in n_components_range: gmm GaussianMixture(n_componentsn, covariance_typefull, random_state42) gmm.fit(X_scaled) bic_values.append(gmm.bic(X_scaled)) plt.plot(n_components_range, bic_values, bo-) plt.xlabel(Number of Components) plt.ylabel(BIC Score) plt.title(BIC for GMM) plt.show()BIC曲线解读当n_components3时BIC达到最低点验证了数据中确实存在三个自然类别更多成分会导致过拟合2.3 最终模型训练best_n 3 final_gmm GaussianMixture(n_componentsbest_n, covariance_typefull, random_state42) final_gmm.fit(X_scaled) # 获取训练结果 cluster_probs final_gmm.predict_proba(X_scaled) cluster_labels final_gmm.predict(X_scaled)模型参数解析weights_: 各高斯成分的混合权重means_: 各高斯成分的均值向量covariances_: 各高斯成分的协方差矩阵3. 结果可视化与分析3.1 二维特征空间投影选择信息量最大的两个特征进行可视化plt.figure(figsize(12, 6)) # 真实类别分布 plt.subplot(121) sns.scatterplot(xX[:, 2], yX[:, 3], huey, paletteviridis) plt.title(True Species Distribution) plt.xlabel(Petal Length) plt.ylabel(Petal Width) # GMM聚类结果 plt.subplot(122) sns.scatterplot(xX[:, 2], yX[:, 3], huecluster_labels, paletteviridis) plt.title(GMM Cluster Assignment) plt.xlabel(Petal Length) plt.ylabel(Petal Width) plt.tight_layout() plt.show()对比分析GMM正确分离了setosa类别versicolor和virginica的边界区域存在少量误分类概率模型能更好处理重叠区域3.2 三维概率分布可视化创建三维空间展示各点的最大类别概率# 准备三维绘图数据 x X[:, 2] # 花瓣长度 y X[:, 3] # 花瓣宽度 z np.max(cluster_probs, axis1) # 最大概率值 fig plt.figure(figsize(10, 8)) ax fig.add_subplot(111, projection3d) # 按真实类别着色 colors [r, g, b] for i in range(best_n): mask (y i) ax.scatter(x[mask], y[mask], z[mask], ccolors[i], labeltarget_names[i], s40, alpha0.7) ax.set_xlabel(Petal Length) ax.set_ylabel(Petal Width) ax.set_zlabel(Cluster Probability) ax.set_title(3D Probability Distribution by True Species) ax.legend() plt.show()关键发现类别中心区域概率接近1.0边界区域概率值在0.5-0.8之间setosa类别的概率分布最集中virginica在边缘有概率下降趋势3.3 决策边界与概率等高线# 创建网格数据 petal_length np.linspace(X[:,2].min()-0.5, X[:,2].max()0.5, 100) petal_width np.linspace(X[:,3].min()-0.5, X[:,3].max()0.5, 100) xx, yy np.meshgrid(petal_length, petal_width) grid_data np.column_stack([xx.ravel(), yy.ravel()]) # 标准化网格数据(仅使用花瓣特征) grid_scaled (grid_data - mean_vec[2:]) / scale_vec[2:] full_grid np.zeros((len(grid_scaled), 4)) full_grid[:, 2:] grid_scaled # 预测网格点概率 Z final_gmm.predict_proba(full_grid)[:, 0] # setosa概率 Z Z.reshape(xx.shape) # 绘制等高线 plt.figure(figsize(10, 8)) contour plt.contourf(xx, yy, Z, levels20, cmapRdYlBu) plt.colorbar(contour, labelSetosa Probability) # 叠加原始数据点 sns.scatterplot(xX[:, 2], yX[:, 3], huey, paletteviridis, edgecolork, s80) plt.title(Probability Contour for Setosa Class) plt.xlabel(Petal Length) plt.ylabel(Petal Width) plt.show()工程实践建议对于高维数据建议先进行PCA降维再应用GMM初始化使用k-means通常比随机初始化收敛更快监控收敛过程可通过设置verbose2参数大数据集可考虑使用max_iter和tol参数控制训练时间# 高级配置示例 gmm_optimized GaussianMixture( n_components3, covariance_typefull, init_paramskmeans, max_iter500, tol1e-4, verbose2, random_state42 )