我想使用 scipy odr 将数据拟合到幂律,其目的是最小化垂直平方距离。我想找到每个点与拟合之间的垂直距离。
“.delta”返回 |y_model - y_data|每个点的残差(垂直距离),我似乎找不到任何返回垂直距离的内置方法。我确信它们是在算法内部计算的,因为它们用于计算拟合的参数,但我无法在任何地方找到它们。
如果确实无法通过一个命令获取它们,我该如何手动执行此操作?如果拟合的曲线是直线我可以做到,但它是幂律,我不知道该怎么办。
假设您有以下型号:
import numpy as np
import matplotlib.pyplot as plt
from scipy import odr
from shapely.geometry import Point, LineString
def model(B, x):
return B[2] * x ** 2 + B[1] * x + B[0]
np.random.seed(12345)
x = np.linspace(0, 1, 20)
y = model([0.1, 0.2, 1.], x)
sx = 0.1 * np.ones_like(x)
sy = 0.2 * np.ones_like(x)
x += sx * np.random.normal(size=x.size)
y += sy * np.random.normal(size=x.size)
regressor = odr.Model(model)
data = odr.RealData(x, y, sx=sx, sy=sy)
solver = odr.ODR(data, regressor, beta0=[1., 1., 1.])
solution = solver.run()
检查
solution
对象没有发现残差(距离)。
然后我们可以使用
shapely
来完成工作。
首先我们重新采样并估计模型(进行一些外推):
xlin = np.linspace(-0.2, 1.1, 200)
ylin = model(solution.beta, xlin)
我们通过插值构造一个
LineString
:
fit = LineString([(x, y) for x, y in zip(xlin, ylin)])
现在我们可以轻松计算距该曲线的距离:
distances = np.array([
fit.distance(Point(x, y))
for x, y in zip(x, y)
])
或者更好地定位曲线上的点投影:
projected = [
fit.interpolate(fit.project(Point(x, y)))
for x, y in zip(x, y)
]
projected = np.array([[p.x, p.y] for p in projected])
以图形方式呈现为: