spark mlib中的随机梯度下降算法

线性回归是利用被称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析

关于线性回归,逻辑回归的一些讲解

http://blog.csdn.net/viewcode/article/details/8794401

一般来说有最小二乘法与梯度下降算法

可以把最小二乘法看作是数学家的算法,梯度下降算法看作是程序员的算法(毕竟是搜索嘛)

算法具体的定义就不叙述了

梯度下降算法就是让损失函数的值降导最小(有可能是局部最优解)

梯度下降算法大致有两种

一,批量梯度下降算法

计算所有的数据,算出导数,然后沿着导数的反方向使损失函数减小

二,随机梯度下降算法

与批量梯度下降算法的差别就是计算的数据是从所有的数据中随机抽取的一部分

最小二乘法的准确度当然比随机梯度下降算法要高,但最小二乘法中涉及到求矩阵的逆,这是非常耗时间的,在数据很大的时候我们一般选取梯度下降算法

以上是理论内容

mlib中给出的就是随机梯度下降算法(可以设置每次计算抽取的比例,默认是1.0)

程序员要需要实现算法,具体编程过程中还有一些细节需要注意

eg:

梯度下降的速率,这个很关键,速率大了可能会在极值处震荡,速率小了收敛的速度会变慢,编程中的速率是   设置的初始速率/sqrt(迭代的次数),越接近极值的部分速率越小

还有个步长的设置,一般经验值是0.01~0.1  刚开始学习书上写的1,结果一直都不对,后来慢慢尝试自己分析,找到了问题所在,算是第一次调参吧。步长过大会使结果在最优值左右震荡,步长过去,则根本走不过去,悲伤的故事.

步长为1的时候,出问题的数据是每个特征值都大于1.0,当我在步长为1.0的时候,训练了1e4次,结果归于正常。

object Main {
  //产生我们需要的数据
    def makedata(){
       // y=3x+4y+2.5z+g
        var o=new PrintWriter("/home/hadoop/hei")
        val d=1
        for(j<- 1 until 20){
          var x=(new Random).nextDouble()*d
          var y=(new Random).nextDouble()*d
          var z=(new Random).nextDouble()*d
          var g=(new Random).nextDouble()*d
         o.println((3*x+4*y+2.5*z+g)+","+x+" "+y+" "+z+" "+g)
        }
          o.close()
    }
     def main(args: Array[String]): Unit = {
        makedata()
        val sc=new SparkContext(new SparkConf().setAppName("gg").setMaster("local"))
        val data = sc.textFile("/home/hadoop/hei").map { x =>val m=x.split(",")
            LabeledPoint(m(0).toDouble,Vectors.dense(m(1).split(" ").map {_.toDouble}))}
        //设置需要的参数
        val numIterations=100
        val stepSize=0.1
        //训练模型
        val model=LinearRegressionWithSGD.train(data, numIterations, stepSize)
        //输出权重及偏置
        println(model.weights)
        println(model.intercept)
        //预测数据
        val predict=model.predict(data.map { x => x.features })
        val predictlable=predict.zip(data.map { x => x.label })
        predictlable.foreach(f=>println(f._1+"                "+f._2))
        //计算误差
        val loss=predictlable.map(f=>
        math.pow((f._1-f._2),2.0)
        ).reduce(_+_)/predict.count().toDouble
        println(loss)
     }
}


你可能感兴趣的:(spark,机器学习)