Spark中DataFrame版的相关系数计算——DataFrameStatFunctions,Spark线性回归pipline

前言:

很多人还在实用RDD的相关API,为跟上“未来”,咱讨论下DataFrame版的相关API。

MLlib 的基于 RDD 的 API 现在处于维护状态。

从 Spark 2.0 开始, spark.mllib 包中的基于 RDD 的 API 已经进入了维护模式。Spark 的主要的机器学习 API 现在是 spark.ml 包中的基于 DataFrame 的 API 。

有什么影响?

MLlib 仍将支持基于 RDD 的 API ,在 spark.mllib 中有 bug 修复。
MLlib 不会为基于 RDD 的 API 添加新功能。
在 Spark 2.x 发行版本中, MLlib 将向基于 DataFrames 的 API 添加功能,以达到与基于 RDD 的 API 的功能奇偶校验。
在达到功能奇偶校验(大概估计为 Spark 2.3 )之后,基于 RDD 的 API 将被弃用。
预计将在 Spark 3.0 中删除基于 RDD 的 API 。
为什么 MLlib 切换到基于 DataFrame 的 API ?

DataFrames 提供比 RDD 更加用户友好的 API 。 DataFrames 的许多好处包括 Spark Datasources,SQL/DataFrame 查询,Tungsten 和 Catalyst 优化以及跨语言的统一 API 。
用于 MLlib 的基于 DataFrame 的 API 为 ML algorithms (ML 算法)和跨多种语言提供了统一的 API 。
DataFrames 便于实际的 ML Pipelines (ML 管道),特别是 feature transformations (特征转换)。有关详细信息,请参阅 Pipelines 指南 。

##正文
在将数据“喂”给模型之前,预处理中很重要的一步是去除冗余数据。
关于计算相关系数前是否需要将数据标准化:
大部分人表示“可以不用,因为相关系数本身就是一个标准化的统计量,协方差可以用来表示变量间共同变化的程度,而相关系数是协方差标准化后得到的统计量。”
我还没求证,等放上几天,我再比较不同结果得下结论。

  1. 想想含有n个特征的数据集,计算一个n X n的相关系数矩阵【我只计算了对角线的一侧,因为X与Y和Y与X的相关系数是相等的】,并将结果保存在Double二维数组中。可以看到,部分列之间的相关性确实很高。但别急,现在还不能删,因为我们还不知道删除哪一个变量更为合理。
    这里写图片描述
  2. 对数组中的数处理为绝对值之后复制一份,对副本进行排序(NaN之前已经被处理为0),每次取复制的数组中的第一个值(前提是大于阈值0.8);在二维数组中找到对应的两个变量记为indexX和indexY
  3. 计算indexX和其他所有变量的相关系数的绝对值之和,记为sumX;同理,对indexY,记为sumY。比较,删除sum值较大的那一个变量(对于DataFrame删)
  4. 重复2-3步骤,直到处理完复制的数组中的所有大于阈值的值
  5. 保存清洗过后的数据

代码

其实不想贴代码,因为代码不“漂亮”,有较多的for循环。一方面是对scala还不能灵活运用,一方面没找到DataFrame中直接对变量矩阵进行运算得出相关系数矩阵的方法。所以就自己用for循环造了。

package main.scala.firstput

import org.apache.log4j.{
    Level, Logger}
import org.apache.spark.sql.{
    DataFrame, SparkSession}

/**
  * @author 王海[https://github.com/AtTops]
  *         package main.scala.firstput
  *         description 计算相关性矩阵,将大于阈值0.8的挑选删除
  *         Date 2018/1/2 9:35
  *         Version V1.0
  */
object GetCorrelationMartix {
    
  var myTrainCsvPath: String = "yourpath"
  var secondTrainCsvPath: String = "yourpath"

  /**
    * 使用DataFrameStatFunctions中的API
    * TODO:参考mlib中的correlationExample.scala,修改为矩阵运算
    */
  def correlationAndCleanAgain_w(columnNames: Array[String], dataFrame: DataFrame): DataFrame = {
    
    // 计算一个n X n的相关系数矩阵【我只计算了对角线的一侧】,并将结果保存在Double二维数组中
    val storeCorrsMatrix = Array.ofDim[Double](columnNames.length, columnNames.length) // 使用ofDim创建二维数组
    var tempDf: DataFrame = dataFrame
    for (i <- 0 until columnNames.length - 1) {
     // 我们仅计算矩阵对角线一侧就行
      //      println(f"${columnNames(i)}%5s 与其他列-------------------------------------------") // 这里的f插值没有起作用
      for (j <- i + 1 until columnNames.length) {
    
        var corrValue: Double = dataFrame.stat.corr(columnNames(i), columnNames(j))
        if (corrValue < 0)
          corrValue = corrValue.abs // 处理为绝对值
        else if (corrValue.isNaN)
          corrValue = 0 // NaN处理为0
        /*        if (corrValue > 0.8)
                  println(s"${columnNames(i)}与${columnNames(j)}的相关系数值为:$corrValue") // s字符串插值器,scala2.10添加*/
        storeCorrsMatrix(i)(j) = corrValue
      }
    }
    println("它应该是0:" + storeCorrsMatrix(5)(5) + " ;它应该是0.9645:" + storeCorrsMatrix(22)(23)) // 简单验证

    val corrsMatrixClong: Array[Double] = storeCorrsMatrix.flatten.sortWith(_ > _) // 二维数组按行拼接为一维数组,然后从小到大排序
    //    storeCorrsMatrix.copyToArray(corrsMatrixClong, 0)
    /*println("storeCorrs数组的长度为:" + storeCorrs.length) // 276(23+22+21+...1)
    println("front_track与rear_track的相关系数值为:" + storeCorrs(storeCorrs.length-1))*/
    //    println(corrsMatrixClong.mkString("  "))
    println(corrsMatrixClong.length) // 576=24*24
    // 每次取复制的数组中的第一个值(前提是大于阈值0.8);在二维数组中找到对应的两个变量的位置记为valueX和valueY
    // 为了简便,我取的下标,因为我这里就8个大于阈值0.8的数
    for (i <- 0 to 7) {
    
      val indexArray: Array[Int] = findIndexByValue_w(storeCorrsMatrix, corrsMatrixClong(i))
      val indexX = indexArray(0
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值