1

ノイズの多い一連のデータにガウス曲線を当てはめ、特定のアプリケーションの FWHM を取得する必要があります。MATLAB を使用して概念をデモしましたが、MATLAB でのカーブ フィッティングは非常に簡単です。

ただし、最終的にはコードを Java/Android に変換する必要があります。ガウス曲線をデータ セットに適合させるのに役立つ Android のライブラリを探してみましたが、何も見つかりませんでした。その結果、手動でできるように、関連するすべての数学を学び始めました。

私の質問: 単項ガウス モデルの 3 つのパラメーター (中心、幅、高さ) を推定するにはどうすればよいですか? 私はExpectation-Maximizationアルゴリズムを調べてみましたが、それは私の頭をはるかに超えていました。

一般に、エラーの最小化と関係があると思いますか? ガウス曲線をデータに適合させる段階的な方法を理解するのに苦労しています。

編集:

私が試したことの 1 つは、データの自然対数を取得し、LSQR を使用して結果に放物線を当てはめ、それから元に戻すことでした。ただし、得られた結果は正確ではありません。おそらく、この方法が何らかの形で偏っているためです。

パラメータ推定の方法がわからない場合、データに曲線を当てはめる方法について他に提案はありますか? (Android では統計ライブラリがかなり制限されているように見えるため、手動で行う必要があることを忘れないでください)

4

2 に答える 2

2

org.apache.commons.math3 の 3.3 バージョンでは、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());

結果はノルム、平均、シグマになり、ノルムは振幅になります。

于 2014-06-10T21:10:57.867 に答える
2

私は最近、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 には、それぞれ y オフセット、振幅、重心位置、およびシグマである不可解なパラメーター A、B、C、および D があります。

Androidについては何も知らないので、このパッケージを使用できるかどうかはわかりませんが、関連する質問を探しているときにこの質問を見つけました(MatlabアプリケーションをJavaで複製しています、面白くない) そして、まだ理解していない場合は、これが役立つかもしれません!

于 2013-08-15T22:05:25.000 に答える