MATLAB,高斯参数

MATLAB,高斯参数,matlab,gaussian,Matlab,Gaussian,我必须找到至少有两个峰值的数据序列的高斯参数。我怎么办?假设我有yi=f(xi),我需要参数mu和sigma 我知道我可以取所有数据的对数,然后用polyfit计算出来,但是用这种方法,用几句话我就得到了我不需要的东西(太长了,说不出原因) 我该怎么办 重要细节:我的MATLAB版本没有normfit。如果您的MATLAB支持,您可以尝试将数据分为两个簇,然后分别计算每个簇的平均值和方差: %// Cluster bimodal data idx = kmeans(y, 2); y1 = y(i

我必须找到至少有两个峰值的数据序列的高斯参数。我怎么办?假设我有
yi=f(xi
),我需要参数mu和sigma

我知道我可以取所有数据的对数,然后用polyfit计算出来,但是用这种方法,用几句话我就得到了我不需要的东西(太长了,说不出原因)

我该怎么办


重要细节:我的MATLAB版本没有normfit。

如果您的MATLAB支持,您可以尝试将数据分为两个簇,然后分别计算每个簇的平均值和方差:

%// Cluster bimodal data
idx = kmeans(y, 2);
y1 = y(idx == 1);
y2 = y(idx == 2);

%// Compute means and variances of clusters
M = [mean(y1), mean(y2)];
V = [var(y1), var(y2)];
对于k模式的一般情况,可以使用以下代码:

idx = kmeans(y, k);    %// Cluster data
C = arrayfun(@(x)y(idx == x), 1:k, 'UniformOutput', false);
M = cellfun(@mean, C); %// Mean of clusters
V = cellfun(@var, C);  %// Variance of clusters
这种方法的好处是,只要事先知道,它就可以适用于任意数量的集群

例子 让我们先生成一些任意双峰高斯数据:

N = 1e4;                    %// Number of samples per mode
M = [1, 5]; V = [0.2, 0.4]; %// Means and variances of two normal distributions
y = bsxfun(@plus, bsxfun(@times, randn(1e4, 1), sqrt(V), M);
y = y(randperm(numel(y)));  %// Shuffle samples
我们应该得到以下直方图:

现在,让我们执行k均值聚类,并计算每个聚类的均值和方差:

idx = kmeans(y, 2);    %// Cluster bimodal data
C = arrayfun(@(x)y(idx == x), 1:k, 'UniformOutput', false);
M = cellfun(@mean, C); %// Mean of clusters
V = cellfun(@var, C);  %// Variance of clusters
我得到的结果是:

M =
    0.9985    4.9802

V =
    0.1949    0.3854
这与原始数据非常接近



如果你没有MATLAB的
kmeans
,你可以使用一个FEX实现,例如。

我在这里已经回答了几次这类问题,每次我都认为“做这类事情必须要简单得多…”然而,我还没有看到或想到一个更简单的方法,所以……请容忍我:)

如果您事先知道峰值的数量,您可以这样做:

function GaussFit

    % DATA TO REPRODUCE
    mu    = [112  -45];
    sigma = [ 12   24];

    F =[...
        mu(1) + sigma(1)*randn(1e4, 1)
        mu(2) + sigma(2)*randn(1e4, 1)];

    % interpolate with splines through the histogram
    [y,x] = hist(F, 1500);
    G = spline(x,y);

    % Find optimum curve fit 
    P0 = [% mu  S    A
            80  2   2e3;  % (some rough initial estimate)
            -8  12  2e3];        
    P = fminunc(@(P) Obj(P, x,G), P0); % refine the estimate

    % REPRODUCED DATA
    P(:,1:2).'

    figure, clf, hold on
    plot(x, P(1,3)*Gaussian(P(1,1),P(1,2),x) + P(2,3)*Gaussian(P(2,1),P(2,2),x))
    plot(x, ppval(G,x),'r.', 'MarkerSize', 1)

end

% The objective function for the curve fitting optimizer
function val = Obj(P, x,F)

    G = zeros(size(x));    
    for ii = 1:size(P,1);

        mu = P(ii,1);    % mean
        sigma = P(ii,2); % std. deviation
        A = P(ii,3);     % "amplitude"

        G = G + A/sigma/sqrt(2*pi) * exp(-(x-mu).^2/2/sigma^2);

    end    

    val = sum((G-ppval(F,x)).^2);

end

% just a function for plotting
function G = Gaussian(mu,sigma,x)
    G = 1/sigma/sqrt(2*pi) * exp(-(x-mu).^2/2/sigma^2);    
end
结果:

ans =
  112.1633   -45.2013
  12.6777     24.6723

不错的结果,我想说:)

和往常一样,这种方法有一些缺点;这需要你事先知道

  • 数据集中的峰值数
  • 初始估计“足够接近”以使优化器收敛到实际解决方案
  • 如果您事先不知道峰值的数量(并且希望自动找到峰值的数量),则必须使用
    kmeans
    并在数据集中定位峰值的数量(及其平均值)

    无论如何,重要的是有办法找到峰值的数量,但没有办法自动找到合适的初始估计值。如果您只有一个或几十个数据集,那么仍然可以手动查找初始估计值,但超出此范围的任何操作都会使上述方法越来越不吸引人

    不过,您可以使用全局优化器,在这种情况下,您不必再提出初始估计。但正是在这一点上,我忍不住思考

    “对于这样一个简单的问题,这不应该是必要的!”


    但是哦,好吧

    那么你的数据是一个并集还是两个正态分布集的和?我猜你的意思是你想找到混合模型?这段代码可能会有帮助:@EitanT我的数据来自两个不同的高斯峰(它们完全分开)。@ragnar所以这是一个联合体。期望最大化是通常按照@zkan的建议进行的。很抱歉耽搁了,我离开了一段时间。不幸的是,我的MATLAB不支持kmeans。不过,我以后会记住这一点uses@ragnar嗯,我想你没有安装统计工具箱吧?也许您可以下载
    kmeans
    ?我会看看我是否能想出一个不使用统计工具箱的解决方案……你可能是对的,因为我甚至不能正确使用fit函数:我尝试了fit(x,data,'fourier8')之类的方法,但根本不起作用。。你知道如何在不使用e-mule、torrent或类似工具的情况下从internet下载/安装统计工具箱吗?你可能是对的,因为我甚至不能正确使用fit函数:我尝试了fit(x,data,'fourier8')之类的方法,但根本不起作用。。您知道如何在不使用e-mule、torrent或类似工具的情况下从internet下载/安装统计工具箱吗?@ragnar使用FEX实现(例如),它应该在没有统计工具箱的情况下工作,并提供相同的结果。