📜  高斯混合模型(1)

📅  最后修改于: 2023-12-03 15:42:32.671000             🧑  作者: Mango

高斯混合模型

高斯混合模型(Gaussian mixture model,GMM)是一种常见的聚类算法,适用于模式识别、图像分割、语音识别等领域,常用于非线性数据建模和密度估计。

原理

GMM 基于多维高斯分布组成的混合分布模型,其密度函数定义如下:

$$p(x) = \sum_{i=1}^{K}w_i \cdot \mathcal{N}(x|\mu_i, \Sigma_i)$$

其中,$w_i$ 表示第 $i$ 个高斯分布的权重,$\mu_i$ 表示均值向量,$\Sigma_i$ 表示协方差矩阵。

GMM 的目标是通过已知数据集,通过构建混合分布模型来估计数据集的密度分布模型,并通过代价函数的最小化来确定模型的参数。

实现

GMM 的实现通常使用期望最大化算法(Expectation-Maximization Algorithm,EM),该算法步骤如下:

  1. 随机初始化模型参数 $\theta = (\mu_i,\Sigma_i,w_i)$
  2. E步骤:计算每个样本属于每一个高斯分布的后验概率,即计算 $p(z_i=k|x_i,\theta)$
  3. M步骤:通过最大化对数似然函数来更新参数 $\theta$
  4. 重复 2-3 步,直到收敛

EM 算法的核心是计算后验概率和最大化对数似然函数,这两个步骤可以使用高斯分布的统计公式来计算。

示例

以下是使用 Python 实现 GMM 算法的代码示例:

import numpy as np
from scipy.stats import multivariate_normal


class GMM:
    def __init__(self, n_components, tol=1e-4, max_iter=100):
        self.n_components = n_components
        self.tol = tol
        self.max_iter = max_iter

    def _init_params(self, X):
        self.n_features = X.shape[1]

        self.pi = np.ones(self.n_components) / self.n_components
        self.mu = np.random.randn(self.n_components, self.n_features)
        self.sigma = np.tile(np.identity(self.n_features), (self.n_components, 1, 1))

    def _estimate_posterior(self, X):
        log_likelihoods = np.zeros((X.shape[0], self.n_components))

        for k in range(self.n_components):
            log_likelihoods[:, k] = np.log(self.pi[k]) + multivariate_normal.logpdf(X, self.mu[k], self.sigma[k])

        log_likelihood = np.sum(log_likelihoods, axis=1)
        posterior = np.exp(log_likelihoods - log_likelihood[:, np.newaxis])

        return posterior

    def _estimate_parameters(self, X, posterior):
        Nk = np.sum(posterior, axis=0)

        self.pi = Nk / X.shape[0]
        self.mu = posterior.T.dot(X) / Nk[:, np.newaxis]
        self.sigma = np.zeros((self.n_components, self.n_features, self.n_features))

        for k in range(self.n_components):
            X_centered = X - self.mu[k]
            self.sigma[k] = (posterior[:, k, np.newaxis] * X_centered).T.dot(X_centered) / Nk[k]

    def fit(self, X):
        self._init_params(X)

        for i in range(self.max_iter):
            old_params = (self.pi.copy(), self.mu.copy(), self.sigma.copy())

            posterior = self._estimate_posterior(X)
            self._estimate_parameters(X, posterior)

            if np.linalg.norm(np.array(old_params) - np.array((self.pi, self.mu, self.sigma))) < self.tol:
                break

该实现中使用了 Scipy 库的 multivariate_normal 模块来计算多维高斯分布密度函数,同时实现了 _init_params_estimate_posterior_estimate_parameters 三个方法分别用于初始化模型参数、计算后验概率和最大化对数似然函数。

我们可以使用以下代码来检验该实现是否正确:

X = np.concatenate((np.random.randn(100, 2), np.random.randn(100, 2) + 3))
gmm = GMM(n_components=2)
gmm.fit(X)

import matplotlib.pyplot as plt

plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=np.argmax(gmm._estimate_posterior(X), axis=1))
plt.show()

该示例中生成了一个包含两个二维高斯分布的数据集,经过 GMM 算法的拟合,可以得到聚类结果如下:

GMM 示例