前言
提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。
文章目录
- 前言
- 聚类算法
- 经典应用场景
- 高斯混合模型
- 优点
- 缺点
- 总结
- 简单实例(函数库实现)
- 高斯分布
- 代码解析
- 数学表达
- 1. 基本概念
- 2. 数学模型
- 2.1 生成模型
- 2.2 混合分布
- 3. 参数估计
- 3.1 E 步骤(Expectation Step)
- 3.2 M 步骤(Maximization Step)
- 4. 应用
- 总结
- 手动实现
- 代码分析
聚类算法
聚类算法在各种领域中有广泛的应用,主要用于发现数据中的自然分组和模式。以下是一些常见的应用场景以及每种算法的优缺点:
经典应用场景
-
市场细分:根据消费者的行为和特征,将他们分成不同的群体,以便进行有针对性的营销。
-
图像分割: 将图像划分为多个区域或对象,以便进行进一步的分析或处理。
-
社交网络分析:识别社交网络中的社区结构。
-
文档分类:自动将文档分组到不同的主题或类别中。
-
异常检测识别数据中的异常点或异常行为。
-
基因表达分析:在生物信息学中,根据基因表达模式对基因进行聚类。
高斯混合模型
高斯混合模型
高斯混合模型(Gaussian Mixture Models, GMM)是一种用于聚类和密度估计的概率模型。它假设数据集由多个高斯分布的线性组合构成,每个高斯分布代表一个聚类。下面是 GMM 的优缺点。优点
- 灵活性:
- GMM 可以捕捉任意形状的聚类,因为它使用多个高斯分布的组合来拟合数据。与 K-means 只能形成球形聚类不同,GMM 能够建模椭圆形和不规则形状的聚类。
- 概率模型:
- GMM 提供每个点属于每个聚类的概率,允许对模糊边界的聚类进行建模。这使得 GMM 在处理具有重叠或不确定性的聚类时比硬聚类方法更具优势。
- 统计推断:
- GMM 可以利用统计方法进行模型选择和参数估计,例如使用期望最大化(EM)算法进行参数估计。
- 适用于复杂数据:
- GMM 可以处理高维数据,并且可以通过调整成分数量来适应数据的复杂性。
缺点
- 对初始条件敏感:
- GMM 的效果往往依赖于初始参数设置,尤其是高斯分布的数量和初始均值。选择不当可能导致局部最优解。
- 计算复杂性:
- GMM 的计算复杂度比某些其他聚类方法(如 K-means)要高。EM 算法在每个迭代中都需要计算所有点到所有高斯成分的概率,处理大型数据集时可能会变得缓慢。
- 需要选择成分数量:
- 选择合适的高斯成分数量(即聚类数量)通常是一个挑战。选择不当可能导致过拟合或欠拟合。
- 对异常值敏感:
- GMM 对异常值比较敏感,尤其是在高斯分布的均值和方差估计时。异常值可能会显著影响模型参数的估计。
- 假设数据分布:
- GMM 假设数据是由高斯分布生成的,但在某些情况下,数据可能并不符合这一假设。这可能会导致模型性能下降。
总结
高斯混合模型是一种灵活且强大的聚类方法,适用于多种应用场景,尤其是在数据具有复杂结构时。然而,它也具有一定的局限性,特别是在选择模型参数和对异常值的敏感性方面。在实际应用中,选择合适的聚类方法需要根据数据的特性和分析目标进行权衡。
简单实例(函数库实现)
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture# 生成样本数据
np.random.seed(42)
n_samples = 300# 创建两个高斯分布的数据
X1 = np.random.normal(loc=0, scale=0.5, size=(n_samples, 2)) + np.array([0, -2])
X2 = np.random.normal(loc=0, scale=0.5, size=(n_samples, 2)) + np.array([2, 2])
X3 = np.random.normal(loc=0, scale=0.5, size=(n_samples, 2)) + np.array([-2, 2])# 合并数据
X = np.vstack((X1, X2, X3))# 可视化生成的数据
plt.scatter(X[:, 0], X[:, 1], s=10)
plt.title('Generated Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()# 创建高斯混合模型
n_components = 3 # 设定聚类的数量
gmm = GaussianMixture(n_components=n_components, random_state=42)# 拟合模型
gmm.fit(X)# 预测聚类标签
labels = gmm.predict(X)# 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels, s=10, cmap='viridis')
plt.title('GMM Clustering Results')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.colorbar(label='Cluster Label')
plt.show()# 输出每个组件的参数
for i in range(n_components):print(f"Component {i+1}:")print(f" Mean: {gmm.means_[i]}")print(f" Covariance: {gmm.covariances_[i]}")
data数据分布与代码运行结果:
高斯分布
高斯分布(又称正态分布)是统计学中最重要的概率分布之一,具有广泛的应用。以下是高斯分布的数学公式和相关概念:
- 高斯分布的定义
在一维情况下,均值为 μ \mu μ、标准差为 σ \sigma σ 的高斯分布的概率密度函数(PDF)可以表示为:
f ( x ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x - \mu)^2}{2\sigma^2}} f(x)=σ2π1e−2σ2(x−μ)2
- x x x 是随机变量。
- μ \mu μ 是均值,表示分布的中心。
- σ \sigma σ 是标准差,表示数据的离散程度。
- e e e 是自然对数的底数(约为 2.71828)。
- 高斯分布的性质
2.1 对称性
高斯分布是对称的,均值 μ \mu μ 是分布的中心。即,对于任何 x x x,有:
f ( μ + x ) = f ( μ − x ) f(\mu + x) = f(\mu - x) f(μ+x)=f(μ−x)
2.2 特殊点
- 均值:分布的中心点,决定了分布的平移。
- 方差:方差 σ 2 \sigma^2 σ2 决定了分布的宽度,更大的方差表示数据点的分布更加分散。
2.3 68-95-99.7 规则
在标准正态分布中(即 μ = 0 \mu = 0 μ=0 和 σ = 1 \sigma = 1 σ=1):- 约 68% 的数据位于均值的一个标准差范围内( μ ± σ \mu \pm \sigma μ±σ)。
- 约 95% 的数据位于均值的两个标准差范围内( μ ± 2 σ \mu \pm 2\sigma μ±2σ)。
- 约 99.7% 的数据位于均值的三个标准差范围内( μ ± 3 σ \mu \pm 3\sigma μ±3σ)。
- 多维高斯分布
在多维情况下,假设随机向量 x \mathbf{x} x 是一个 d d d 维的随机变量,其均值为 μ \boldsymbol{\mu} μ 和协方差矩阵为 Σ \Sigma Σ,则其概率密度函数为:
f ( x ) = 1 ( 2 π ) d ∣ Σ ∣ e − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) f(\mathbf{x}) = \frac{1}{\sqrt{(2\pi)^d |\Sigma|}} e^{-\frac{1}{2} (\mathbf{x} - \boldsymbol{\mu})^T \Sigma^{-1} (\mathbf{x} - \boldsymbol{\mu})} f(x)=(2π)d∣Σ∣1e−21(x−μ)TΣ−1(x−μ)
- ∣ Σ ∣ |\Sigma| ∣Σ∣ 是协方差矩阵的行列式。
- Σ − 1 \Sigma^{-1} Σ−1 是协方差矩阵的逆矩阵。
- x − μ \mathbf{x} - \boldsymbol{\mu} x−μ 是一个 d d d 维列向量。
- 应用
高斯分布在许多领域中都非常重要,包括:
- 统计推断:用于许多参数估计和假设检验方法。
- 机器学习:许多算法的基础假设是数据遵循高斯分布。
- 信号处理:用于建模噪声。
结论
高斯分布因其数学性质和在自然界中的广泛存在,成为了统计学和数据科学中的基础工具。通过高斯分布,我们能够有效地描述和理解各种现象。
代码解析
np.random.seed(42)
:设置随机种子为 42,确保每次运行代码时生成的随机数相同。这样可以使结果可重复,有助于调试和结果验证。X1 = np.random.normal(loc=0, scale=0.5, size=(n_samples, 2)) + np.array([0, -2])
这个函数用于生成符合正态分布的随机数。其参数意义如下:
loc=0
: 这个参数指定正态分布的均值(mean),在这里为 0。scale=0.5
: 这个参数指定标准差(standard deviation),在这里为 0.5。size=(n_samples, 2)
: 这个参数指定生成样本的形状,表明要生成 n _ s a m p l e s n\_samples n_samples 个样本,每个样本有 2 个特征。
因此,这部分代码生成的随机变量 Z Z Z 服从以下的二维正态分布:
Z ∼ N ( ( 0 0 ) , ( 0. 5 2 0 0 0. 5 2 ) ) Z \sim \mathcal{N}\left(\begin{pmatrix} 0 \\ 0 \end{pmatrix}, \begin{pmatrix} 0.5^2 & 0 \\ 0 & 0.5^2 \end{pmatrix}\right) Z∼N((00),(0.52000.52))
生成的样本 X 1 X1 X1 服从以下的二维正态分布:
X 1 ∼ N ( ( 0 − 2 ) , ( 0.25 0 0 0.25 ) ) X1 \sim \mathcal{N}\left(\begin{pmatrix} 0 \\ -2 \end{pmatrix}, \begin{pmatrix} 0.25 & 0 \\ 0 & 0.25 \end{pmatrix}\right) X1∼N((0−2),(0.25000.25))
3.X = np.vstack((X1, X2, X3))
np.vstack()
是 NumPy 中的一个函数,用于将多个数组沿垂直方向堆叠。其参数可以是一个包含多个数组的元组或列表。所有数组的列数必须相同,以确保它们能够正确地堆叠在一起。X1
、X2
、X3
:这些变量通常是之前生成的样本集合,可能代表来自不同类别或不同分布的数据。假设它们的形状分别为 ( n 1 , 2 ) (n_1, 2) (n1,2)、 ( n 2 , 2 ) (n_2, 2) (n2,2) 和 ( n 3 , 2 ) (n_3, 2) (n3,2),表示每个样本集有 n 1 n_1 n1、 n 2 n_2 n2和 n 3 n_3 n3 个样本,每个样本有 2 个特征。生成的新数组X
的形状将为 ( n 1 + n 2 + n 3 , 2 ) (n_1 + n_2 + n_3, 2) (n1+n2+n3,2).
数学表达
高斯混合模型 (Gaussian Mixture Model, GMM) 是一种用于表征具有多个高斯分布成分的概率模型,它常用于聚类、密度估计、数据生成等任务。下面将结合数学公式详细讲解 GMM 的基本概念和相关公式。
1. 基本概念
GMM 假设数据点来自于多个不同的高斯分布,每个分布称为一个“成分”。这些成分共同形成一个混合模型,能够更好地捕捉数据的多样性。GMM 中的每个高斯成分都由其均值、协方差和权重定义。
2. 数学模型
假设我们有 K K K 个高斯成分,每个成分 k k k 的参数如下:
- 均值(Mean): μ k ∈ R d \mu_k \in \mathbb{R}^d μk∈Rd
- 协方差矩阵(Covariance Matrix): Σ k ∈ R d × d \Sigma_k \in \mathbb{R}^{d \times d} Σk∈Rd×d
- 权重(Weight): π k \pi_k πk (满足 ∑ k = 1 K π k = 1 \sum_{k=1}^{K} \pi_k = 1 ∑k=1Kπk=1, π k ≥ 0 \pi_k \geq 0 πk≥0)
2.1 生成模型
GMM 的生成过程可以表示为:
- 从类别 k k k 的权重分布中选择一个成分 k k k:
P ( Z = k ) = π k P(Z=k) = \pi_k P(Z=k)=πk
其中 Z Z Z 表示选择的成分。- 在选择的成分 k k k 下,从对应的高斯分布中生成样本 X X X:
X ∣ Z = k ∼ N ( μ k , Σ k ) X | Z=k \sim \mathcal{N}(\mu_k, \Sigma_k) X∣Z=k∼N(μk,Σk)
内容补充页(相关公式解释)
2.2 混合分布
因此,整个数据的概率密度函数 (PDF) 可以表示为:
P ( X ) = ∑ k = 1 K π k ⋅ N ( X ∣ μ k , Σ k ) P(X) = \sum_{k=1}^{K} \pi_k \cdot \mathcal{N}(X | \mu_k, \Sigma_k) P(X)=k=1∑Kπk⋅N(X∣μk,Σk)
其中 N ( X ∣ μ k , Σ k ) \mathcal{N}(X | \mu_k, \Sigma_k) N(X∣μk,Σk) 是第 k k k 个高斯成分的概率密度函数,定义为:
N ( X ∣ μ k , Σ k ) = 1 ( 2 π ) d / 2 ∣ Σ k ∣ 1 / 2 exp ( − 1 2 ( X − μ k ) ⊤ Σ k − 1 ( X − μ k ) ) \mathcal{N}(X | \mu_k, \Sigma_k) = \frac{1}{(2\pi)^{d/2} |\Sigma_k|^{1/2}} \exp\left(-\frac{1}{2} (X - \mu_k)^{\top} \Sigma_k^{-1} (X - \mu_k)\right) N(X∣μk,Σk)=(2π)d/2∣Σk∣1/21exp(−21(X−μk)⊤Σk−1(X−μk))3. 参数估计
为了从数据中估计 GMM 的参数 { π k , μ k , Σ k } \{ \pi_k, \mu_k, \Sigma_k \} {πk,μk,Σk},我们通常使用期望最大化(EM)算法。EM 算法为 GMM 提供了一种有效的迭代方法。
3.1 E 步骤(Expectation Step)
在 E 步骤中,我们计算后验概率 P ( Z = k ∣ X ) P(Z=k | X) P(Z=k∣X):
γ n k = P ( Z = k ∣ X n ) = π k ⋅ N ( X n ∣ μ k , Σ k ) ∑ j = 1 K π j ⋅ N ( X n ∣ μ j , Σ j ) \gamma_{nk} = P(Z=k | X_n) = \frac{\pi_k \cdot \mathcal{N}(X_n | \mu_k, \Sigma_k)}{\sum_{j=1}^{K} \pi_j \cdot \mathcal{N}(X_n | \mu_j, \Sigma_j)} γnk=P(Z=k∣Xn)=∑j=1Kπj⋅N(Xn∣μj,Σj)πk⋅N(Xn∣μk,Σk)
其中 γ n k \gamma_{nk} γnk 是数据点 X n X_n Xn 属于成分 k k k 的责任度。3.2 M 步骤(Maximization Step)
在 M 步骤中,我们更新参数:
- 权重:
π k = 1 N ∑ n = 1 N γ n k \pi_k = \frac{1}{N} \sum_{n=1}^{N} \gamma_{nk} πk=N1n=1∑Nγnk- 均值:
μ k = ∑ n = 1 N γ n k X n ∑ n = 1 N γ n k \mu_k = \frac{\sum_{n=1}^{N} \gamma_{nk} X_n}{\sum_{n=1}^{N} \gamma_{nk}} μk=∑n=1Nγnk∑n=1NγnkXn- 协方差矩阵:
Σ k = ∑ n = 1 N γ n k ( X n − μ k ) ( X n − μ k ) ⊤ ∑ n = 1 N γ n k \Sigma_k = \frac{\sum_{n=1}^{N} \gamma_{nk} (X_n - \mu_k)(X_n - \mu_k)^{\top}}{\sum_{n=1}^{N} \gamma_{nk}} Σk=∑n=1Nγnk∑n=1Nγnk(Xn−μk)(Xn−μk)⊤4. 应用
高斯混合模型广泛应用于以下领域:
- 聚类(如图像分割、市场细分)
- 密度估计(生成模型)
- 异常检测(识别与模型不一致的数据点)
总结
高斯混合模型通过多个高斯成分的线性组合来建模复杂的分布,能够有效地捕捉数据的多样性。通过 EM 算法,GMM 可以从数据中学习到每个成分的参数,进而实现分类、聚类等多种任务。
手动实现
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normalclass GaussianMixtureModel:def __init__(self, n_components, max_iter=100, tol=1e-6):self.n_components = n_componentsself.max_iter = max_iterself.tol = toldef initialize_parameters(self, X):n_samples, n_features = X.shapeself.weights = np.ones(self.n_components) / self.n_componentsself.means = X[np.random.choice(n_samples, self.n_components, replace=False)]self.covariances = np.array([np.cov(X, rowvar=False)] * self.n_components)def e_step(self, X):n_samples = X.shape[0]self.responsibilities = np.zeros((n_samples, self.n_components))for k in range(self.n_components):pdf = multivariate_normal(mean=self.means[k], cov=self.covariances[k])self.responsibilities[:, k] = self.weights[k] * pdf.pdf(X)self.responsibilities /= self.responsibilities.sum(axis=1, keepdims=True)def m_step(self, X):n_samples, n_features = X.shapeeffective_n = self.responsibilities.sum(axis=0)self.means = np.dot(self.responsibilities.T, X) / effective_n[:, np.newaxis]self.covariances = np.zeros((self.n_components, n_features, n_features))for k in range(self.n_components):X_centered = X - self.means[k]self.covariances[k] = (self.responsibilities[:, k][:, np.newaxis] * X_centered).T @ X_centeredself.covariances[k] /= effective_n[k]self.weights = effective_n / n_samplesdef fit(self, X):self.initialize_parameters(X)log_likelihood_old = 0for iteration in range(self.max_iter):self.e_step(X)self.m_step(X)log_likelihood = 0for k in range(self.n_components):pdf = multivariate_normal(mean=self.means[k], cov=self.covariances[k])log_likelihood += np.sum(self.responsibilities[:, k] * np.log(self.weights[k] * pdf.pdf(X) + 1e-10))if np.abs(log_likelihood - log_likelihood_old) < self.tol:print(f"Converged at iteration {iteration}")breaklog_likelihood_old = log_likelihooddef predict(self, X):n_samples = X.shape[0]likelihoods = np.zeros((n_samples, self.n_components))for k in range(self.n_components):pdf = multivariate_normal(mean=self.means[k], cov=self.covariances[k])likelihoods[:, k] = self.weights[k] * pdf.pdf(X)return np.argmax(likelihoods, axis=1)# 可视化结果
def plot_results(X, labels, means, covariances):plt.figure(figsize=(8, 6))unique_labels = np.unique(labels)colors = ['r', 'g', 'b', 'c', 'm', 'y']for i, label in enumerate(unique_labels):plt.scatter(X[labels == label, 0], X[labels == label, 1], s=20, color=colors[i % len(colors)], label=f"Cluster {label + 1}")# 绘制高斯分布的等高线mean = means[label]cov = covariances[label]x, y = np.meshgrid(np.linspace(X[:, 0].min() - 1, X[:, 0].max() + 1, 100),np.linspace(X[:, 1].min() - 1, X[:, 1].max() + 1, 100))pos = np.dstack((x, y))rv = multivariate_normal(mean, cov)plt.contour(x, y, rv.pdf(pos), levels=5, colors=colors[i % len(colors)], alpha=0.5)plt.title("Gaussian Mixture Model Clustering")plt.xlabel("Feature 1")plt.ylabel("Feature 2")plt.legend()plt.show()# 测试
if __name__ == "__main__":np.random.seed(42)X1 = np.random.normal(0, 1, (100, 2))X2 = np.random.normal(5, 1, (100, 2))X3 = np.random.normal(10, 1, (100, 2))X = np.vstack((X1, X2, X3))plt.scatter(X[:, 0], X[:, 1])plt.title("Original Data")plt.xlabel("Feature 1")plt.ylabel("Feature 2")gmm = GaussianMixtureModel(n_components=3)gmm.fit(X)labels = gmm.predict(X)plot_results(X, labels, gmm.means, gmm.covariances)
数据与结果为:
代码分析
明天再说,累了。