《机器学习系统设计》学习笔记(2)

一个真实的例子:根据一家公司服务器过去的访问量来预测未来的访问量。

具体步骤:

1.读取数据:

服务器的访问量被记录成一个csv文件web_traffic.csv,格式如下:

1 2272
2 nan
3 1386
4 1365
5 1488
6 1337
7 1883
8 2283
9 1335
10 1025
11 1139
12 1477

数据中第一列是小时数,第二列是那个小时访问的访问量。使用scipy这个工具将它读入一个scipy自定义的用于科学计算的数组(代码如下):

import scipy as sp
data = sp.genfromtxt("web_traffic.tsv",delimiter='\t')
print data[:10]

上述代码包含打印数据前十行的逻辑,其结果如下。

[[ 1.00000000e+00 2.27200000e+03]
[ 2.00000000e+00 nan]
[ 3.00000000e+00 1.38600000e+03]
[ 4.00000000e+00 1.36500000e+03]
[ 5.00000000e+00 1.48800000e+03]
[ 6.00000000e+00 1.33700000e+03]
[ 7.00000000e+00 1.88300000e+03]
[ 8.00000000e+00 2.28300000e+03]
[ 9.00000000e+00 1.33500000e+03]
[ 1.00000000e+01 1.02500000e+03]]

关于对科学数组的操作,可以参考如下网页:http://wiki.scipy.org/Tentative_NumPy_Tutorial

2.做数据清洗和预处理

我们发现这些数据项中有一些无效的值,瞧见数据中被标红的nan么?这代表了无效信息。我们统计一下样例数据集中无效数据的个数

x = data[:,1]
y = data[:,1]
sp.sum(sp.isnan(y))

我们得到结果为8,也就是8个无效数据,而数据集的个数是743,可以忍。我们把它洗掉。btw,numpy工具还是很方便的。

x = x[~sp.isnan(y)]
y = y[~sp.isnan(y)]

为了得到更加直观的印象,我们将它可视化。这时候就使用到了图形工具Matplotlib. 第一次使用,和Matlib很像,当年可是用Matlib画了不少图。

 

我们看到,很明显趋势是个上升趋势,但怎么做出预测呢?

使用Matplotlib画图的教程如下:http://matplotlib.org/users/pyplot_tutorial.html  

我这里上不去,只能用代理上,怀疑被墙了,有同学说不是。如果你跟我遇到同样问题,可以试试代理。先不F 我们的GFW了。 pyplot包的用法见下面链接:http://matplotlib.org/api/pyplot_api.html 同样自己想办法。

 

3.使用正确的模型和学习方法

我们不知道模型是什么,我们要找到它,并且用拟合出来的模型来预测未来!

从上面的图,我第一个印象是我本科时代学的一门课:数值逼近。数值逼近的核心就是根据现有数据找到规律,也就是拟合函数。读下去发现,书中的例子就是一种典型的数值逼近方法,但是记得当时的课程没有迭代和学习这个概念。继续往下看。

 

假定这个函数为f,那么怎么判定这个函数是一个较好的模型呢?常见的做法就是看样本数据与函数之间的误差和有多大,为了避免负数,一般会用方差。这样就定义了一个函数:

def error(f,x,y):
    return sp.sum((f(x)-y)**2)

 

f是什么样子的呢?,最简单的就是一次函数 我们f定义为 f(x) = ax +b 现在的工作就是要确定a和b是什么了。SciPy中有个ployfit函数,可以让我们走捷径。它能够找出a和b,使得上面定义的error返回最小值(也就是对数据最拟合)

   fp1, residuals, rank, sv, rcond = sp.polyfit(x,y,1,full =True)
   print fp1

其中fp1是一个二维数组,里边有a和b的值

打印出来的值为[2.59619213  989.02487106]

我们得到了线性函数 f(x)= 2.59619213x + 989.02487106

它的误差有多大呢?还记得那个error函数么?

我们用如下代码构造一个这样的函数:

f1 = sp.poly1d(fp1)
print (error(f1,x,y))

我们得到了一个结果:317389767.34 结果好不好呢?先不说。画张图看看。加入如下代码:

fx = sp.linspace(0,x[-1],1000) #生成X来作图
    plt.plot(fx,f1(fx),linewidth=4) #画出曲线
    plt.legend(["d=%i" % f1.order],loc ="upper left") #角标

得到的图如下:

很明显从图里边看出来,从第四周开始,这条直线显然代表不了那些数据点了。317389767.34这个值好不好呢?因为全是做的拟合,肯定都有误差。我们先拿这个数保底,看看能不能找到更好的模型吧。从这里看,显然一次线性函数不是描述模型的好选择。后面就是尝试不同的迭代方法了。 How? 下节继续吧。

 

btw,要是上大学的时候有这本书该多好!现在的小朋友们真是幸福。想学东西会有这么多好资源。

 

posted @ 2014-09-17 23:32  skytraveler  阅读(1590)  评论(3编辑  收藏  举报