假设现在有n对坐标系中的点最小二乘法曲线拟合公式推导与代码实现,现在要做k阶多项式拟合,多项式函数如下:

最小二乘法曲线拟合公式推导与代码实现   (1)

如果将所有已知的点代入公式1就可以得到n组等式:

最小二乘法曲线拟合公式推导与代码实现

最小二乘法曲线拟合公式推导与代码实现

...

最小二乘法曲线拟合公式推导与代码实现

这些不等式不一定的有解的,就是说在k阶多项式的曲线下不能拟合每个点,所以我们需要求多项式计算出来的y与真实y之间最小来实现尽量拟合每个点。

最小二乘法曲线拟合公式推导与代码实现    (2)

将公式1代入2可以得到

最小二乘法曲线拟合公式推导与代码实现     (3)

可以通过公式3对最小二乘法曲线拟合公式推导与代码实现求偏导后令其为0来求解所有a的值,得到下面的式子

最小二乘法曲线拟合公式推导与代码实现

最小二乘法曲线拟合公式推导与代码实现

最小二乘法曲线拟合公式推导与代码实现

......

最小二乘法曲线拟合公式推导与代码实现

整理一下这些方程可以得到

最小二乘法曲线拟合公式推导与代码实现

最小二乘法曲线拟合公式推导与代码实现

最小二乘法曲线拟合公式推导与代码实现

......

最小二乘法曲线拟合公式推导与代码实现

写成矩阵的表达

最小二乘法曲线拟合公式推导与代码实现\

这个式子还可以继续分解

假设最小二乘法曲线拟合公式推导与代码实现最小二乘法曲线拟合公式推导与代码实现

那么上面的矩阵计算可以简化为最小二乘法曲线拟合公式推导与代码实现,所以得到最小二乘法曲线拟合公式推导与代码实现

这就是二项式曲线拟合的公式。下面用代码来实现看看拟合效果

import numpy as np
import matplotlib.pyplot as plt
import random

fig = plt.figure()
ax = fig.add_subplot(111)

k = 9

x = np.arange(-1,1,0.02)
y = [((a*a-1)*(a*a-1)*(a*a-1)+0.5)*np.sin(a*2) for a in x]
i = 0
xa = []
ya = []
for xx in x:
    yy = y[i]
    d = float(random.randint(60, 140)) / 100
    i += 1
    xa.append(xx * d)
    ya.append(yy * d)
ax.plot(xa, ya, color='m', linestyle='', marker='.')

assert len(xa) == len(ya)
n = len(xa)

X = np.zeros((n, k+1))
Y = np.zeros((n, 1))
for i in range(n):
  Y[i][0] = ya[i]
  for j in range(k+1):
    X[i][j] = xa[i] ** j

a = np.matmul(np.matmul(np.matrix(np.matmul(X.T, X)).I, X.T), Y)
a = np.squeeze(np.array(a))

xxa= np.arange(-1,1.0,0.01)
newya = []
for i in range(len(xxa)):
  temp = 0
  for j in range(k+1):
    temp += a[j] * xxa[i] ** j
  newya.append(temp)
newya = np.squeeze(np.array(newya))
print(len(newya), len(xa))

ax.plot(xxa, newya, color='g', linestyle='-', marker='')
plt.show()

k = 20

最小二乘法曲线拟合公式推导与代码实现

k = 10

最小二乘法曲线拟合公式推导与代码实现

k = 5

最小二乘法曲线拟合公式推导与代码实现

从上面几幅图也可以看出一点神经网络中过拟合和欠拟合的感觉,要刚刚好才能达到不错的效果。

相关文章: