我必须将高斯曲线拟合到一组噪声数据中,然后将其作为特定应用的FWHM。我用MATLAB演示了这个概念,MATLAB中的曲线拟合非常简单。
但是,我最终必须将代码翻译成Java / Android。我试图在Android中寻找可以帮助我将高斯曲线拟合到数据集的库,但我找不到任何东西。因此,我开始尝试学习所有涉及的数学,所以我可以手动完成。
我的问题:我如何评估单项高斯模型的三个参数(中心,宽度,高度)?我试着研究期望最大化算法,但这已经超出了我的想法。
一般来说,我认为它与错误最小化有关?我只是弄清楚将高斯曲线拟合到我的数据的逐步方法。
编辑:
我尝试的其中一件事已经涉及获取我的数据的自然对数,使用LSQR将抛物线拟合到结果,然后转换回来。但是,我得到的结果并不准确,可能是因为这种方法在某种程度上存在偏差。
如果您不知道如何进行参数估算,您是否还有其他建议将曲线拟合到我的数据中? (请记住,它必须是手动的,因为Android的统计库似乎相当有限)
答案 0 :(得分: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具有隐藏参数A,B,C和D,它们分别是y offset,幅度,质心位置和sigma。
我不知道关于Android的一件事,所以我不知道你是否能够使用这个软件包,但我在找一个相关的问题时发现了这个问题(我也在复制一个Matlab用Java编写的应用程序并不好玩,如果你还没想到它,可能会有所帮助!
答案 1 :(得分:2)
使用GaussianCurveFitter可以更轻松地使用3.3版本的org.apache.commons.math3:
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());
结果将是标准,均值,西格玛,其中标准将是你的幅度。