如何用NumPy Polynomial.fit()强制线性拟合过指定点(原点)
用NumPy Polynomial.fit()强制拟合经过指定点(含原点)
为什么权重法不是最优解
你试过的权重调整只能让拟合结果更偏向目标点,但没法严格强制拟合线精准经过该点——权重本质是最小化加权平方误差,哪怕给指定点设极大权重,也可能因为数值计算的问题做不到完全精确,而且这种方法不够可靠。
精确强制经过指定点的两种方法
方法1:手动约束参数(适合强制过原点)
对于线性拟合 ( y = kx + b ),如果要强制过原点((0,0)),那截距(b)直接固定为0,问题简化成拟合(y = kx)。可以用最小二乘法直接求解:
import numpy as np import matplotlib.pyplot as plt x = np.array([0, 1, 2, 3]) y = np.array([0, 4, 5, 6]) # 直接求解斜率k,固定截距为0 k, _, _, _ = np.linalg.lstsq(x[:, np.newaxis], y, rcond=None) fitfunc = np.polynomial.Polynomial([0, k[0]]) # 验证结果 print(fitfunc) print(fitfunc.coef) # 系数为[0, k],截距严格为0 print(fitfunc(0)) # 输出0,确保过原点 # 绘图展示 fig, ax1 = plt.subplots() ax1.plot(x, y, ".") ax1.plot(x, fitfunc(x), label=str(fitfunc)) plt.legend() plt.show()
方法2:约束最小二乘法(适合任意指定点)
如果要强制拟合经过多个任意指定点,NumPy的Polynomial.fit本身不支持硬约束,这时可以用scipy的约束最小二乘工具实现:
import numpy as np import matplotlib.pyplot as plt from scipy.optimize import lsq_linear x = np.array([0, 1, 2, 3]) y = np.array([0, 4, 5, 6]) degree = 1 # 构造线性拟合的设计矩阵,每行对应[1, x_i](对应截距b和斜率k) X = np.vander(x, degree+1, increasing=True) # 设置约束:强制经过(0,0),即 截距b*1 + 斜率k*0 = 0 A_eq = np.array([[1, 0]]) # 约束矩阵,对应系数[b, k] b_eq = np.array([0]) # 约束目标值 # 求解约束最小二乘 res = lsq_linear(X, y, A_eq=A_eq, b_eq=b_eq) coef = res.x fitfunc = np.polynomial.Polynomial(coef) # 验证结果 print(fitfunc) print(fitfunc.coef) print(fitfunc(0)) # 严格输出0 # 绘图展示 fig, ax1 = plt.subplots() ax1.plot(x, y, ".") ax1.plot(x, fitfunc(x), label=str(fitfunc)) plt.legend() plt.show()
关于Polynomial.fit的权重参数
w参数是给每个数据点的误差分配权重,权重越大,拟合时越优先降低该点的误差。比如设w=[1000, 1, 1, 1]会让拟合结果非常靠近(0,0),但没法保证严格经过,而且极端权重容易引发数值不稳定问题,所以不推荐用这种方法实现精确约束。
内容的提问来源于stack exchange,提问作者handle
相关产品推荐
相关产品推荐

