Python圆拟合到对随机噪声不太敏感的数据点

Python圆拟合到对随机噪声不太敏感的数据点,python,geometry,curve-fitting,data-fitting,Python,Geometry,Curve Fitting,Data Fitting,我有一组测量的半径(t+ε+误差),在一个等间距的角度。 该模型是以(R,Alpha)为中心的半径(R)圆,加上小噪声和一些比噪声大得多的随机误差值 问题是找到圆心模型(r,Alpha)和圆半径(r)。但它不应该对随机误差太敏感(在下面的数据点7和14) 一些半径可能会丢失,因此简单的平均值在这里不起作用 我尝试了最小二乘优化,但它对错误有明显的反应 有没有一种方法可以优化Python中的最小增量而不是增量的最小二乘 Model: n=36 R=100 r=10 Alpha=2*Pi/6 Da

我有一组测量的半径(t+ε+误差),在一个等间距的角度。 该模型是以(R,Alpha)为中心的半径(R)圆,加上小噪声和一些比噪声大得多的随机误差值

问题是找到圆心模型(r,Alpha)和圆半径(r)。但它不应该对随机误差太敏感(在下面的数据点7和14)

一些半径可能会丢失,因此简单的平均值在这里不起作用

我尝试了最小二乘优化,但它对错误有明显的反应

有没有一种方法可以优化Python中的最小增量而不是增量的最小二乘

Model:
n=36
R=100
r=10
Alpha=2*Pi/6

Data points:
[95.85, 92.66, 94.14, 90.56, 88.08, 87.63, 88.12, 152.92, 90.75, 90.73, 93.93, 92.66, 92.67, 97.24, 65.40, 97.67, 103.66, 104.43, 105.25, 106.17, 105.01, 108.52, 109.33, 108.17, 107.10, 106.93, 111.25, 109.99, 107.23, 107.18, 108.30, 101.81, 99.47, 97.97, 96.05, 95.29]

看起来您的主要问题是删除异常值。有两种方法可以做到这一点,但对于您的应用程序,您最好的选择可能是根据项目与中位数的距离来删除项目(因为中位数对异常值的敏感度远低于平均值)

如果您使用的是
numpy
,则如下所示:

def remove_outliers(data_points, margin=1.5):
    nd = np.abs(data_points - np.median(data_points))
    s = nd/np.median(nd)
    return data_points[s<margin]
如果你不想把离群值计算得太高,你可以计算数据集的平均值,这只是最小二乘优化的线性等价物

如果你在寻找更好的东西,我可能会建议你把数据通过某种方式传递出去,但我认为这里真的不需要这样做

一个低通滤波器可能是最好的,你可以这样做:(注意,alpha是一个数字,你将不得不摆弄,以获得你想要的输出。)


在这一点上,您的最小二乘优化应该可以正常工作。

回答您的最后一个问题

有没有一种方法可以优化Python中的最小增量而不是增量的最小二乘

Model:
n=36
R=100
r=10
Alpha=2*Pi/6

Data points:
[95.85, 92.66, 94.14, 90.56, 88.08, 87.63, 88.12, 152.92, 90.75, 90.73, 93.93, 92.66, 92.67, 97.24, 65.40, 97.67, 103.66, 104.43, 105.25, 106.17, 105.01, 108.52, 109.33, 108.17, 107.10, 106.93, 111.25, 109.99, 107.23, 107.18, 108.30, 101.81, 99.47, 97.97, 96.05, 95.29]
是的,选择一种优化方法(例如在
scipy.optimize.fmin
中实现的下坡单纯形),并将绝对偏差之和用作价值函数。您的数据集很小,我想任何通用优化方法都会很快收敛。(对于非线性最小二乘拟合,也可以使用通用优化算法,但更常见的是使用最小化平方和的Levenberg-Marquardt算法。)

如果您对最小化绝对偏差而不是平方有理论依据感兴趣,请参阅“稳健估计”一章中的数值公式

从实际角度来看,绝对偏差之和可能没有唯一的最小值。 在两个点(例如,(0,5)和(1,9)以及常数函数y=a的平凡情况下,a在5和9之间的任何值都给出相同的和(4)。当偏差为平方时,不存在这样的问题


如果最小化绝对偏差将不起作用,则可以考虑启发式程序来识别和去除异常值。例如或。

您只是想扔掉异常值吗?@SlaterTyranus是的,我希望它们不会影响我的拟合圆谢谢回复。问题是离群值的大小没有定义,因此我正在寻找类似最小二乘优化但不适用于平方的代码,以最小化大纲视图对整体结果的贡献。@Oscar上述代码没有假定离群值的大小,只是与标准的偏差。第一个代码“只提供一个元素的整数数组可以转换为索引“。第二个删除83%的数据点。有没有一种方法可以优化最小的三角形而不是正方形?更新了这个问题。一些半径可能会丢失,这意味着无法工作。我曾经考虑过傅里叶变换,并将半径视为正弦波,但这对我的新手来说很难。你可以改变精确的截止值以适应你的问题,但我可以发布一个低通滤波器方法的示例。傅里叶变换在这里没有意义。
def low_pass(data, alpha):
    new_data = [data[0]]
    for i in range(1, len(data)):
        new_data.append(alpha * data[i] + (1 - alpha) * new_data[i-1])
    return new_data