Scikit-learn GaussianMixture 实战:3种协方差矩阵对比与聚类效果可视化

📅 2026/7/6 12:25:54
Scikit-learn GaussianMixture 实战:3种协方差矩阵对比与聚类效果可视化
Scikit-learn GaussianMixture 实战3种协方差矩阵对比与聚类效果可视化1. 高斯混合模型的核心概念高斯混合模型Gaussian Mixture Model, GMM是一种基于概率的聚类算法它假设数据是由多个高斯分布组合生成的。与K-means等硬聚类算法不同GMM属于软聚类方法能够给出每个样本属于各个簇的概率。关键数学概念每个高斯分布由均值向量μ和协方差矩阵Σ定义混合系数α表示各高斯分布的权重满足∑α1概率密度函数p(x) ∑αᵢN(x|μᵢ,Σᵢ)在实际应用中GMM通过EM算法迭代优化这些参数E步计算样本属于各分布的概率责任值M步根据责任值更新分布参数2. 协方差矩阵类型解析Scikit-learn的GaussianMixture提供了4种协方差矩阵类型直接影响聚类形状类型参数数量形状特点适用场景fullD(D1)/2每个簇有完全独立的协方差矩阵各簇形状方向均不同tiedD(D1)/2所有簇共享同一个协方差矩阵簇形状相同但位置不同diagD对角矩阵特征间独立各轴缩放比例不同spherical1对角且元素相同σ²I各向同性分布from sklearn.mixture import GaussianMixture # 创建不同协方差类型的GMM模型 gmm_full GaussianMixture(n_components3, covariance_typefull) gmm_tied GaussianMixture(n_components3, covariance_typetied) gmm_diag GaussianMixture(n_components3, covariance_typediag)3. 实战案例鸢尾花数据集聚类3.1 数据准备与可视化import matplotlib.pyplot as plt from sklearn.datasets import load_iris import numpy as np # 加载数据 iris load_iris() X iris.data[:, :2] # 只使用前两个特征便于可视化 y iris.target # 可视化原始数据 plt.scatter(X[:, 0], X[:, 1], cy, s40, cmapviridis) plt.title(Iris True Labels) plt.xlabel(Sepal length) plt.ylabel(Sepal width)3.2 不同协方差矩阵效果对比我们创建可视化函数来比较三种主要协方差类型def plot_gmm(gmm, X, title): # 训练模型 gmm.fit(X) # 预测聚类结果 labels gmm.predict(X) # 创建网格用于绘制决策边界 x_min, x_max X[:, 0].min() - 1, X[:, 0].max() 1 y_min, y_max X[:, 1].min() - 1, X[:, 1].max() 1 xx, yy np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100)) Z gmm.predict(np.c_[xx.ravel(), yy.ravel()]) Z Z.reshape(xx.shape) # 绘制结果 plt.figure(figsize(8, 6)) plt.contourf(xx, yy, Z, alpha0.3) plt.scatter(X[:, 0], X[:, 1], clabels, s40, cmapviridis) # 绘制椭圆表示协方差 for i in range(gmm.n_components): # 计算2D协方差椭圆 if gmm.covariance_type full: cov gmm.covariances_[i][:2, :2] elif gmm.covariance_type tied: cov gmm.covariances_[:2, :2] elif gmm.covariance_type diag: cov np.diag(gmm.covariances_[i][:2]) elif gmm.covariance_type spherical: cov np.eye(2) * gmm.covariances_[i] v, w np.linalg.eigh(cov) angle np.arctan2(w[0][1], w[0][0]) angle 180 * angle / np.pi # 转换为度 v 2. * np.sqrt(2.) * np.sqrt(v) ell plt.matplotlib.patches.Ellipse(gmm.means_[i, :2], v[0], v[1], 180 angle, colorblack) ell.set_clip_box(plt.gca().bbox) ell.set_alpha(0.5) plt.gca().add_artist(ell) plt.title(title) plt.xlabel(Sepal length) plt.ylabel(Sepal width) # 比较三种主要类型 plot_gmm(gmm_full, X, GMM with full covariance) plot_gmm(gmm_tied, X, GMM with tied covariance) plot_gmm(gmm_diag, X, GMM with diagonal covariance)3.3 性能指标对比我们使用轮廓系数和BIC贝叶斯信息准则评估模型from sklearn.metrics import silhouette_score models { full: gmm_full, tied: gmm_tied, diag: gmm_diag, spherical: GaussianMixture(n_components3, covariance_typespherical) } results [] for name, model in models.items(): model.fit(X) labels model.predict(X) sil_score silhouette_score(X, labels) bic model.bic(X) results.append({ type: name, silhouette: sil_score, BIC: bic }) # 展示结果对比 import pandas as pd df_results pd.DataFrame(results) print(df_results.sort_values(silhouette, ascendingFalse))典型输出结果covariance_typesilhouette_scoreBICfull0.52580diag0.48610tied0.45595spherical0.426254. 高级应用技巧4.1 确定最佳聚类数使用BIC和轮廓系数确定最优组件数n_components np.arange(1, 8) bics [] silhouettes [] for n in n_components: gmm GaussianMixture(n_componentsn, covariance_typefull) gmm.fit(X) bics.append(gmm.bic(X)) labels gmm.predict(X) silhouettes.append(silhouette_score(X, labels)) # 绘制结果 fig, ax1 plt.subplots() ax2 ax1.twinx() ax1.plot(n_components, bics, b-, labelBIC) ax2.plot(n_components, silhouettes, r-, labelSilhouette) ax1.set_xlabel(Number of components) ax1.set_ylabel(BIC, colorb) ax2.set_ylabel(Silhouette, colorr) plt.title(Optimal Number of Components)4.2 处理高维数据当特征维度较高时建议先使用PCA降维选择diag或spherical减少参数数量使用BayesianGaussianMixture自动确定组件数from sklearn.decomposition import PCA from sklearn.mixture import BayesianGaussianMixture # 高维数据处理示例 X_highdim iris.data # 使用全部4个特征 # 方法1PCA降维 pca PCA(n_components2) X_pca pca.fit_transform(X_highdim) gmm_pca GaussianMixture(n_components3, covariance_typefull) gmm_pca.fit(X_pca) # 方法2自动确定组件数 bgmm BayesianGaussianMixture(n_components10, covariance_typediag) bgmm.fit(X_highdim) print(f实际使用的组件数: {np.sum(bgmm.weights_ 0.01)})5. 常见问题解决方案问题1模型收敛警告解决方案增加max_iter或tol参数或尝试不同初始化gmm GaussianMixture(n_components3, covariance_typefull, max_iter500, tol1e-4, init_paramskmeans)问题2奇异矩阵错误解决方案使用更简单的协方差类型或添加正则化gmm GaussianMixture(n_components3, covariance_typediag, reg_covar1e-6) # 添加小的正则化项问题3聚类结果不稳定解决方案固定random_state或使用BayesianGaussianMixturegmm GaussianMixture(n_components3, covariance_typefull, random_state42)