假设现在有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
从上面几幅图也可以看出一点神经网络中过拟合和欠拟合的感觉,要刚刚好才能达到不错的效果。