MapReduce实现线性回归

该博客介绍了如何在Hadoop2.6.0环境下使用MapReduce实现线性回归。作者详细阐述了实现思路,包括数据打乱、线性回归计算、参数值合并以及验证过程,并分享了运行结果和源码链接。
摘要由CSDN通过智能技术生成

1. 软件版本:

Hadoop2.6.0(IDEA中源码编译使用CDH5.7.3,对应Hadoop2.6.0),集群使用原生Hadoop2.6.4,JDK1.8,Intellij IDEA 14 。源码可以在https://github.com/fansy1990/linear_regression 下载。

2. 实现思路:

本博客实现的是一元一次线性方程,等于是最简单的线性方程了,采用的是Couresa里面的机器学习中的大数据线性方程的方法来更新参数值的(即随机梯度下降方法,当然也可以使用批量梯度下降方法来实现,只是在LinearRegressionJob中实现的不一样而已),如果对随机梯度下降或者批量梯度下降不了解的话,需要先去看看。下面是实现思路:

2.1 Shuffle Data(打乱数据):

如果要采用随机梯度下降的话,那么需要保持原始数据随机,所以这里的第一步就是随机打乱原始数据。采用的思路是:在Mapper端输出随机值作为key,输出当前记录作为value,在Reducer端直接遍历每个key的所有values,直接输出value以及NullWritable.get即可。
在这里添加一个额外的参数randN,这个参数表示在Mapper端随机值时,多少个原始数据使用同一个随机值,如果randN为1,那么每个原始数据都会使用一个随机值作为key,如果randN为2,那么每两个原始数据使用一个随机值,如果randN为0或小于0,那么所有数据都使用同一个随机值(注意,这个时候其实在Reducer端的values其实也是乱序的,请读者思考为什么?)。
其Mapper中map核心实现如下所示
 protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        if(randN <= 0) { // 如果randN 比0小,那么不再次打乱数据
            context.write(randFloatKey,value);
            return ;
        }
        if(++countI >= randN){// 如果randN等于1,那么每次随机的值都是不一样的
            randFloatKey.set(random.nextFloat());
            countI =0;
        }
        context.write(randFloatKey,value);
    }

2.2 Linear Regression(线性回归):

线性回归采用随机梯度下降的方法来更新theta0和theta1 (只实现了一元一次,所以只有两个参数),每个Mapper都会使用同样的初始化参数(theta0=1和theta1=0),在每个Mapper中使用自己的数据来更新theta0和theta1,更新的公式为:
theta0 = theta0 -alpha*(h(x)-y)x
theta1 = theta1 -alpha*(h(x)-y)x
其中,h(x)= theta0 + theta1 * x ;同时,需要注意这里的更新是同步更新,其核心代码如下所示:
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        float[] xy = Utils.str2float(value.toString().split(splitter));
        float x = xy[0];
        float y = xy[1];
        /
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值