【问题标题】:Gaussian Curve Fitting - Parameter Estimation - Android/Java高斯曲线拟合 - 参数估计 - Android/Java
【发布时间】:2013-07-11 16:52:58
【问题描述】:

我必须将高斯曲线拟合到一组嘈杂的数据中,然后将其作为特定应用的 FWHM。我用 MATLAB 演示了这个概念,在 MATLAB 中进行曲线拟合非常简单。

但是,我最终必须将代码翻译成 Java/Android。我尝试在 Android 中寻找可以帮助我将高斯曲线拟合到数据集的库,但我找不到任何东西。因此,我开始尝试学习所有涉及的数学,以便我可以手动完成。

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

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

编辑:

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

如果您不知道如何进行参数估计,您还有其他建议可以将曲线拟合到我的数据吗? (请记住,它必须是手动的,因为 Android 的统计库似乎相当有限)

【问题讨论】:

  • 这是题外话。 SO适用于编程问题,而不是数学问题。检查MathematicsSE
  • 不过是编程题,哈哈。

标签: java android gaussian estimation


【解决方案1】:

我最近使用 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;
        }
    }
}

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

GaussianFunction 具有神秘的参数 A、B、C 和 D,它们分别是 y 偏移、幅度、质心位置和 sigma。

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

【讨论】:

    【解决方案2】:

    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());
    

    结果将是 norm、mean、sigma,其中 norm 将是您的幅度。

    【讨论】:

      猜你喜欢
      • 2021-10-14
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      • 2017-05-23
      • 2012-06-12
      • 1970-01-01
      • 2016-10-30
      • 2016-07-21
      相关资源
      最近更新 更多