我不确定如何使用经过训练的高斯混合模型(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]);
我故意使测试数据类似于Cluster 2数据。在我们使用GMM进行培训后,我们能以某种方式预测新测试数据的标签吗?对于每个类的预测,是否可能得到一些概率(例如(p1 = 18%,p2 = 80%和p3 = 2%)。由于我们得到了p2 = 80%,我们可以进行硬分类,将新的测试数据标记为Cluster 2。
p.s。:我发现了这篇文章,但对我来说似乎理论(A similar post)。如果可以,请在回复中添加一些简单的Matlab脚本。
非常感谢。 A.
当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是我想要分离的对象)。然后我试着以某种方式“强迫”#39;单独的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聚类的概率版本。它是否有资格在这样一个受监督的人中使用它?样式?任何推荐的论文或参考文献?
再次感谢您的回复! 甲
答案 0 :(得分:3)
实际上,您已经训练了三个GMM模型而不是一个,每个模型都是混合物。通常,您将创建一个包含多个组件的GMM,其中每个组件代表一个集群......
那么我要做的就是创建一个新的GMM模型,该模型在整个数据集(X1
,X2
和X3
)上训练,其组件数等于来自三个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进行数据聚类(无监督学习)。根据我现在的理解,您想要的是使用现有的训练模型(监督学习)对数据进行分类。我想我对你使用&#34;集群&#34;感到困惑。术语:)
无论如何它现在应该很容易;只需使用每个模型计算测试数据的类条件概率密度函数,并选择具有最高似然性的模型作为类标签(无需将模型合并为一个)。
继续你的初始代码,那就是:
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)。