平均分散数据

计算科学 Python 回归
2021-12-10 02:24:01

我有多组测量数据,可以使用散点图(图中的红点和黑点)轻松可视化。如果我的测量结果是完美的,那么红点和黑点应该位于一条曲线上。但是它们不是,因此我想以这样的方式“平均”/拟合数据点,以便获得图中的黑线。黑线可以是一条线或一组离散点,与所有测量数据的距离最小。

有人可以帮我开始吗?理想情况下,已经有一个 python 库可以为我处理这个问题,但我对算法描述也很满意。

散点数据和平均/拟合曲线

3个回答

根据您的最后评论(您可能有多个测量值并且您不在乎某组测量值是高于还是低于拟合),我认为您正在寻找的是样条拟合。您可以使用 scipy.interpolate B-spline 例程来执行此操作。下面的脚本基于一个函数生成三组数据(您可以考虑为您的系统建模)。对于第一组,它为函数“上方”(红点)添加了一些随机误差,第二组在下方(蓝点),第三组在上方和下方(绿点)。黑线是精确函数的图(没有错误)。

然后使用该scipy.interpolate.splrep函数为该数据生成 B 样条表示。B 样条是多项式函数的分段组合,通常是三次多项式(三次 B 样条),具有一些不错的特性。如果您想了解更多关于它们的信息,我强烈建议您阅读 C. de Boor 和 P. Dierckx 的作品。scipy.interpolate.splrep函数返回结、系数和顺序的元组。使用该scipy.interpolate.splev函数,您可以在拟合区间内的多个点中评估 B 样条表示。

下面的脚本以洋红色绘制了 B 样条的评估。

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as ip

def f(x):
    return np.sin(np.pi*2*x)*np.exp(-2*x)

N=20
err=0.15

data = np.zeros([3*N,2])

#red dots above curve
data[:N,0] = np.sort(np.random.rand(N))
data[:N,1] = f(data[:N,0])+err*np.random.rand(N)

#blue dots below curve
data[N:2*N,0] = np.sort(np.random.rand(N))
data[N:2*N,1] = f(data[N:2*N,0])-err*np.random.rand(N)

#green dots above and below curve
data[2*N:,0] = np.sort(np.random.rand(N))
data[2*N:,1] = f(data[2*N:,0])-2*err*(np.random.rand(N)-0.5)

plt.plot(data[:N,0],data[:N,1],'ro')
plt.plot(data[N:2*N,0],data[N:2*N,1],'bo')
plt.plot(data[2*N:,0],data[2*N:,1],'go')

data = data[data[:,0].argsort()]
x = data[:,0]
y = data[:,1]
y_exact = f(x)


plt.plot(x,y_exact,'k')

w = np.ones([len(x),1])
spl = ip.splrep(x,y,w)

xn = np.linspace(0,1.0,100)
sple = ip.splev(xn,spl)

plt.plot(xn,sple,'m')

plt.show()

要在给定点的红色和黑色标记的情况下重现您的特定图形,您可以使用一块 voronoi 图。换句话说,您的黑线将是最近的红点和最近的黑点之间等距的点集。

但是假设你想做一些不那么做作的事情,你可以使用某种非线性 svm 来代替。例如这里如图所示。

获得连续分段线性近似的一个简单想法是对每对点(红色和相应的黑色)求平均值,并对这些平均值进行分段线性插值这将产生与您展示的内容接近的东西。(但是,它不使用回归)

这能满足你的需要吗?

对于实现,我认为你可以手动完成,方法很简单。