【问题标题】:Understanding concept of Gaussian Mixture Models理解高斯混合模型的概念
【发布时间】:2014-11-19 02:31:26
【问题描述】:

我正在尝试通过阅读在线资源来了解 GMM。我已经使用 K-Means 实现了聚类,并且正在查看 GMM 与 K-means 的比较。

这是我的理解,如果我的概念有误,请告诉我:

GMM 类似于 KNN,在这两种情况下都实现了聚类。但是在 GMM 中,每个集群都有自己独立的均值和协方差。此外,k-means 将数据点硬分配给集群,而在 GMM 中,我们得到一组独立的高斯分布,并且对于每个数据点,我们都有概率属于其中一个分布。

为了更好地理解它,我使用 MatLab 对其进行了编码并实现了所需的聚类。我使用 SIFT 特征来进行特征提取。并使用 k-means 聚类来初始化值。 (这来自VLFeat 文档)

%images is a 459 x 1 cell array where each cell contains the training image
[locations, all_feats] = vl_dsift(single(images{1}), 'fast', 'step', 50); %all_feats will be 128 x no. of keypoints detected
for i=2:(size(images,1))
    [locations, feats] = vl_dsift(single(images{i}), 'fast', 'step', 50);
    all_feats = cat(2, all_feats, feats); %cat column wise all features
end

numClusters = 50; %Just a random selection.
% Run KMeans to pre-cluster the data
[initMeans, assignments] = vl_kmeans(single(all_feats), numClusters, ...
    'Algorithm','Lloyd', ...
    'MaxNumIterations',5);

initMeans = double(initMeans); %GMM needs it to be double

% Find the initial means, covariances and priors
for i=1:numClusters
    data_k = all_feats(:,assignments==i);
    initPriors(i) = size(data_k,2) / numClusters;

    if size(data_k,1) == 0 || size(data_k,2) == 0
        initCovariances(:,i) = diag(cov(data'));
    else
        initCovariances(:,i) = double(diag(cov(double((data_k')))));
    end
end

% Run EM starting from the given parameters
[means,covariances,priors,ll,posteriors] = vl_gmm(double(all_feats), numClusters, ...
    'initialization','custom', ...
    'InitMeans',initMeans, ...
    'InitCovariances',initCovariances, ...
    'InitPriors',initPriors);

基于上述我有meanscovariancespriors。我的主要问题是,现在怎么办?我现在有点迷路了。

此外,meanscovariances 向量的大小分别为 128 x 50。我期待它们是1 x 50,因为每一列都是一个集群,每个集群不会只有一个均值和协方差吗? (我知道 128 是 SIFT 特征,但我期待的是均值和协方差)。

在 k-means 中,我使用了 MatLab 命令knnsearch(X,Y),它基本上为 Y 中的每个点找到 X 中最近的邻居。

那么如何在 GMM 中实现这一点,我知道它是概率的集合,当然,与该概率最近的匹配将是我们的获胜集群。这就是我感到困惑的地方。 网上所有的教程都讲了如何实现meanscovariances的值,但是在聚类方面如何实际使用它们就不多说了。

谢谢

【问题讨论】:

  • 旁注:我认为您混淆了K-meanskNN(K-最近邻)。第一种是聚类方法(无监督学习),第二种是分类方法(监督学习)。
  • 这个概念和 GMM UBM 说话人验证一样吗?

标签: matlab machine-learning classification cluster-analysis mixture-model


【解决方案1】:

我认为如果你先看看GMM 模型代表什么会有所帮助。我将使用 Statistics Toolbox 中的 functions,但您应该可以使用 VLFeat 来做同样的事情。

让我们从两个一维normal distributions 的混合情况开始。每个高斯由一对meanvariance 表示。混合物为每个成分分配一个权重(先验)。

例如,让我们混合两个权重相等的正态分布 (p = [0.5; 0.5]),第一个以 0 为中心,第二个以 5 为中心 (mu = [0; 5]),第一个和第二个分布的方差分别等于 1 和 2 (sigma = cat(3, 1, 2))。

如下所示,均值有效地改变了分布,而方差决定了分布的宽/窄和平坦/尖度。先验设置混合比例得到最终的组合模型。

% create GMM
mu = [0; 5];
sigma = cat(3, 1, 2);
p = [0.5; 0.5];
gmm = gmdistribution(mu, sigma, p);

% view PDF
ezplot(@(x) pdf(gmm,x));

EM clustering 的思想是每个分布代表一个集群。因此,在上面的一维数据示例中,如果给您一个实例 x = 0.5,我们会以 99.5% 的概率将其分配为属于第一个集群/模式

>> x = 0.5;
>> posterior(gmm, x)
ans =
    0.9950    0.0050    % probability x came from each component

您可以看到实例如何很好地落在第一个钟形曲线之下。而如果你在中间取一个点,答案会更加模棱两可(分配给 class=2 的点,但确定性要低得多):

>> x = 2.2
>> posterior(gmm, 2.2)
ans =
    0.4717    0.5283

multivariate normal distributions 将相同的概念扩展到更高维度。在不止一个维度上,covariance matrix 是方差的泛化,以说明特征之间的相互依赖关系。

这里又是一个在二维中混合了两个 MVN 分布的示例:

% first distribution is centered at (0,0), second at (-1,3)
mu = [0 0; 3 3];

% covariance of first is identity matrix, second diagonal
sigma = cat(3, eye(2), [5 0; 0 1]);

% again I'm using equal priors
p = [0.5; 0.5];

% build GMM
gmm = gmdistribution(mu, sigma, p);

% 2D projection
ezcontourf(@(x,y) pdf(gmm,[x y]));

% view PDF surface
ezsurfc(@(x,y) pdf(gmm,[x y]));

协方差矩阵如何影响联合密度函数的形状背后有一些直觉。例如在 2D 中,如果矩阵是对角的,则意味着这两个维度不会共同变化。在这种情况下,PDF 看起来像一个轴对齐的椭圆,根据哪个维度具有更大的方差,水平或垂直拉伸。如果它们相等,则形状是一个完美的圆形(分布在两个维度上以相等的速率分布)。最后,如果协方差矩阵是任意的(非对角线但根据定义仍然是对称的),那么它可能看起来像一个旋转了某个角度的拉伸椭圆。

所以在上图中,您应该能够区分这两个“凸点”以及各自代表的单独分布。当您使用 3D 和更高维度时,将其视为在 N 维度中表示 (hyper-)ellipsoids


现在,当您使用 GMM 执行 clustering 时,目标是找到模型参数(每个分布的均值和协方差以及先验),以便生成的模型最适合数据。最佳拟合估计转化为给定 GMM 模型的数据的 maximizing the likelihood(意味着您选择最大化 Pr(data|model) 的模型)。

正如其他人所解释的,这是使用EM algorithm 迭代解决的; EM 从混合模型参数的初始估计或猜测开始。它根据参数产生的混合密度迭代地重新对数据实例进行评分。然后使用重新评分的实例来更新参数估计。重复此过程直到算法收敛。

不幸的是,EM算法对模型的初始化非常敏感,所以如果你设置了不好的初始值,可能需要很长时间才能收敛,甚至卡在local optima。初始化 GMM 参数的更好方法是使用K-means 作为第一步(就像您在代码中显示的那样),并使用这些集群的均值/cov 来初始化 EM。

与其他聚类分析技术一样,我们首先需要decide on the number of clusters 才能使用。 Cross-validation 是一种可靠的方法,可以很好地估计集群的数量。

EM 聚类的缺点是需要拟合很多参数,并且通常需要大量数据和多次迭代才能获得良好的结果。具有 M 混合和 D 维数据的无约束模型涉及拟合D*D*M + D*M + M 参数(每个大小为 DxD 的 M 个协方差矩阵,加上长度为 D 的 M 个平均向量,加上长度为 M 的先验向量)。对于large number of dimensions 的数据集,这可能是个问题。所以习惯上施加限制和假设来简化问题(一种regularization 以避免overfitting 问题)。例如,您可以将协方差矩阵固定为仅对角线,甚至可以将协方差矩阵 shared 用于所有高斯。

最后,一旦您拟合了混合模型,您就可以通过使用每个混合组件计算数据实例的后验概率来探索集群(就像我在 1D 示例中展示的那样)。 GMM 根据这种“成员资格”可能性将每个实例分配给一个集群。


以下是使用高斯混合模型聚类数据的更完整示例:

% load Fisher Iris dataset
load fisheriris

% project it down to 2 dimensions for the sake of visualization
[~,data] = pca(meas,'NumComponents',2);
mn = min(data); mx = max(data);
D = size(data,2);    % data dimension    

% inital kmeans step used to initialize EM
K = 3;               % number of mixtures/clusters
cInd = kmeans(data, K, 'EmptyAction','singleton');

% fit a GMM model
gmm = fitgmdist(data, K, 'Options',statset('MaxIter',1000), ...
    'CovType','full', 'SharedCov',false, 'Regularize',0.01, 'Start',cInd);

% means, covariances, and mixing-weights
mu = gmm.mu;
sigma = gmm.Sigma;
p = gmm.PComponents;

% cluster and posterior probablity of each instance
% note that: [~,clustIdx] = max(p,[],2)
[clustInd,~,p] = cluster(gmm, data);
tabulate(clustInd)

% plot data, clustering of the entire domain, and the GMM contours
clrLite = [1 0.6 0.6 ; 0.6 1 0.6 ; 0.6 0.6 1];
clrDark = [0.7 0 0 ; 0 0.7 0 ; 0 0 0.7];
[X,Y] = meshgrid(linspace(mn(1),mx(1),50), linspace(mn(2),mx(2),50));
C = cluster(gmm, [X(:) Y(:)]);
image(X(:), Y(:), reshape(C,size(X))), hold on
gscatter(data(:,1), data(:,2), species, clrDark)
h = ezcontour(@(x,y)pdf(gmm,[x y]), [mn(1) mx(1) mn(2) mx(2)]);
set(h, 'LineColor','k', 'LineStyle',':')
hold off, axis xy, colormap(clrLite)
title('2D data and fitted GMM'), xlabel('PC1'), ylabel('PC2')

【讨论】:

  • 像往常一样,一个惊人的答案!
  • O.o 当stackoverflow“专业人士”给出了可以在整个互联网上找到的东西的最佳解释。哇。 +1
  • 谢谢 Amro,这比我希望的要多得多。我相信更多的人会像我一样从您的详细回答中受益:)
  • 是的,我也是 +1.... 尤其是那些动画 GIF。你的回答总是让我大吃一惊!
  • 我也很喜欢这个,因为这可以更好地解释 GMM 是如何工作的,而我目前对它们的了解。再次感谢您的精彩回答!
【解决方案2】:

您是对的,在使用 K-Means 或 GMM 进行聚类的背后也有同样的见解。 但是正如您提到的,高斯混合考虑了数据协方差。 要找到 GMM 统计模型的最大似然参数(或最大后验 MAP),您需要使用称为EM algorithm 的迭代过程。每次迭代由一个 E 步(期望)和一个 M 步(最大化)组成,重复直到收敛。 收敛后,您可以轻松估计每个集群模型的每个数据向量的隶属概率。

【讨论】:

  • 感谢您的回答。要获得 MAP 参数(均值、协方差、先验),我必须运行 EM?但我以为我已经在我的代码中做到了:% Run EM starting from the given parameters [means,covariances,priors,ll,posteriors] = vl_gmm(double(all_feats), numClusters, ... 这不是必需的吗?
  • 我不知道 v1_gmm 函数,但它似乎从 kmeans 初始化运行 EM。然后为了获得聚类,您可以估计每个高斯分布下每个数据向量的成员资格。请注意,正如@Taygun 所提到的,集群的数量是 kmeans 算法的参数。然而,它们存在一些扩展,如 Adaptive K-Means Clustering ...
【解决方案3】:

协方差告诉您数据在空间中的变化情况,如果分布具有较大的协方差,则意味着数据分布更广,反之亦然。当您拥有高斯分布的 PDF(均值和协方差参数)时,您可以检查该分布下测试点的成员置信度。

然而,GMM 也存在 K-Means 的弱点,即您必须选择参数 K,即集群的数量。这需要对数据的多模态有很好的理解。

【讨论】:

    猜你喜欢
    • 2013-06-11
    • 2023-03-24
    • 2021-09-30
    • 2014-01-09
    • 2012-05-08
    • 2018-07-19
    • 1970-01-01
    • 2016-08-06
    • 2017-02-26
    相关资源
    最近更新 更多