首页 > Python基础教程 >
-
用Python进行机器学习实例(2)
现在,我们已经对数据有了一个直观的认识,我们接下来要做的是找到一个真实的模型,并且能推断未来的数据走势。
用逼近误差(approximation error)来选择模型
在很多模型中选择一个正确的模型,我们需要用逼近误差来衡量模型预测性能,并用来选择模型。这里,我们用预测值和真实值差值的平方来定义度量误差:
1
2
|
def error(f, x, y): return sp. sum ((f(x) - y) * * 2 ) |
其中f表示预测函数。
用简单直线来拟合数据
我们现在假设该数据的隐含模型是一条直线,那么我们还如何去拟合这些数据来使得逼近误差最小呢?SciPy的polyfit()函数可以解决这个问题,给出x和y轴的数据,还有参数order(直线的order是1),该函数给出最小化逼近误差的模型的参数。
1
|
fp1, residuals, rank, sv, rcond = sp.polyfit(hours, hits, 1 , full = True ) |
fp1是polyfit函数返回模型参数,对于直线来说,它是直线的斜率和截距。
如果polyfit的参数full为True的话,将得到拟合过程中更多有用的信息,这里只有residuals是我们感兴趣的,它正是该拟合直线的逼近误差。
然后将该线在图中画出来:
1
2
3
4
5
6
7
|
#fit straight line model fp1, residuals, rank, sv, rcond = sp.polyfit(hours, hits, 1 , full = True ) fStraight = sp.poly1d(fp1) #draw fitting straight line fx = sp.linspace( 0 ,hours[ - 1 ], 1000 ) # generate X-values for plotting plt.plot(fx, fStraight(fx), linewidth = 4 ) plt.legend([ "d=%i" % fStraight.order], loc = "upper left" ) |
用更高阶的曲线来拟合数据
用直线的拟合是不是很好呢?用直线拟合的误差是317,389,767.34,这说明我们的预测结果是好还是坏呢?我们不妨用更高阶的曲线来拟合数据,看是不是能得到更好的效果。
其逼近误差为:
1
2
3
4
5
|
Error of straight line: 317389767.34 Error of Curve2 line: 179983507.878 Error of Curve3 line: 139350144.032 Error of Curve10 line: 121942326.364 Error of Curve50 line: 109504587.153 |
这里我们进一步看一下实验结果,看看我们的预测曲线是不是很好的拟合数据了呢?尤其是看一下多项式的阶数从10到50的过程中,模型与数据贴合太紧,这样模型不但是去拟合数据背后的模型,还去拟合了噪声数据,导致曲线震荡剧烈,这种现象叫做 过拟合 。
小结
从上面的小实验中,我们可以看出,如果是直线拟合的话就太简单了,但多项式的阶数从10到50的拟合又太过了,那么是不是2、3阶的多项式就是最好的答案呢?但我们同时发现,如果我们以它们作为预测的话,那它们又会无限制增长下去。所以,我们最后反省一下,看来我们还是没有真正地理解数据。
衡量性能指标
作为一个ML的初学者,在衡量学习器性能方面会遇到很多问题或错误。如果是拿你的训练数据来进行测试的话,这可能是一个很简单的问题;而当你遇到的不平衡的训练数据时,数据就决定了预测的成功与否。
回看数据
我们再仔细分析一下数据,看一下再week3到week4之间,好像是有一个明显的拐点,所以我们把week3.5之后的数据分离出来,训练一条新的曲线。
1
2
3
4
5
6
7
8
9
|
inflection = 3.5 * 7 * 24 #the time of week3.5 is an inflection time1 = hours[:inflection] value1 = hits[:inflection] time2 = hours[inflection:] value2 = hits[inflection:] fStraight1p = sp.polyfit(time1,value1, 1 ) fStraight1 = sp.poly1d(fStraight1p) fStraight2p = sp.polyfit(time2,value2, 1 ) fStraight2 = sp.poly1d(fStraight2p) |