Spark Mllib 回归学习笔记一(java):线性回归(线性,lasso,岭),广义回归

来源:互联网 发布:win10查看网卡mac地址 编辑:程序博客网 时间:2024/04/27 06:47

本博使用spark2.0.0版本,对于每一个回归这里不详讲原理,附上链接,有兴趣的伙伴可以点开了解。
其他参考资料:
官方文档
官方接口文档

线性回归

线性拟合,就是预测函数是一条直线,对于眼前一堆分布貌似有规律的点,我们假定一条直线拟合这些点:

h(x)=a0+a1x1+a2x2+..+anxn

方程系数ai是我们要求的
变量xi是i个变量或者说属性
J(θ)是损失函数(也称成本函数):我们假定的这条直线的输出与训练数据的标签的差值的和,再加上一个正则项。

正则化是为了避免过拟合情况。
根据正则项的不同,在spark中又分出三种回归:LinearRegression、Lasso和RidgeRegression(岭回归)

采用L1正则化时为Lasso回归(元素绝对值),采用L2时为RidgeRegression回归(元素平方),没有正则化时就是线性回归。

比如岭回归的损失函数:

显然,损失函数值越小说明当前这条直线拟合效果越好,那么如何最小化损失值捏?
通常用梯度下降法!,具体原理可以参考这里

spark中线性回归算法可使用的类包括LinearRegression、LassoWithSGD、RidgeRegressionWithSGD(SGD代表随机梯度下降法),这几个类都有几个可以用来对算法调优的参数

  • numIterations 要迭代的次数
  • stepSize 梯度下降的步长(默认1.0)
  • intercept 是否给数据加上一个干扰特征或者偏差特征(默认:false)
  • regParam Lasso和ridge的正规参数(默认1.0)

调用算法的方式在不同语言中有所不同,像python,你可以LinearRegressionWithSGD.train(),对其传参,然而,java和scala你需要创建对象,用setter设置参数,用fit训练模型

实例

操作数据下载

package linear;import java.util.Arrays;import org.apache.spark.api.java.*;import org.apache.spark.api.java.function.Function;import org.apache.spark.mllib.linalg.Vector;import org.apache.spark.mllib.linalg.Vectors;import org.apache.spark.mllib.regression.LabeledPoint;import org.apache.spark.mllib.regression.LinearRegressionModel;import org.apache.spark.mllib.regression.LinearRegressionWithSGD;import org.apache.spark.SparkConf;import scala.Tuple2;public class LinearRegresion {    /**     * @param args     */    public static void main(String[] args) {        SparkConf sparkConf = new SparkConf().setAppName("Regresion").setMaster("local[*]");        JavaSparkContext sc =  new JavaSparkContext(sparkConf);        JavaRDD<String>  data = sc.textFile("/home/monkeys/lpsa.txt");        //一、整理数据:把每一行原始的数据(num1, num2 num3...)转换成LabeledPoint(label, features)        JavaRDD<LabeledPoint> parsedData = data.filter( //过滤一下,不读取空行                new Function<String, Boolean>(){                    public Boolean call(String line){                        if(line.length() > 3)                            return true;                        return false;                    }                }                ).map(//用map对每一行数据操作一下                new Function<String, LabeledPoint>(){                    public LabeledPoint call(String line){                                              String[] parts = line.split(",");                            String[] features = parts[1].split(" ");                               double[] v = new double[features.length];                            for(int i = 0; i < features.length - 1; i ++)                                v[i] = Double.parseDouble(features[i]);                            return   new LabeledPoint(Double.parseDouble(parts[0]), Vectors.dense(v));                                          }                }    );        parsedData.cache();        //迭代次数        int numIterations = 100;        //二、训练:用训练集和迭代次数为参进行模型训练        final LinearRegressionModel model = LinearRegressionWithSGD.train(JavaRDD.toRDD(parsedData), numIterations);        //三、预测        JavaRDD<Tuple2<Double, Double>> valuesAndPreds = parsedData.map(                new Function<LabeledPoint, Tuple2<Double, Double>>(){                    public Tuple2<Double, Double> call(LabeledPoint point){                        double prediction = model.predict(point.features());                        return new Tuple2<Double, Double>(prediction, point.label());                    }                }                );        //四、误差计算        double MSE = new JavaDoubleRDD(valuesAndPreds.map(                new Function<Tuple2<Double, Double>, Object>(){                    public Object call(Tuple2<Double, Double> pair){                        return Math.pow(pair._1() - pair._2(), 2.0);                    }                }                ).rdd()).mean();        System.out.println("training MeanSquared Error = " + MSE);        //五、保存        model.save(sc.sc(),"myModelPath" );        LinearRegressionModel sameModel = LinearRegressionModel.load(sc.sc(), "myModelPath");    }}

 广义回归(GLM)

前面的线性回归输出结果服从高斯分布,当回归结果服从泊努利分布,即0-1分布时,其为逻辑回归,无论是高斯还是逻辑,抑或伽马,泊松等等,还有其他的,都属于指数族分布
概率能写成形如 P(y;η)=b(y)exp(ηTT(y)?a(η)) 的我们就称其为指数族分布。
显然,广义回归的范围就很大啦,所以,在spark的java官方apl文档我们可以看到很多由GeneralizedLinearRegression点出来的回归模型。

这里不一一介绍其下的分布模型,每一种模型有其概率分布,相应地有他们的损失函数,最小化损失函数,使假定函数的预测效果能更好地接近我们的真实结果是贯穿的思想。

0 0