首页 » 机器学习实战 » 机器学习实战全文在线阅读

《机器学习实战》15.2 Hadoop流

关灯直达底部

Hadoop是一个开源的Java项目,为运行MapReduce作业提供了大量所需的功能。除了分布式计算之外,Hadoop自带分布式文件系统。

本书既不是Java,也不是Hadoop的教材,因此本节只对Hadoop做简单介绍,只要能满足在Python中用Hadoop来执行MapReduce作业的需求即可。如果读者想对Hadoop做深入理解,可以阅读《Hadoop实战》1或者浏览Hadoop官方网站上的文档(http://hadoop.apache.org/)。 此外,Mahout in action2一书也为在MapReduce下实现机器学习算法提供了很好的参考资料。

1. Chuck Lam, Hadoop in Action (Manning Publications, 2010),中文版由人民邮电出版社出版。

2.Sean Owen, Robin Anil, Ted Dunning, and Ellen Friedman, Mahout in Action (Manning Publications, 2011),中文版即将由人民邮电出版社出版。

Hadoop可以运行Java之外的其他语言编写的分布式程序。因为本书以Python为主,所以下面将使用Python编写MapReduce代码,并在Hadoop流中运行。Hadoop流(http://hadoop.apache.org/common/docs/current/streaming.html)很像Linux系统中的管道(管道使用符号|,可以将一个命令的输出作为另一个命令的输入)。如果用mapper.py调用mapper,用reducer.py调用reducer,那么Hadoop流就可以像Linux命令一样执行,例如:

cat inputFile.txt | python mapper.py | sort | python reducer.py > outputFile.txt    

这样,类似的Hadoop流就可以在多台机器上分布式执行,用户可以通过Linux命令来测试Python语言编写的MapReduce脚本。

15.2.1 分布式计算均值和方差的mapper

接下来我们将构建一个海量数据上分布式计算均值和方差的MapReduce作业。示范起见,这里只选取了一个小数据集。在文本编辑器中创建文件mrMeanMapper.py,并加入如下程序清单中的代码。

程序清单15-1 分布式均值和方差计算的mapper

import sysfrom numpy import mat, mean, powerdef read_input(file):    for line in file:        yield line.rstrip    input = read_input(sys.stdin)    input = [float(line) for line in input]    numInputs = len(input)    input = mat(input)    sqInput = power(input,2)    print /"%dt%ft%f/" % (numInputs, mean(input), mean(sqInput))    print >> sys.stderr, /"report: still alive/"  

这是一个很简单的例子:该mapper首先按行读取所有的输入并创建一组对应的浮点数,然后得到数组的长度并创建NumPy矩阵。再对所有的值进行平方,最后将均值和平方后的均值发送出去。这些值将用于计算全局的均值和方差。

注意:一个好的习惯是向标准错误输出发送报告。如果某作业10分钟内没有报告输出,则将被Hadoop中止。

下面看看程序清单15-1的运行效果。首先确认一下在下载的源码中有一个文件inputFile.txt,其中包含了100个数。在正式使用Hadoop之前,先来测试一下mapper。在Linux终端执行以下命令:

cat inputFile.txt | python mrMeanMapper.py]    

如果在Windows系统下,可在DOS窗口输入以下命令:

python mrMeanMapper.py < inputFile.txt  

运行结果如下:

100 0.509570 0.344439report: still alive   

其中第一行是标准输出,也就是reducer的输入;第二行是标准错误输出,即对主节点做出的响应报告,表明本节点工作正常。

15.2.2 分布式计算均值和方差的reducer

至此,mapper已经可以工作了,下面介绍reducer。根据前面的介绍,mapper接受原始的输入并产生中间值传递给reducer。很多mapper是并行执行的,所以需要将这些mapper的输出合并成一个值。接下来给出reducer的代码:将中间的key/value对进行组合。打开文本编辑器,建立文件mrMeanReducer.py,然后输入程序清单15-2的代码。

程序清单15-2 分布式均值和方差计算的reducer

import sysfrom numpy import mat, mean, powerdef read_input(file):    for line in file:        yield line.rstripinput = read_input(sys.stdin)mapperOut = [line.split(/'t/') for line in input]cumVal=0.0cumSumSq=0.0cumN=0.0for instance in mapperOut:    nj = float(instance[0])    cumN += nj    cumVal += nj*float(instance[1])    cumSumSq += nj*float(instance[2])mean = cumVal/cumNvarSum = (cumSumSq - 2*mean*cumVal + cumN*mean*mean)/cumNprint /"%dt%ft%f/" % (cumN, mean, varSum)print >> sys.stderr, /"report: still alive/"  

程序清单15-2就是reducer的代码,它接收程序清单15-1的输出,并将它们合并成为全局的均值和方差,从而完成任务。

你可以在自己的单机上用下面的命令测试一下:

%cat inputFile.txt | python mrMeanMapper.py | python mrMeanReducer.py     

如果是DOS环境,键入如下命令:

%python mrMeanMapper.py < inputFile.txt | python mrMeanReducer.py     

后面的章节将介绍如何在多台机器上分布式运行该代码。你手边或许没有10台机器,没有问题,下节就会介绍如何租用服务器。