继续第二篇笔记中的例子。
3.不断的迭代与探索的过程
从上篇的图看到,直线并不能很好的代表week4以后的趋势。既然一阶函数不行,我们试试二阶函数?
f(x)= ax**2 + bx + c
继续使用polyfit这个函数来确定a,b,c的值:
f2p =sp.polyfit(x,y,2) print f2p
上述代码得到了一个数组
[ 1.05322215e-02 -5.26545650e+00 1.97476082e+03],这就是a,b,c分别的值。
f2 = sp.poly1d(f2p) print(error(f2,x,y))
继续计算一下残差平方和是:179983507.878 ,显然要比1次的好。如果阶数越高,效果就越好,我们为什么不进一步增加阶数?
try一下阶数为3,10,100的情况
f3 = sp.poly1d(sp.polyfit(x, y, 3)) f10 = sp.poly1d(sp.polyfit(x, y, 10)) f100 = sp.poly1d(sp.polyfit(x, y, 100)) print 'd3=' ,(error(f3,x,y)) print 'd10=' ,(error(f10,x,y)) print 'd100=' , (error(f100,x,y))
残差平方和结果为:
d3= 139350144.032
d10= 121942326.364
d100= 109452403.459
结果是越来越好了,但是100项式的模型是否真的代表了用户真实行为呢?我们继续把图画出来。
紫色的曲线代表了100阶多项式。看出它的问题了么?抖动的太厉害了!响应了所有数据的要求,但是,里边其实有不少数据算是噪声数据,比如偏离太远的点,没有代表性。这样的拟合被叫做 过度拟合(overfitting),10阶也同样类似的问题(如果数据更多,效果会更加明显)。所以,一味的提高模型的复杂度并不是一个好办法。
问题在哪里?从建模角度似乎遇上了一些瓶颈。我们返回来看数据,我们真的的理解数据了么?