VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 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)

相关教程