我正在尝试使用gm进行群集。我试过这段代码:
opts = statset('MaxIter', 300, 'Display', 'iter');
gm = gmdistribution.fit(braindata, nsegments, 'Regularize', 1e-6, 'Options', opts);
其中braindata是一个数据矩阵(体素*蛋白质,1478071 * 11),nsegments是8。
我收到了这个错误:
Error using gmdistribution.fit (line 136) The following column(s) of data are effectively constant: 6 7 8 9 10 11.
Error in reducedSegbrain_gmix (line 119) gm = gmdistribution.fit(braindata, nsegments, 'Regularize', 1e-6, 'Options', opts);
这有什么解决方法吗?
答案 0 :(得分:1)
对我来说,最好的选择就是丢弃那一栏。在我的申请中没问题,但可能不适合你。
这是检查该条件并产生错误的gmdistribution
类定义的位:
varX = var(X);
I = find(varX < eps(max(varX))*n);
if ~isempty(I)
error('stats:gmdistribution:ZeroVariance',...
'The following column(s) of data are effectively constant: %s.', num2str(I));
end
其中X
是传递给fit
方法的多变量数据。它对“有效零方差”的测试是eps
的组合,它是当前数据类型(例如uint8
或double
)可表示的最小差异的度量,以及数据中的行。
因此,一种方法是重新实现该测试并在gmdistribution.fit
抛出错误之前对其进行一些操作。如果数据的方差很小,以至于它被认为是零,那么就没有任何东西可以从它的包含中获得,因此丢弃该列并继续拟合剩下的那些是没有害处的。
从您的示例的外观来看,这将是您数据集的一半。这可能并不理想,但在多变量分析中发现变量的子集包含大部分方差并不常见(参见Pareto)。你可以先进行主成分分析,在gmm拟合之前丢弃其中的一些,尽管上面的测试已经有效地做了。
如果您必须包含这些列,那么您可以对它们进行一些其他处理以提高方差。首先,我要确保将值存储在一个具有足够精度来表示它们的数据类型中,尽管这通常由MATLAB自动处理得很好。
如果这些低方差列的平均值与其他列的数量级不同(注意上述测试是相对于所有列方差的最大值的eps
)那么会产生相对差异,你可以通过一些明智的正常化来减少这种差异。
如果一切都失败了,那么你可能需要回到采集源并提高信噪比。如果那是一台核磁共振成像仪,那么我祝你好运...