假设我有x
和y
个向量,其权重向量为wgt
。我可以使用y = a x^3 + b x^2 + c x + d
拟合三次曲线(np.polyfit
),如下所示:
y_fit = np.polyfit(x, y, deg=3, w=wgt)
现在,假设我想再做一次,但这一次,我希望适合通过0
(即y = a x^3 + b x^2 + c x
,d = 0
),我该如何指定一个特定的系数(在这种情况下是d
)为零?
由于
答案 0 :(得分:4)
您可以使用np.linalg.lstsq
并手动构建系数矩阵。首先,我将创建示例数据x
和y
,并且"完全适合" y0
:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(100)
y0 = 0.07 * x ** 3 + 0.3 * x ** 2 + 1.1 * x
y = y0 + 1000 * np.random.randn(x.shape[0])
现在我将创建一个完整的三次多项式' training'或者'自变量'包含常量d
列的矩阵。
XX = np.vstack((x ** 3, x ** 2, x, np.ones_like(x))).T
如果我使用此数据集计算拟合并将其与polyfit
进行比较,让我们看看我得到了什么:
p_all = np.linalg.lstsq(X_, y)[0]
pp = np.polyfit(x, y, 3)
print np.isclose(pp, p_all).all()
# Returns True
我使用np.isclose
的地方,因为这两种算法确实产生了很小的差异。
你可能认为这很好,但我仍然没有回答这个问题'。从这里开始,强制拟合为零偏移与从数组中删除np.ones
列相同:
p_no_offset = np.linalg.lstsq(XX[:, :-1], y)[0] # use [0] to just grab the coefs
好的,让我们看看与我们的数据相比这看起来是什么样的:
y_fit = np.dot(p_no_offset, XX[:, :-1].T)
plt.plot(x, y0, 'k-', linewidth=3)
plt.plot(x, y_fit, 'y--', linewidth=2)
plt.plot(x, y, 'r.', ms=5)
这给出了这个数字,
警告:对实际未通过(x,y)=(0,0)的数据使用此方法时,将偏向您的输出解系数估计值({{1} })因为
p
将试图弥补数据中存在偏移的事实。一种方形钉圆孔'问题
此外,您还可以通过执行以下操作将数据设置为立方 :
lstsq
此处再次出现上述警告。如果您的数据包含二次,线性或常数项,则立方系数的估计值将有偏差。有时候 - 对于数值算法 - 这种事情是有用的,但是对于统计目的,我的理解是包含所有较低项的重要性。如果测试结果显示较低的术语在统计上与零没有差别,那么为了安全起见,你可能应该在估算你的立方体时将它们留在里面。
祝你好运!
答案 1 :(得分:0)
您可以尝试以下操作:
从curve_fit
导入scipy
,即
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
定义曲线拟合功能。就您而言,
def fit_func(x, a, b, c):
# Curve fitting function
return a * x**3 + b * x**2 + c * x # d=0 is implied
执行曲线拟合
# Curve fitting
params = curve_fit(fit_func, x, y)
[a, b, c] = params[0]
x_fit = np.linspace(x[0], x[-1], 100)
y_fit = a * x**3 + b * x**2 + c * x
请根据需要绘制结果
plt.plot(x, y, '.r') # Data
plt.plot(x_fit, y_fit, 'k') # Fitted curve
在使用numpy
的{{1}}函数通过原点的意义上,它不能回答问题,但是可以解决问题。
希望有人发现它有用:)