线性回归和逻辑回归的区别_Spark实现线性回归与逻辑回归算法

一.线性回归算法简介 

  线性回归(Linear Regression)是利用线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为一元线性回归,多于一个自变量情况的叫做多元线性回归。对于参数的求解,需要对函数进行评估以检测是否为最优。一般这个函数被称为损失函数(loss function),用来描述算法好坏的程度。

5dcfa4a27926e073a31b410880995554.png

  计算损失函数是线性回归的基础,计算损失函数一般使用最小二乘法或梯度下降法。

343c5c99ddb349f8d9e25ae13b31d1e3.png

二.最小二乘法

  最小二乘法【最小平方法】是一种数学优化技术。它通过最小化误差的平方来寻找数据的最佳函数匹配。利用最小二乘法可以简便地求出结果,并使得这些求得的结果与实际数据之间误差的平方和最小 。

  在Spark ML中,将训练特征转换为矩阵,结果转换为向量,误差函数不变。最小二乘法要求矩阵是列满秩的,而且求矩阵的逆比较慢。

关键概念解释:

  1. 线性独立【线性无关】:指一组向量中任意一个向量都不能由其它一个或几个向量线性表示。一个矩阵的列秩是矩阵的线性无关的列向量的极大数目,行秩与其类似。矩阵的列秩和行秩总是相等的,可以称为矩阵的秩。

三.梯度下降法

  参考头条文章:Python实现随机&批量梯度下降算法

四.线性回归算法代码实现

package org.com.tl.spark.mllibimport org.apache.log4j.{Level, Logger}import org.apache.spark.ml.regression.LinearRegressionimport org.apache.spark.sql.SparkSession/**  * Created by zhen on 2020/11/25.  */object LinearRegressionAnalyse {  /**    * 设置日志级别    */  Logger.getLogger("org").setLevel(Level.WARN)  def main(args: Array[String]) {    val spark = SparkSession.builder().appName("LinearRegressionAnalyse")      .master("local[2]")      .getOrCreate()    val sc = spark.sparkContext    // 加载训练数据    val allData = spark.read.format("libsvm")      .load("D:/spark-2.4.3/data/mllib/sample_linear_regression_data.txt")    allData.count()    val weights = Array(0.8,0.2) //设置训练集和测试集的比例    val split_data = allData.randomSplit(weights) // 拆分训练集和测试集    //随机取样,训练模型    val training = split_data(0)    //随机取样,预测数据    val testing = split_data(1)    // 创建线性回归模型    val lr = new LinearRegression()      .setMaxIter(10) // 最大迭代次数      .setRegParam(0.3) // 正则化参数      .setElasticNetParam(0.8) // 弹性系数    // 训练模型    val lrModel = lr.fit(training)    //各个维度的参数值,类似于一维函数y=ax+b中的a    println(s"Coefficients: ${lrModel.coefficients}")    println(s"Intercept: ${lrModel.intercept}") // 截距    // 模型评估    val trainingSummary = lrModel.summary    println(s"numIterations: ${trainingSummary.totalIterations}")    println(s"RMSE: ${trainingSummary.rootMeanSquaredError}") // RMSE:均方根差    println(s"r2: ${trainingSummary.r2}") // r2:判定系数,也称为拟合优度,越接近1越好    // 预测    val predictions = lrModel.transform(testing)    predictions.show()    sc.stop()  }}

执行结果:

4523059fc869f12980a3813fa65fd3e8.png
a036529c9f5a693b09ace800d05a5a90.png

  分析结果可以看出,预测的结果是很不理想的,要分析原因,首先看训练数据:

7cd1669004afaa99eda3f0fcf444d636.png

  从训练数据中可以看出,首先是训练数据的范围差异较大,第一列的结果值与vector向量参数值之间差异尤为明显;可以使用归一化的方式把数据都转换到0~1之间,实现的代码如下:

/**  * 最大值最小值  */val max = allData.select("label").rdd.map(row => row.getAs[Double]("label")).collect().maxval min = allData.select("label").rdd.map(row => row.getAs[Double]("label")).collect().minval broad_max = sc.broadcast(max)val broad_min = sc.broadcast(min)/**  * 定义自定义函数,实现归一化  */def normalization(label : Double) = {  val max = broad_max.value  val min = broad_min.value  (label-min) / (max - min)}val addNormalization = spark.udf.register("normalization", normalization _)    val normAllData = allData.withColumn("label", addNormalization(allData("label")))normAllData.count()

五.逻辑回归算法简介

  逻辑回归是一种广义线性回归(generalized linear model),因此与多元线性回归分析有很多相同之处。它们的模型形式基本上相同,其区别在于他们的因变量不同,多元线性回归直接将函数结果作为因变量。而逻辑回归则通过函数L将函数结果对应一个隐状态p,然后根据p与1-p的大小决定因变量的值。如果L是逻辑函数,就是逻辑回归,如果L是多项式函数就是多项式回归。

531d534d198491d16a116c5ada03d71c.png

六.逻辑回归算法代码实现

package org.com.tl.spark.mllibimport org.apache.log4j.{Level, Logger}import org.apache.spark.ml.classification.LogisticRegressionimport org.apache.spark.ml.linalg.Vectorsimport org.apache.spark.sql.SparkSession/**  * Created by zhen on 2020/11/25.  */object LogisticRegressionAnalyse {  /**    * 设置日志级别    */  Logger.getLogger("org").setLevel(Level.WARN)  def main(args: Array[String]) {    val spark = SparkSession.builder()      .appName("LogisticRegressionAnalyse")      .master("local[2]")      .getOrCreate()    // 加载训练数据    val allData = spark.read.format("libsvm")      .load("D:/spark-2.4.3/data/mllib/sample_libsvm_data.txt")    allData.count()    val weights = Array(0.8,0.2) //设置训练集和测试集的比例    val split_data = allData.randomSplit(weights) // 拆分训练集和测试集    // 创建逻辑回归对象    val lr = new LogisticRegression()        .setMaxIter(10)        .setRegParam(0.3)        .setElasticNetParam(0.8)    // 训练模型    val lrModel = lr.fit(split_data(0))    lrModel.transform(split_data(1))      .select("label", "features", "probability", "prediction")      .show()    val trainingSummary = lrModel.summary    // 评估    val accuracy = trainingSummary.accuracy    val falsePositiveRate = trainingSummary.weightedFalsePositiveRate // 失败率    val truePositiveRate = trainingSummary.weightedTruePositiveRate // 正确率    val fMeasure = trainingSummary.weightedFMeasure // 查全率    val precision = trainingSummary.weightedPrecision // 查准率    val recall = trainingSummary.weightedRecall // 召回率    println(s"Accuracy: $accuracyFPR: $falsePositiveRateTPR: $truePositiveRate" +      s"F-measure: $fMeasurePrecision: $precisionRecall: $recall")    //关闭spark    spark.stop()  }}

  执行结果:

840650435ae9d30f568911b107759253.png
78d107ea744fde7e3a7424ff9abfbec4.png

  从结果上来看还是令人满意的,先去看看训练数据:

47f0170afe1b9c51711e3614c7123d18.png

  相比于上面线性回归的连续型数据,使用逻辑回归【其实是逻辑分类】对离散型数据做二分类是比较容易的,得到较高的准确率是很正常的表现【毕竟蒙还有50%的准确率。。。】。

七.总结

  线性回归算法做回归预测不是一个很好的选择,线性回归一般应用于简单的逻辑,训练数据的维度较小;多维度的分析一般使用逻辑回归或神经网络;下面附上基本算法图鉴:

330444bbf75e3ec5d13307b53f54c541.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值