必威体育Betway必威体育官网
当前位置:首页 > IT技术

M次多项式拟合

时间:2019-07-02 06:42:15来源:IT技术作者:seo实验室小编阅读:54次「手机版」
 

多项式拟合

M次多项式拟合问题实际就是一个最小二乘法的问题,作者在《统计学习方法》中并没有给出具体的推导公式,下文给出具体的推导公式。

设M次多项式为

fM(xI,w)=w0+w1xi+w2xi2+⋯+wMxiM=∑j=0Mwjxj=XiTw" role="presentation" style="text-align: center; position: relative;">fM(xI,w)=w0+w1xi+w2xi2++wMxiM=j=0Mwjxj=XiTw

其中w=(w0,w1,⋯,wM)" role="presentation" style="position: relative;">w=(w0,w1,,wM),Xi为矩阵

X=[1x1x12⋯x1M⋮⋮1xnxn2⋯xnM]" role="presentation" style="text-align: center; position: relative;">X=[1x1x12x1M1xnxn2xnM]

的第 i 行。于是我们可以得到损失函数

L(w)=12∑i=1N(f(xi,w)−yi)2=12∑i=1N(∑j=0Mwjxij−yi)2=12||Xw−y||22" role="presentation" style="text-align: center; position: relative;">L(w)=12i=1N(f(xi,w)yi)2=12i=1N(j=0Mwjxijyi)2=12||Xwy||22

这里的损失函数前面加了12" role="presentation" style="position: relative;">12,是为了方便计算。此外,这里转换为向量更加方便求解,书中是直接公式推导,没有使用向量方法,我们等会再看那种方法。

为了使损失函数最小化,只需要对w" role="presentation" style="position: relative;">w进行求导,然后令导数为0就可以获得结果。

∂L(w)∂w=XT(Xw−y)=XTXw−XTy" role="presentation" style="text-align: center; position: relative;">L(w)w=XT(Xwy)=XTXwXTy

从而可以求出来w=(XTX)−1XTy" role="presentation" style="position: relative;">w=(XTX)1XTy

" role="presentation" style="position: relative;">

接下来不使用向量进行求导:

L(w)=12∑i=1N(∑j=0Mwjxij−yi)2∂L(w)∂wk=12∑i=1N[2(∑j=0Mwjxij−yi)xik]=∑i=1N∑j=0Mwjxij+k−∑i=0Nyixik=0" role="presentation" style="position: relative;">L(w)=12i=1N(j=0Mwjxijyi)2L(w)wk=12i=1N[2(j=0Mwjxijyi)xik]=i=1Nj=0Mwjxij+ki=0Nyixik=0

所以要拟合多项式系数w0,w1,⋯,wM" role="presentation" style="position: relative;">w0,w1,,wM,需要求解下方的方程组。为了方便,省略∑" role="presentation" style="position: relative;">的上下标记

[N∑xi∑xi2⋯∑xiM∑xi∑xi2∑xi3⋯∑xIM+1⋮⋱⋮∑xiM∑xiM+1∑xiM+2⋯∑xi2M]{w0w1⋮wM}=[∑yi∑xiyi∑xi2yi⋮∑xiMyi]" role="presentation" style="text-align: center; position: relative;">[Nxixi2xiMxixi2xi3xIM+1xiMxiM+1xiM+2xi2M]{w0w1wM}=[yixiyixi2yixiMyi]

之后就可以计算出各个w的值了。

下文中是一个Python多项式拟合的代码,参考别人的博客HTTPs://blog.csdn.net/xiaolewennofollow/article/details/46757657。对于上面给出的线性方程组的公式,我们只需要求出左右矩阵和向量就可以获得w向量的结果。

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

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

#生成数据点
x=numpy.arange(-1,1,0.1)
y = [((a*a-1)*(a*a-1)*(a*a-1)+0.5)*numpy.sin(a*2) for a in x]
plt.plot(x,y)
i=0
x_offset=[]
y_offset=[]
#生成的曲线上的点进行偏移,相当于加上噪声
for xx in x:
    yy=y[i]
    d=float(random.randint(60,140))/100
    i+=1
    x_offset.APPend(xx*d)
    y_offset.append(yy*d)
ax.plot(x_offset,y_offset,color='m',linestyle='',marker='.')
#这个函数是用来求系数的,order是多项式的幂次数,x_offset,y_offset是生成的数据
def get_w(order,x_offset,y_offset):
    #存储从0到m次的幂方和
    saveMat=[]
    for j in range(0,2*order+1):
        sum=0
        for i in range(0,len(x_offset)):
            sum+=(x_offset[i]**j)
        saveMat.append(sum)

    #求左边的矩阵
    matLeft=[]
    for row in range(0,order+1):
        rowvector=saveMat[row:row+order+1]
        matLeft.append(rowvector)

    matLeft=numpy.array(matLeft)

    #求右边的向量
    matRight=[]
    for i in range(0,order+1):
        y=0.0
        for k in range(0,len(x_offset)):
            y+=y_offset[k]*(x_offset[k]**i)
        matRight.append(y)

    matRight=numpy.array(matRight)

    W=numpy.linalg.solve(matLeft,matRight)
    return W

'''
order=3
W=get_w(order,x_offset,y_offset)
    #进行曲线的拟合
xxa= numpy.arange(-1,1,0.1)
yya=[]
for i in range(0,len(xxa)):
    yy=0.0
    for j in range(0,order+1):
        dy=(xxa[i]**j)
        dy*=W[j]
        yy+=dy
    yya.append(yy)
ax.plot(xxa,yya,color='g',linestyle='-',marker='')
ax.legend()
plt.show()
'''

看下图order为3和9时候的曲线拟合情况(绿色的线是进行拟合的曲线)

3次多项式拟合

9次多项式拟合

我们可以看出随着M(多项式次数)的增大,模型越来越复杂,拟合的程度越来越好,训练误差也越来越小,训练误差不断逼近0。但是测试误差确并不如此,它会随着模型的复杂度的增大先减小再增大。下图就是训练误差和测试误差与模型复杂度的关系图

模型复杂度和测试误差训练误差的关系

相关阅读

分享到:

栏目导航

推荐阅读

热门阅读