高斯混合聚类原理:
高斯混合模型(Gaussian Mixture Model ,GMM)也是原型聚类,和上一篇总结的K-means和LVQ一样,不过与它们不同的是,GMM没有想用原型向量来刻画聚类结构的不同。因为比如用k-means算法解决聚类问题非常简单,将数据聚为一个一个的点,但这样往往比较粗糙,不适用于很多数据集。所以是采用概率模型来表达原型,即通过统计得到每个样本点属于各个类的概率,而不是判定它完全属于一个类,所以有时也会被称为软聚类。从贝叶斯我们可以看出,给出一个概率来估计比直接得出一个结果要好得多。那么如何估计出概率值呢?没错,就是利用高斯分布函数。首先看一下高斯分布的概率密度公式:
p
(
x
)
=
1
(
2
π
)
n
2
(
∣
∑
∣
)
1
2
e
−
1
2
(
x
−
μ
)
T
(
∑
)
−
1
(
x
−
μ
)
p(x)=\frac{1}{{(2\pi)^{\frac{n}{2}}}(|\sum|)^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T(\sum)^{-1} (x-\mu)}
p(x)=(2π)2n(∣∑∣)211e−21(x−μ)T(∑)−1(x−μ)
可以看出高斯分布由均值向量
μ
\mu
μ和协方差矩阵
∑
\sum
∑这两个参数确定,故将概率密度函数记为:
p
(
x
∣
μ
,
∑
)
p(x|\mu,\sum)
p(x∣μ,∑)
可定义高斯混合分布为:
p
(
x
)
=
∑
k
=
1
K
α
i
.
p
(
x
∣
μ
i
,
∑
i
)
p(x)=\sum_{k=1}^{K}\alpha_i.p(x|\mu_i,\sum i)
p(x)=k=1∑Kαi.p(x∣μi,∑i)
给定一组数据,假设该数据由多个高斯分布产生,现在我们要估计这些高斯分布的参数,以及每个样本属于每个高斯分布的概率,那么根据样本推测出元GMM的概率分布就可以了。具体求解就要借助EM算法可得,不再做赘述。
高斯混合模型不需要先验知识,可以实现模型结构和参数的自动学习,而且因为该分布由k个混合部分组成,所以它本身可以任意复杂,通过增加model的数量(即聚类的k值),可以任意的逼近任何连续的概率分布。但同样的,它对初始化方法很敏感。
GMM应用:
GaussianMixture参数说明:
GaussianMixture(covariance_type=‘full’, init_params=‘kmeans’, max_iter=100,means_init=None, n_components=2, n_init=1, precisions_init=None,random_state=None, reg_covar=1e-06, tol=0.001, verbose=0,verbose_interval=10, warm_start=False, weights_init=None)
用sklearn做GMM异常检测:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from sklearn import mixture
n_samples = 300
np.random.seed(0)
# 以(20, 20)为中心的数据
shifted_gaussian = np.random.randn(n_samples, 2) + np.array([20, 20])
# 进行拉伸等变换
C = np.array([[0., -0.7], [3.5, .7]])
stretched_gaussian = np.dot(np.random.randn(n_samples, 2), C)
X_train = np.vstack([shifted_gaussian, stretched_gaussian])
clf = mixture.GaussianMixture(n_components=2, covariance_type='full')
clf.fit(X_train)
#根据概率画出等高线
x = np.linspace(-20., 30.)
y = np.linspace(-20., 40.)
X, Y = np.meshgrid(x, y)
XX = np.array([X.ravel(), Y.ravel()]).T
Z = -clf.score_samples(XX)
Z = Z.reshape(X.shape)
CS = plt.contour(X, Y, Z, norm=LogNorm(vmin=1.0, vmax=1000.0),
levels=np.logspace(0, 3, 10))
CB = plt.colorbar(CS, shrink=0.8, extend='both')
plt.scatter(X_train[:, 0], X_train[:, 1], .8)
plt.title('Negative log-likelihood predicted by a GMM')
plt.axis('tight')
plt.show()