在之前的篇章中,我们介绍了高斯混合模型(GMM)及其基本实现。本文将扩展这一模型,重点是引入早停机制来提高训练效率,并且在训练过程中每隔一定的迭代次数绘制聚类结果,以便观察模型的收敛情况。
引入早停机制
为了避免不必要的计算,我们可以在训练过程中引入早停机制。具体来说,当对数似然(Log-Likelihood)在迭代过程中不再显著改善时,我们将停止迭代。由于对数似然值在概率模型中通常为负数,优化时我们期望这个值变得更小,但要注意不要忽略负号。
代码实现
下面是修改后的 GMM 代码示例,它实现了早停机制并在每5次迭代后绘制当前的聚类结果:
python">from scipy.stats import multivariate_normal
import math
from sklearn.datasets import make_blobs
import numpy as np
import matplotlib.pyplot as plt# 生成数据
X, y = make_blobs(n_samples=1500, cluster_std=[1.0, 3.5, 0.5], random_state=42)# 初始化参数
m, n = X.shape
K = 3
max_iter = 20
tol = 1e-4
oldNLL = -np.inf# 初始化责任矩阵、混合系数、均值和协方差矩阵
r = np.full(shape=(m, K), fill_value=1/K)
pi = np.full((K,), fill_value=1/K)
random_row = np.random.randint(low=0, high=m, size=K)
mean = np.array([X[idx, :] for idx in random_row]).T
cov = np.array([np.cov(X.T) for _ in range(K)])for iteration in range(max_iter):# E步:更新每个样本的责任矩阵for i in range(m):for k in range(K):xi_pdf = multivariate_normal.pdf(X[i], mean=mean[:, k], cov=cov[k])r[i, k] = pi[k] * xi_pdfr[i] /= np.sum(r[i])# 计算对数似然NLL = 0for i in range(m):for k in range(K):NLL += math.log(pi[k])NLL += multivariate_normal.logpdf(X[i], mean=mean[:, k], cov=cov[k])# 检查对数似然是否改进if np.abs(NLL - oldNLL) < tol:print(f"Converged at iteration {iteration}")breakoldNLL = NLL# 每5次迭代绘制一次聚类结果if iteration % 5 == 0:preds = np.argmax(r, axis=1)plt.figure(figsize=(8, 6))plt.scatter(X[:, 0], X[:, 1], c=preds, cmap='viridis', s=30)plt.title(f'GMM Clustering at Iteration {iteration}')plt.show()
总结
通过添加早停机制,我们可以显著减少计算时间,尤其是在处理大规模数据时。此外,定期绘制聚类结果有助于可视化模型的收敛过程和结果。虽然 Mini-Batch K-means 和传统的 K-means 已经可以处理简单的聚类任务,但 GMM 提供了更复杂的数据建模能力,适用于需要捕捉簇形状和大小差异的场景。
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!