You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用肘部法则确定GMM最优聚类数:绘图异常问题求助

GMM肘部法则图绘制问题解决思路

问题描述

我想绘制高斯混合模型(GMM)的肘部法则图来确定最优聚类数量,目前使用mean_属性计算样本到聚类中心的距离,但无法生成典型的肘部法则图,求解决思路?

当前代码:

from sklearn.mixture import GaussianMixture
from scipy.spatial.distance import cdist

def elbow_report(X):
    meandist = []
    n_clusters = range(2,15)
    for n_cluster in n_clusters:
        gmm = GaussianMixture(n_components=n_cluster)
        gmm.fit(X)
        meandist.append(
          sum(
            np.min(
              cdist(X, gmm.means_, 'mahalanobis', VI=gmm.precisions_), 
              axis=1
            ),
            X.shape[0]
          )
        )
    plt.plot(n_clusters,meandist,'bx-')
    plt.xlabel('Number of Clusters') 
    plt.ylabel('Mean Mahalanobis Distance') 
    plt.title('GMM Clustering for n_cluster=2 to 15')
    plt.show()

核心问题与解决步骤

1. 修复计算逻辑错误

你代码里的sum(..., X.shape[0])是关键错误:sum()的第二个参数是求和的初始值,不是用来求平均的除数。这会导致结果被额外加上样本数,完全偏离“平均距离”的计算逻辑,自然出不来肘部曲线。

正确的做法是先计算所有样本到最近聚类中心的最小马氏距离之和,再除以样本数得到平均值。

2. 选择更贴合GMM的评估指标

GMM是概率模型,单纯用距离的肘部法则效果有限,更推荐用BIC(贝叶斯信息准则)或AIC(赤池信息准则):

  • BIC/AIC会平衡模型拟合度和复杂度,数值先降后升,最低点对应的聚类数就是最优解;
  • 相比距离指标,这两个准则更能反映GMM的拟合质量,避免过拟合。

3. 确保模型收敛

默认迭代次数可能不够,建议设置max_iter=500,同时可以检查gmm.converged_属性确认模型是否收敛,避免无效结果。

修正后的代码示例

方案1:修正距离计算的肘部法则图

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
from scipy.spatial.distance import cdist

def elbow_report(X):
    mean_distances = []
    n_clusters = range(2, 15)
    for n_cluster in n_clusters:
        # 增加迭代次数,固定随机种子保证可复现
        gmm = GaussianMixture(n_components=n_cluster, max_iter=500, random_state=42)
        gmm.fit(X)
        # 计算每个样本到最近聚类中心的马氏距离,求平均值
        min_distances = np.min(cdist(X, gmm.means_, 'mahalanobis', VI=gmm.precisions_), axis=1)
        avg_distance = np.mean(min_distances)
        mean_distances.append(avg_distance)
    
    plt.plot(n_clusters, mean_distances, 'bx-')
    plt.xlabel('聚类数量')
    plt.ylabel('平均马氏距离')
    plt.title('GMM聚类肘部法则图(2-15类)')
    plt.show()

方案2:BIC/AIC准则图(更推荐)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

def gmm_model_selection(X):
    bic_scores = []
    aic_scores = []
    n_clusters = range(2, 15)
    for n_cluster in n_clusters:
        gmm = GaussianMixture(n_components=n_cluster, max_iter=500, random_state=42)
        gmm.fit(X)
        bic_scores.append(gmm.bic(X))
        aic_scores.append(gmm.aic(X))
    
    plt.figure(figsize=(10, 5))
    plt.plot(n_clusters, bic_scores, 'bx-', label='BIC')
    plt.plot(n_clusters, aic_scores, 'rx-', label='AIC')
    plt.xlabel('聚类数量')
    plt.ylabel('准则值')
    plt.title('GMM聚类BIC/AIC准则图(2-15类)')
    plt.legend()
    plt.show()

说明

用BIC/AIC时,曲线的最低点就是最优聚类数——BIC更倾向于选择更简洁的模型,AIC更看重拟合效果,两者结果相近时可信度更高。

内容的提问来源于stack exchange,提问作者Elliott de Launay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:18:19