Sklearn高斯混合模型predict_proba结果异常:中间样本概率为何失衡?
我们有两个可清晰分离的二维簇(如图所示)。使用Sklearn的高斯混合模型(GMM)对该数据集训练:
import numpy as np from sklearn.mixture import GaussianMixture gm = GaussianMixture(n_components=2, random_state=42, n_init= 100, init_params='random_from_data').fit(simpleblobs)
模型学习到的两个高斯分布均值与数据集簇中心相符:
gm.means_ array([[11.70833308, 13.83333333], [29.52666641, 36.19 ]])
但加入位于两簇间的样本middle_guy = (25,25)后,调用gm.predict_proba([middle_guy])得到结果array([[1.00000000e+00, 8.36394939e-66]]),即该样本几乎100%属于左下角簇,右上角簇概率接近0,与预期的近似[0.5,0.5]不符。请问该结果为何与预期不同?我忽略或误解了什么?
出现这个结果的核心原因是GMM的概率计算不仅依赖样本到均值的几何距离,还受各簇的协方差矩阵(以及簇权重)的影响——你只关注了均值的位置,却忽略了模型学习到的簇的分布范围和形状。
具体拆解:
- 你的两个簇是"清晰分离"的状态,说明每个簇内部样本分布非常紧凑,对应的协方差矩阵数值很小(也就是簇的"覆盖范围"极窄)。
- 计算中间点(25,25)到两个均值的欧氏距离:
- 到左下角簇均值的距离≈17.36
- 到右上角簇均值的距离≈12.07
可见它离右上角簇的均值更近,但概率却趋近于0,这说明右上角簇的协方差极小,导致该点完全落在它的分布范围之外。
GMM计算样本属于某簇的概率时,使用的是多元高斯分布的概率密度公式:p(x|k) = (1/(2π)^(d/2)|Σk|^(1/2)) * exp(-0.5*(x-μk)^T Σk^(-1) (x-μk))
其中Σk是第k个簇的协方差矩阵。如果右上角簇的协方差非常小,Σk的逆矩阵会被放大,导致指数部分的数值变得极小,最终概率密度趋近于0——哪怕样本离均值的几何距离不算远。
你可以通过查看模型的协方差和权重来验证这个结论:
print(gm.covariances_) # 查看两个簇的协方差矩阵 print(gm.weights_) # 查看两个簇的权重
大概率会看到右上角簇的协方差矩阵对角线元素(方差)远小于左下角簇,或者两个簇的方差都极小,但右上角簇的分布方向让中间点彻底脱离了它的覆盖范围。
总结:你预期的[0.5,0.5]是基于"几何中点"的直觉,但GMM的概率是基于统计分布的密度,不是几何距离的平分。当簇的分布极度紧凑时,哪怕中间点在几何上靠近两个簇,也可能完全不在其中一个簇的分布范围内,导致概率趋近于0。
内容的提问来源于stack exchange,提问作者Daniyal

