用Python举办呆板进修实例
提要
本文是用Python编程语言来举办呆板进修小尝试的第一篇。主要内容如下:
读入数据并清洗数据
摸索领略输入数据的特点
阐明如作甚进修算法泛起数据
选择正确的模子和进修算法
评估措施表示的精确性
读入数据 Reading the data
当读入数据时,你将面对处理惩罚无效或丢失数据的问题,好的处理惩罚方法对比于准确的科学来说,更像是一种艺术。因为这部门处理惩罚适当可以合用于更多的呆板进修算法并因此提高乐成的概率。
用NumPy有效地品味数据,用SciPy智能地接收数据
Python是一个高度优化的表明性语言,在处理惩罚数值沉重的算法方面要比C等语言慢许多,那为什么依然有许多科学家和公司在计较麋集的规模将赌注下在Python上呢?因为Python可以很容易地将数值计较任务分派给C或Fortran这些底层扩展。个中NumPy和SciPy就是个中代表。NumPy提供了许多有效的数据布局,好比array,而SciPy提供了许多算法来处理惩罚这些arrays。无论是矩阵操纵、线性代数、最优化问题、聚类,甚至快速傅里叶调动,该东西箱都可以满意需求。
读入数据操纵
这里我们以网页点击数据为例,第一维属性是小时,第二维数据是点击个数。
import scipy as sp data = sp.genfromtxt('web_traffic.tsv', delimiter='\t')
预处理惩罚和清洗数据
当你筹备好了你的数据布局用于存储处理惩罚数据后,你大概需要更多的数据来确保预测勾当,可能拥有了很大都据,你需要去思考如何更好的举办数据采样。在将原始数据(rawdata)举办练习之前,对数据举办提炼可以起到很好的浸染,有时,一个用提炼的数据的简朴的算法要比利用原始数据的高级算法的表示结果要好。这个事情流程被称作特征工程(feature engineering)。Creative and intelligent that you are, you will immediately see the results。
由于数据会合大概尚有无效数值(nan),我们可以事先看一下无效值的个数:
hours = data[:,0] hits = data[:,1] sp.sum(sp.isnan(hits))
用下面的要领将其过滤掉:
#cleaning the data hours = hours[~sp.isnan(hits)] hits = hits[~sp.isnan(hits)]
为了将数据给出一个直观的认识,用Matplotlib的pyplot包来将数据泛起出来。
import matplotlib.pyplot as plt plt.scatter(hours,hits) plt.title("Web traffic over the last month") plt.xlabel("Time") plt.ylabel("Hits/hour") plt.xticks([w*7*24 for w in range(10)], ['week %i'%w for w in range(10)]) plt.autoscale(tight=True) plt.grid() plt.show()
其显示结果如下:
选择符合的进修算法
选择一个好的进修算法并不是从你的东西箱中的三四个算法中挑选这么简朴,实际上有更多的算法你大概没有见过。所以这是一个衡量差异的机能和成果需求的深思熟虑的进程,好比执行速度和精确率的衡量,,可扩展性和易用性的均衡。
此刻,我们已经对数据有了一个直观的认识,我们接下来要做的是找到一个真实的模子,而且能揣度将来的数据走势。
用迫近误差(approximation error)来选择模子
在许多模子中选择一个正确的模子,我们需要用迫近误差来权衡模子预测机能,并用来选择模子。这里,我们用预测值和真实值差值的平方来界说怀抱误差:
def error(f, x, y): return sp.sum((f(x)-y)**2)
个中f暗示预测函数。
用简朴直线来拟合数据
我们此刻假设该数据的隐含模子是一条直线,那么我们还如何去拟合这些数据来使得迫近误差最小呢?SciPy的polyfit()函数可以办理这个问题,给出x和y轴的数据,尚有参数order(直线的order是1),该函数给出最小化迫近误差的模子的参数。
fp1, residuals, rank, sv, rcond = sp.polyfit(hours, hits, 1, full=True)
fp1是polyfit函数返回模子参数,对付直线来说,它是直线的斜率和截距。
假如polyfit的参数full为True的话,将获得拟合进程中更多有用的信息,这里只有residuals是我们感乐趣的,它正是该拟合直线的迫近误差。
然后将该线在图中画出来:
#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")
用更高阶的曲线来拟合数据
#p#分页标题#e#
用直线的拟合是不是很好呢?用直线拟合的误差是317,389,767.34,这说明我们的预测功效是好照旧坏呢?我们不妨用更高阶的曲线来拟合数据,看是不是能获得更好的结果。
其迫近误差为:
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之后的数据疏散出来,练习一条新的曲线。
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)
显然,这两条直线更好的描写了数据的特征,固然其迫近误差照旧比那些高阶多项式曲线的误差要大,可是这种方法的拟合可以更好的获取数据的成长趋势。相对付高阶多项式曲线的过拟合现象,对付低阶的曲线,由于没有很好的描写数据,而导致欠拟合的景象。所觉得了更好的描写数据特征,利用2阶曲线来拟合数据,来制止过拟合和欠拟合现象的产生。
练习与测试
我们练习获得了一个模子,这里就是我们拟合的两个曲线。为了验证我们练习的模子是否精确,我们可以在最初练习时将一部门练习数据拿出来,当做测试数据来利用,而不只仅通过迫近误差来鉴别模子优劣。
总结
这一小节作为呆板进修小尝试的引入,主要通报两点意思:
1、要练习一个进修器,必需领略和提炼数据,将留意力从算法转移到数据上
2、进修如何举办呆板进修尝试,不要夹杂练习和测试数据