使用经过训练的高斯混合模型标记新数据

Posted

技术标签:

【中文标题】使用经过训练的高斯混合模型标记新数据【英文标题】:Labelling new data using trained Gaussian Mixture Model 【发布时间】:2014-12-03 09:18:58 【问题描述】:

我不确定如何使用经过训练的高斯混合模型 (GMM) 对一些新数据进行预测。例如,我从 3 个不同的类(集群)中提取了一些标记数据。对于每一类数据点,我拟合了一个 GMM(gm1、gm2 和 gm3)。假设我们知道每个类的高斯混合数(例如,k1=2、k2=1 和 k3=3),或者可以使用 Akaike 信息准则 (AIC) 估计(优化)。那么当我有一些新的数据集时,我怎么知道它是否更有可能属于 1、2 或 3 类?

一些 Matlab 脚本说明了我的意思:

clc; clf; clear all; close all;

%% Create some artificial training data

% 1. Cluster 1 with two mixture of Gaussian (k1 = 2)
rng default;  % For reproducibility
mu1                 = [1 2];
sigma1              = [3 .2; .2 2];
mu2                 = [-1 -2];
sigma2              = [2 0; 0 1];
X1                  = [mvnrnd(mu1,sigma1,200); mvnrnd(mu2,sigma2,100)];

options1            = statset('Display', 'final');
k1                  = 2;
gm1                 = fitgmdist(X1, k1, 'Options', options1);


% 2. Cluster 2 with one mixture of Gaussian (k2 = 1)
mu3                 = [6 4];
sigma3              = [3 .1; .1 4];
X2                  = mvnrnd(mu3,sigma3,300);

options2            = statset('Display', 'final');
k2                  = 1;
gm2                 = fitgmdist(X2, k2, 'Options', options2);

% 3. Cluster 3 with three mixture of Gaussian (k3 = 3)
mu4                 = [-5 -6];
sigma4              = [1 .1; .1 1];
mu5                 = [-5 -10];
sigma5              = [6 .1; .1 1];
mu6                 = [-2 -15];
sigma6              = [8 .1; .1 4];
X3                  = [mvnrnd(mu4,sigma4,200); mvnrnd(mu5,sigma5,300); mvnrnd(mu6,sigma6,100)];

options3            = statset('Display', 'final');
k3                  = 3;
gm3                 = fitgmdist(X3, k3, 'Options', options3);

% Display
figure,
scatter(X1(:,1),X1(:,2),10,'ko'); hold on;
ezcontour(@(x,y)pdf(gm1, [x y]), [-12 12], [-12 12]);
scatter(X2(:,1),X2(:,2),10,'ko');
ezcontour(@(x,y)pdf(gm2, [x y]), [-12 12], [-12 12]);
scatter(X3(:,1),X3(:,2),10,'ko');
ezcontour(@(x,y)pdf(gm3, [x y]), [-12 12], [-12 12]); hold off;

我们可以得到图:

然后我们得到了一些新的测试数据,例如:

%% Create some artificial testing data
mut1                = [6.1 3.8];
sigmat1             = [3.1 .1; .1 4.2];
mut2                = [5.8 4.5];
sigmat2             = [2.8 .1; .1 3.8];
Xt1                 = [mvnrnd(mut1,sigmat1,500); mvnrnd(mut2,sigmat2,100)];

figure,
scatter(Xt1(:,1),Xt1(:,2),10,'ko');
xlim([-12 12]); ylim([-12 12]);

我故意使测试数据类似于集群 2 数据。在我们使用 GMM 进行训练之后,我们能否以某种方式预测新测试数据的标签?是否有可能为每个类别的预测得出一些概率,例如 (p1 = 18%, p2 = 80% 和 p3 = 2%)。由于我们得到了 p2=80%,然后我们可以进行硬分类,将新的测试数据标记为集群 2。

ps:我找到了这篇文章,但对我来说这似乎是理论上的 (A similar post)。如果可以,请在您的回复中添加一些简单的 Matlab 脚本。

非常感谢。答:


编辑:

随着 Amro 回答问题的解决方案,我有更多问题。

    Amro 使用整个数据集创建了一个新的 GMM,并进行了一些初始化:

    % initial parameters of the new GMM (combination of the previous three)
    % (note PComponents is normalized according to proportion of data in each subset)
    S = struct('mu',[gm1.mu; gm2.mu; gm3.mu], ...
      'Sigma',cat(3, gm1.Sigma, gm2.Sigma, gm3.Sigma), ...
      'PComponents',[gm1.PComponents*n1, gm2.PComponents*n2, gm3.PComponents*n3]./n);
    
    % train the final model over all instances
    opts = statset('MaxIter',1000, 'Display','final');
    gmm = fitgmdist(X, k, 'Options',opts, 'Start',S);
    

    Amro 得到的如下所示

    这可能不适合我的数据,因为它将我标记的 cluster1 和 cluster2 与 cluster1 的一部分混合在一起。这是我要避免的。

    这里我提出的是一个人工的数值例子;但是,在我的实际应用中,它处理图像分割问题(​​例如,cluster1 是我的背景图像,cluster2 是我要分离的对象)。然后我尝试以某种方式“强制”单独的 GMM 以适应单独的类。如果两个聚类相距较远(例如本例中的cluster1和cluster 3),使用Amro的方法将所有数据合并,然后进行GMM拟合是没有问题的。但是,当我们对图像数据进行训练时,由于分辨率的限制,将背景与物体分离永远不会完美(造成部分体积效应);因此,很可能我们有 cluster1 与 cluster2 重叠的情况,如图所示。我想也许混合所有数据然后进行拟合会对新数据的进一步预测造成一些问题,对吗?

    不过,经过一番思考,我现在想做的是:

    % Combine the mixture of Gaussian and form a new gmdistribution
    muAll               = [gm1.mu; gm2.mu; gm3.mu]; 
    sigmaAll            = cat(3, gm1.Sigma, gm2.Sigma, gm3.Sigma);
    
    gmAll               = gmdistribution(muAll, sigmaAll);
    
    pt1                 = posterior(gmAll, Xt1);
    

    你们怎么看?还是相当于Amro的方法?如果是这样,有没有办法强制我训练过的 GMM 分离?

    另外,我对使用 posterior 函数的基本原理有疑问。本质上,我想在 GMM 拟合的情况下估计我的测试数据的可能性。那为什么我们现在计算后验概率呢?或者这只是一个命名问题(换句话说,'后验概率'='可能性')?

    据我所知,GMM 一直被用作无监督方法。甚至有人向我提到 GMM 是 k-means 聚类的概率版本。是否有资格以这种“监督”的方式使用它?有推荐的论文或参考文献吗?

再次非常感谢您的回复! A.

【问题讨论】:

【参考方案1】:

实际上,您已经训练了三个 GMM 模型,而不是一个,每个模型本身都是一个混合物。通常,您会创建一个包含多个组件的 GMM,其中每个组件代表一个集群...

因此,在您的情况下,我要做的是创建一个在整个数据集(X1X2X3)上训练的新 GMM 模型,其组件数等于来自所有组件的总和三个 GMM(即2+1+3 = 6 高斯混合)。该模型将使用单独训练的参数进行初始化。

这里的代码来说明(我使用您在示例中创建的相同变量):

% number of instances in each data subset
n1 = size(X1,1);
n2 = size(X2,1);
n3 = size(X3,1);

% the entire dataset
X = [X1; X2; X3];
n = n1 + n2 + n3;
k = k1 + k2 + k3;

% initial parameters of the new GMM (combination of the previous three)
% (note PComponents is normalized according to proportion of data in each subset)
S = struct('mu',[gm1.mu; gm2.mu; gm3.mu], ...
  'Sigma',cat(3, gm1.Sigma, gm2.Sigma, gm3.Sigma), ...
  'PComponents',[gm1.PComponents*n1, gm2.PComponents*n2, gm3.PComponents*n3]./n);

% train the final model over all instances
opts = statset('MaxIter',1000, 'Display','final');
gmm = fitgmdist(X, k, 'Options',opts, 'Start',S);

% display GMM density function over training data
line(X(:,1), X(:,2), 'LineStyle','none', ...
    'Marker','o', 'MarkerSize',1, 'Color','k')
hold on
ezcontour(@(x,y) pdf(gmm,[x y]), xlim(), ylim())
hold off
title(sprintf('GMM over %d training instances',n))


现在我们已经在整个训练数据集上训练了一个 GMM 模型(使用 k=6 混合),我们可以使用它来聚类新的数据实例:

cIdx = cluster(gmm, Xt1);

这与手动计算组件的后验概率相同,并将概率最大的组件作为聚类索引:

pr = posterior(gmm, Xt1);
[~,cIdx] = max(pr,[],2);

正如预期的那样,几乎 95% 的测试数据被归类为属于同一组件:

>> tabulate(cIdx)
  Value    Count   Percent
      1       27      4.50%
      2        0      0.00%
      3      573     95.50%

这里是匹配的高斯参数:

>> idx = 3;
>> gmm.mu(idx,:)
ans =
    5.7779    4.1731
>> gmm.Sigma(:,:,idx)
ans =
    2.9504    0.0801
    0.0801    4.0907

这确实对应上图右上角的组件。

类似地,如果您检查另一个组件 idx=1,它将是前一个组件左侧的组件,这解释了 600 个测试实例中的 27 个是如何“错误分类”的...确信 GMM 在这些情况下:

>> pr(cIdx==1,:)
ans =
    0.9813    0.0001    0.0186    0.0000    0.0000    0.0000
    0.6926    0.0000    0.3074    0.0000    0.0000    0.0000
    0.5069    0.0000    0.4931    0.0000    0.0000    0.0000
    0.6904    0.0018    0.3078    0.0000    0.0000    0.0000
    0.6954    0.0000    0.3046    0.0000    0.0000    0.0000
    <... output truncated ...>
    0.5077    0.0000    0.4923    0.0000    0.0000    0.0000
    0.6859    0.0001    0.3141    0.0000    0.0000    0.0000
    0.8481    0.0000    0.1519    0.0000    0.0000    0.0000

下面是覆盖在上图之上的测试实例:

hold on
gscatter(Xt1(:,1), Xt1(:,2), cIdx)
hold off
title('clustered test instances')


编辑:

我上面的示例旨在展示如何使用 GMM 对数据进行聚类(无监督学习)。根据我现在的理解,您想要的是使用现有的训练模型(监督学习)对数据进行分类。我想我对您使用“集群”一词感到困惑:)

不管怎样,现在应该很容易了;只需使用每个模型计算测试数据的类条件概率密度函数,然后选择似然度最高的模型作为类标签(无需将模型合二为一)。

所以继续你的初始代码,那就是:

p = [pdf(gm1,Xt), pdf(gm2,Xt), pdf(gm3,Xt)];    % P(x|model_i)
[,cIdx] = max(p,[],2);                          % argmax_i P(x|model_i)

cIdx 是测试数据中每个实例的类别预测(1、2 或 3)。

【讨论】:

您可能会发现我之前的回答也很有帮助:Understanding concept of Gaussian Mixture Models 感谢您的链接! 另外,感谢您在上面的回复。请参阅我在原始帖子中的编辑,以讨论一些问题。 @SamoJerom:好的,现在我看到我们在考虑不同的任务(分类与聚类)。请参阅我的编辑以获取回复...如果您阅读贝叶斯决策理论也可能会有所帮助(请注意posterior != likelihood,但两者使用贝叶斯公式相关):en.wikipedia.org/wiki/Bayes%27_theorem。关于这个主题的一个很好的介绍,我推荐经典的 Duda & Hart 书:books.google.com/books/about/…

以上是关于使用经过训练的高斯混合模型标记新数据的主要内容,如果未能解决你的问题,请参考以下文章

高斯混合模型与EM算法

高斯混合模型 (GMM) 提供与训练数据无关的结果

用于像素聚类的高斯混合模型

高斯混合模型 - 参数的 Matlab 训练

如何简单易懂的解释高斯混合(GMM)模型?

在 MATLAB 中可视化高斯混合模型集群