高斯曲线拟合-参数估计-Android/Java



我必须将高斯曲线拟合到有噪声的数据集,然后将其FWHM用于某个应用。我用MATLAB演示了这个概念,在MATLAB中曲线拟合非常容易。

然而,我最终不得不将代码翻译成Java/Android。我试着在Android中寻找可以帮助我将高斯曲线拟合到数据集的库,但我什么都找不到。因此,我开始尝试学习所有涉及的数学,这样我就可以手动完成了。

我的问题是:如何估计单项高斯模型的三个参数(中心、宽度、高度)?我试着研究期望最大化算法,但这远远超出了我的想象。

一般来说,我认为这与误差最小化有关?我只是很难弄清楚将高斯曲线拟合到我的数据中的分步方法。

编辑:

我已经尝试过的一件事是获取数据的自然对数,使用LSQR将结果拟合成抛物线,然后转换回来。然而,我得到的结果并不准确,可能是因为这种方法在某种程度上有偏差。

如果你不知道如何进行参数估计,你有其他建议吗?(记住,它必须是手动的,因为Android的统计库似乎相当有限)

我最近使用Apache Commons数学类做了类似的事情,特别是Levenberg-Marquardt Optimizer、CurveFitter和GaussianFunction类。

我用来准备数据的代码是这样的:

    // Initialize analyzers
    _optimizer = new LevenbergMarquardtOptimizer();
    _fitter = new CurveFitter(_optimizer);
    // Initialize the analysis results
    _gaussians = new ArrayList<GaussianFunction>();
    // Load the data into the gaussian fitter
    for (int i = 0; i != data.length; i++)
        _fitter.addObservedPoint(i, data[i]);

然后实际执行拟合:

public void analyze() {
    // Calculate Mean
    double sum_yx = 0.0;
    double sum_y = 0.0;
    for (int i = 0; i != _data.length; i++) {
        sum_yx += _data[i] * (i + 1);
        sum_y += _data[i];
    }
    double mean = sum_yx / sum_y;
    // Peform the gaussian fit
    // If no guesses given, fit to the mean of the data
    if (_guesses.size() == 0) {
        double[] guess = new double[] { 0, 1, mean, 1 };
        double ret[];
        try {
            ret = _fitter.fit(new ParametricGaussianFunction(), guess);
            _gaussians.add(new GaussianFunction(ret[0], ret[1], ret[2],
                    ret[3]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // If guesses are given, fit to each one
    else {
        try {
            for (double[] guess : _guesses) {
                double ret[] = _fitter.fit(
                        new ParametricGaussianFunction(), guess);
                _gaussians.add(new GaussianFunction(ret[0], ret[1], ret[2],
                        ret[3]));
            }
        } catch (Exception e) {
            e.printStackTrace();
            // _gaussian = null;
        }
    }
}

你提到你的数据很嘈杂;我包括了这些猜测,因为我必须适应高斯分布的峰值,这些峰值本身就形成了高斯形状。初始条件必须非常准确。如果我的猜测偏离了几个像素,我得到了整个数据集的拟合,而不仅仅是峰值。我想,如果没有退路/更大的趋势可以适应,它就会失败。

高斯函数具有隐参数A、B、C和D,它们分别是y偏移、振幅、质心位置和西格玛。

我对Android一无所知,所以我不知道你是否能够使用这个软件包,但我在寻找相关的软件包时发现了这个问题(我也在用Java复制一个Matlab应用程序,这并不有趣),并认为如果你还没有弄清楚,这可能会有所帮助!

有了3.3版本的org.apache.commons.math3,使用GaussianCurveFitter:更容易

        GaussianCurveFitter fitter = GaussianCurveFitter.create();
        WeightedObservedPoints obs = new WeightedObservedPoints();
        for (int index = 0; index < data.length; index++) {
            obs.add(data[i].x, data[i].y);
        }
        double[] bestFit = fitter.fit(obs.toList());

结果将是范数,均值,西格玛,其中范数将是你的振幅。

最新更新