高斯混合模型 GMM · 深度手册
分类:聚类分类 | 难度:★★☆ 进阶 | 编号:
gmm
📊 数据视角:它到底有多常用?
本资料站收录 343 篇 优秀范文,GMM 共出现约 20 次,排名靠前。其中:
- 美赛(MCM/ICM):15 次,主要用于概率建模和聚类;
- 国赛(CUMCM):3 次;
- 电工杯 / 泰迪杯:约 2 次。
关键词覆盖:"GMM"、"高斯混合模型"、"EM算法"、"概率聚类"、"期望最大化" 等。
一句话:GMM 是 K-Means 的概率升级版——不是把点硬分配到某个簇,而是说"这个点有 70% 概率属于簇 1,25% 概率属于簇 2,5% 属于簇 3",用 EM 算法迭代求解。
一、这是什么(一句话用途)
软聚类 / 概率密度估计 / 生成模型(客户分群、异常检测、语音识别)
二、核心思想
高斯混合模型(Gaussian Mixture Model, GMM)假设数据由 K 个高斯分布混合生成:
其中 是第 k 个分量的混合系数(), 是高斯分布。
与 K-Means 的区别:
- K-Means:硬分配——每个点属于且仅属于一个簇
- GMM:软分配——每个点以一定概率属于每个簇
- K-Means:簇是球形等大小的
- GMM:簇可以是椭圆、不同大小、不同方向(通过协方差矩阵)
三、数学原理与推导
3.1 模型定义
GMM 的参数:
似然函数:
3.2 EM 算法(Expectation-Maximization)
E步(期望):计算每个点属于每个簇的后验概率(责任度)
M步(最大化):更新参数
迭代 E-M 直到收敛。
3.3 BIC/AIC 选 K
其中 为参数个数。选 BIC/AIC 最小的 K。
四、建模 / 求解步骤
- 数据标准化
- 选择 K 值(BIC/AIC 或肘部法)
- 初始化参数(K-Means 结果初始化)
- EM 迭代至收敛
- 评估:对数似然、BIC、聚类效果
五、Python 实现示例
5.1 从零手写 GMM(对角协方差)
import numpy as np
class GMM:
def __init__(self, K=3, max_iter=100, tol=1e-6):
self.K = K
self.max_iter = max_iter
self.tol = tol
def _gaussian(self, X, mu, cov):
"""计算高斯概率密度"""
diff = X - mu
inv_cov = np.linalg.inv(cov)
det = np.linalg.det(cov)
exponent = -0.5 * np.sum(diff @ inv_cov * diff, axis=1)
return (1.0 / np.sqrt((2*np.pi)**X.shape[1] * det)) * np.exp(exponent)
def fit(self, X):
N, D = X.shape
# 用 K-Means 初始化
rng = np.random.default_rng(42)
idx = rng.choice(N, self.K, replace=False)
self.mu = X[idx].copy()
self.pi = np.ones(self.K) / self.K
self.cov = np.array([np.cov(X.T) for _ in range(self.K)])
log_likelihood_prev = -np.inf
for iteration in range(self.max_iter):
# E-step
responsibilities = np.zeros((N, self.K))
for k in range(self.K):
responsibilities[:, k] = self.pi[k] * self._gaussian(X, self.mu[k], self.cov[k])
responsibilities /= responsibilities.sum(axis=1, keepdims=True)
# M-step
N_k = responsibilities.sum(axis=0)
self.pi = N_k / N
for k in range(self.K):
diff = X - self.mu[k]
weighted_diff = responsibilities[:, k:k+1] * diff
self.mu[k] = (responsibilities[:, k] @ X) / N_k[k]
self.cov[k] = (weighted_diff.T @ diff) / N_k[k]
# 检查收敛
log_likelihood = np.sum(np.log(responsibilities @ np.array([self._gaussian(X, self.mu[k], self.cov[k]) for k in range(self.K)]).T + 1e-300)))
if abs(log_likelihood - log_likelihood_prev) < self.tol:
print(f'收敛于迭代 {iteration+1}')
break
log_likelihood_prev = log_likelihood
self.responsibilities_ = responsibilities
return self
def predict(self, X):
return np.argmax(self.responsibilities_, axis=1)
# 测试
np.random.seed(42)
X = np.vstack([
np.random.randn(100, 2) * [1, 2] + [0, 0],
np.random.randn(100, 2) * [2, 1] + [5, 5],
np.random.randn(100, 2) * [0.5, 0.5] + [10, 0],
])
gmm = GMM(K=3).fit(X)
print(f"混合系数: {np.round(gmm.pi, 3)}")
print(f"均值:\n{np.round(gmm.mu, 2)}")
5.2 使用 sklearn
import numpy as np
from sklearn.mixture import GaussianMixture
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
np.random.seed(42)
# 椭圆形状的簇
X1 = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]], 100)
X2 = np.random.multivariate_normal([5, 5], [[2, -0.5], [-0.5, 0.5]], 100)
X = np.vstack([X1, X2])
# 用 BIC 选 K
bic_scores = []
for K in range(1, 7):
gmm = GaussianMixture(n_components=K, random_state=42)
gmm.fit(X)
bic_scores.append(gmm.bic(X))
best_K = np.argmin(bic_scores) + 1
print(f"最优 K = {best_K} (BIC最小)")
# 拟合最终模型
gmm = GaussianMixture(n_components=best_K, random_state=42).fit(X)
labels = gmm.predict(X)
probas = gmm.predict_proba(X)
print(f"混合系数: {np.round(gmm.weights_, 3)}")
print(f"均值:\n{np.round(gmm.means_, 2)}")
print(f"协方差:\n{np.round(gmm.covariances_, 2)}")
六、MATLAB 实现示例
%% GMM 聚类(MATLAB/Octave)
rng(42);
% 生成数据
X1 = randn(100,2) + [0,0];
X2 = randn(100,2) + [5,5];
X = [X1; X2];
% 使用内置 gmdistribution
K = 2;
gmm = fitgmdist(X, K);
labels = posterior(gmm, X);
labels = categorical(labels == max(labels, [], 2));
% BIC 选 K
BIC = inf;
for k = 1:5
temp = fitgmdist(X, k);
if temp.BIC < BIC
BIC = temp.BIC;
bestK = k;
end
end
fprintf('最优 K = %d, BIC = %.2f\n', bestK, BIC);
% 输出参数
disp('均值:'); disp(gmm.mu);
disp('混合系数:'); disp(gmm.weights);
七、GMM vs K-Means 对比
| 特性 | K-Means | GMM |
|---|---|---|
| 分配方式 | 硬分配 | 软分配(概率) |
| 簇形状 | 球形 | 椭圆形(可旋转) |
| 参数 | 只需 K | K + 均值 + 协方差 + 混合系数 |
| 计算复杂度 | O(nKt) | O(nKtd) |
| 解释性 | 简单 | 概率语义强 |
八、常见误区与避坑清单
| 误区 | 正确做法 |
|---|---|
| K 随便选 | 用 BIC/AIC 选最优 K |
| 协方差矩阵奇异 | 加正则化项或对角协方差 |
| 不标准化直接拟合 | 必须先 StandardScaler |
| 初始化太随机 | 用 K-Means 结果初始化 |
| 忽略对数似然收敛 | 检查 log_likelihood 是否单调递增 |
九、论文写作技巧
本文采用高斯混合模型(GMM)进行软聚类。GMM 假设数据由 K 个高斯分布混合生成,通过 EM 算法迭代求解参数。与 K-Means 的硬分配不同,GMM 给出每个样本属于各簇的概率,更适合存在重叠簇的场景。经 BIC 准则选择,最优簇数 K=3。
十、相关手册(延伸阅读)
- K-Means 聚类 · 聚类分类
- DBSCAN 密度聚类 · 聚类分类
完整算例(数字演示,照着算一遍)
场景:1 维数据 200 点,呈双峰,用 GMM(K=2) 拟合。
EM 迭代:收敛后两成分权重 π=(0.6,0.4),均值 μ=(2.0,5.5),方差 σ²=(1.0,1.2)。
结论:数据被分为两类,各自服从高斯分布,软归属按后验概率分配。
十一、本手册导航
- 上一篇:K-Means 聚类 · 聚类分类
- 下一篇:DBSCAN 密度聚类 · 聚类分类
- 返回:算法深度手册库 | 资料站首页
本手册由「算法深度手册生成器」自动产出。