假设现在有n对坐标系中的点,现在要做k阶多项式拟合,多项式函数如下:
(1)
如果将所有已知的点代入公式1就可以得到n组等式:
...
这些不等式不一定的有解的,就是说在k阶多项式的曲线下不能拟合每个点,所以我们需要求多项式计算出来的y与真实y之间最小来实现尽量拟合每个点。
(2)
将公式1代入2可以得到
(3)
可以通过公式3对求偏导后令其为0来求解所有a的值,得到下面的式子
......
整理一下这些方程可以得到
......
写成矩阵的表达
\
这个式子还可以继续分解
假设,
那么上面的矩阵计算可以简化为,所以得到
这就是二项式曲线拟合的公式。下面用代码来实现看看拟合效果
import numpy as npimport matplotlib.pyplot as pltimport randomfig = plt.figure()ax = fig.add_subplot(111)k = 9x = 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 = 0xa = []ya = []for xx in x:yy = y[i]d = float(random.randint(60, 140)) / 100i += 1xa.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] ** ja = 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 = 0for j in range(k+1):temp += a[j] * xxa[i] ** jnewya.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
从上面几幅图也可以看出一点神经网络中过拟合和欠拟合的感觉,要刚刚好才能达到不错的效果。