spark LinearRegression 预测缺失字段的值
最近在做金融科技建模的时候,字段里面很多缺少值得时候,模型对于新用户的预测会出现很大的不稳定,即PSI较大的情况。
虽然我们依据字段IV值得大小不断的在调整字段且开发新变量,但是很多IV值很大的字段直接用平均值、或者0代替显然不够合理。
所以,我们在尝试把字段缺失值当作需要预测的值,把该字段不缺失的当作y,用其他字段当作X,去预测该字段缺失值得值。不同于机器学习的回归和分类预测。
这里的预测结果是一个具体的值,它的范围从负无穷到正无穷都有可能。
数据直接读存于Hive,代码如下:
import org.apache.spark.sql.{DataFrame, Row, SQLContext, SaveMode}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.ml.regression.LinearRegression
import org.apache.spark.mllib.regression.LabeledPoint
import  org.apache.spark.ml.regression.LinearRegressionModel
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}
import scala.collection.mutable.ArrayBuffer
//  select   corr(cast(p.cnt_addbook_one as double),cast(l.cnt_addbook_one as double))as corrs  from   lkl_card_score.predictcnt_addbook_one20180201  p join lkl_card_score.fieldValuePredictModel3
//l on p.order_id=l.order_src  where l.cnt_addbook_one<>0
//
object predictcnt_addbook_one20180201 {
  def main(args: Array[String]): Unit = {
    val cf = new SparkConf().setAppName("ass").setMaster("local")
    val sc = new SparkContext(cf)
    val sqlContext = new SQLContext(sc)
    val hc = new HiveContext(sc)
    import sqlContext.implicits._
     val data = hc.sql(s"select * from lkl_card_score.fieldValuePredictModel3 where cnt_addbook_one<>0   and cnt_addbook_one%2=1").map {
          row =>
            val arr = new ArrayBuffer[Double]()
            //剔除label、phone字段
            for (i <-  until row.size) {
              if (row.isNullAt(i)) {
                arr += 0.0
              }
              else if (row.get(i).isInstanceOf[Int])
                arr += row.getInt(i).toDouble
              else if (row.get(i).isInstanceOf[Double])
                arr += row.getDouble(i)
              else if (row.get(i).isInstanceOf[Long])
                arr += row.getLong(i).toDouble
              else if (row.get(i).isInstanceOf[String])
                arr += 0.0
            }
            LabeledPoint(row.getLong().toDouble,Vectors.dense(arr.toArray))
        }.toDF("Murder","features")
    // 建立模型,预测谋杀率Murder
    // 设置线性回归参数
      val lr1 = new LinearRegression()
     val lr2 = lr1.setFeaturesCol("features").setLabelCol("Murder").setFitIntercept(true)
    // RegParam:正则化
    val lr3 = lr2.setMaxIter().setRegParam(0.3).setElasticNetParam(0.8)
    // 将训练集合代入模型进行训练
      val lr = lr3
    val lrModel = lr.fit(data)
    // 输出模型全部参数
    lrModel.extractParamMap()
    println(s"Coefficients: ${lrModel.coefficients} Intercept: ${lrModel.intercept}")
    lrModel.write.overwrite().save(s"hdfs://ns1/user/songchunlin/model/predictcnt_addbook_one20180202")
    // 模型进行评价
    val trainingSummary = lrModel.summary
    println(s"numIterations: ${trainingSummary.totalIterations}")
    println(s"objectiveHistory: ${trainingSummary.objectiveHistory.toList}")
    trainingSummary.residuals.show()
    println(s"RMSE: ${trainingSummary.rootMeanSquaredError}")
    println(s"r2: ${trainingSummary.r2}")
    val predict = hc.sql(s"select * from lkl_card_score.fieldValuePredictModel3 where cnt_addbook_one<>0   and cnt_addbook_one%2=0").map {
      row =>
        val arr = new ArrayBuffer[Double]()
        //剔除label、phone字段
        for (i <-  until row.size) {
          if (row.isNullAt(i)) {
            arr += 0.0
          }
          else if (row.get(i).isInstanceOf[Int])
            arr += row.getInt(i).toDouble
          else if (row.get(i).isInstanceOf[Double])
            arr += row.getDouble(i)
          else if (row.get(i).isInstanceOf[Long])
            arr += row.getLong(i).toDouble
          else if (row.get(i).isInstanceOf[String])
            arr += 0.0
        }
        (row.getString(),Vectors.dense(arr.toArray))
    }.toDF("order_src","features")
   val models=LinearRegressionModel.load("hdfs://ns1/user/songchunlin/model/predictcnt_addbook_one20180202")
    val prediction =models.transform(predict)
    //    val predictions = lrModel.transform(vecDF)
    println("输出预测结果")
    val predict_result: DataFrame =prediction.selectExpr("order_src","prediction")
    val pre2=prediction.map(row=>Row(row.get().toString,row.get().toString))
    val schema = StructType(
      List(
        StructField("order_id", StringType, true),
        StructField("cnt_addbook_one", StringType, true)
      )
    )
    val scoreDataFrame = hc.createDataFrame(pre2,schema)
    scoreDataFrame.count()
    scoreDataFrame.write.mode(SaveMode.Overwrite).saveAsTable("lkl_card_score.predictcnt_addbook_one20180202")
//    predict_result.write.mode(SaveMode.Overwrite).saveAsTable("lkl_card_score.fieldValuePredictModel3_prediction20180131")
//    predict_result.foreach(println(_))
//    sc.stop()
  }
}
用模型预测未参加训练的数据,计算预测的数据和真实数据相关性为0.99553818714507836,有很大的价值。
select corr(cast(l.cnt_addbook_one as double),cast(p.cnt_addbook_one as double)) from lkl_card_score.predictcnt_addbook_one20180202 l
join lkl_card_score.fieldValuePredictModel3 p on l.order_id=p.order_src
;
spark LinearRegression 预测缺失字段的值的更多相关文章
- Oracle 判断某個字段的值是不是数字
		
转:https://my.oschina.net/bairrfhoinn/blog/207835 摘要: 壹共有三种方法,分别是使用 to_number().regexp_like() 和 trans ...
 - Mysql 修改字段默认值
		
环境:MySQL 5.7.13 问题描述:建表的时候,users_info表的role_id字段没有默认值,后期发现注册的时候,需要提供给用户一个默认角色,也就是给role_id字段一个默认值. 当前 ...
 - PHP多维数组根据其中一个字段的值排序
		
平时简单的一维数组或者简单的数组排序这里就不多作介绍,这里主要是针对平时做项目中的可能遇到的情况,根据多维数组中的其中一个排序.用到的php函数是:array_multisort. 思路:获取其中你需 ...
 - SQL Server2000导出数据时包含主键、字段默认值、描述等信息
		
时经常用SQL Server2000自带的导出数据向导将数据从一台数据库服务器导出到另一台数据库服务器: 结果数据导出了,但表的主键.字段默认值.描述等信息却未能导出,一直没想出什么方法,今天又尝试了 ...
 - 通过反射得到object[]数组的类型并且的到此类型所有的字段及字段的值
		
private string T_Account(object[] list) { StringBuilder code = new StringBuilder(); //得到数据类型 Type t ...
 - 向已写好的多行插入sql语句中添加字段和值
		
#region 添加支款方式--向已写好的多行插入sql语句中添加字段和值 public int A_ZhifuFS(int diqu) { ; string strData = @"SEL ...
 - sql如何将同个字段不同值打印在一行
		
group_concat(distinct(img)) group by id通过id分组把img的值打印在一行group_concat()通常和group by一起使用,功能是把某个字段的值打印在一 ...
 - C# SQLiteDataReader获得数据库指定字段的值
		
获得数据库指定字段的值,赋给本地变量 (1)如下,获得userinfo数据表里的字段"userid"."orgid", string userid=" ...
 - mssql查询某个值存在某个表里的哪个字段的值里面
		
第一步:创建 查询某个值存在某个表里的哪个字段的值里面 的存储过程 create proc spFind_Column_In_DB ( @type int,--类型:1为文字类型.2为数值类型 )-- ...
 
随机推荐
- Ubuntu常用安装源
			
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...
 - C# using关键字 --转
			
其实对于.NET的学习者一开始都接触using这个关键字了,可能大家没有怎么在意,包括我本人也是的,直到今天有人问我using的作用时,才引起了我的注意. 概况来说可以分为两种:第一种,就 ...
 - 【C#公共帮助类】JsonHelper 操作帮助类
			
四个主要操作类:JsonConverter .JsonHelper .JsonSplit .AjaxResult 一.JsonConverter: 自定义查询对象转换动态类.object动态类转换js ...
 - C#通过反射获取对象属性,打印所有字段属性的值
			
获取所有字段的值: public void PrintProperties(Object obj) { Type type = obj.GetType(); foreach( PropertyInfo ...
 - MAC版Eclipse的常用快捷键
			
一.Command类 Command+1 快速修复 Command+d 删除当前行 Command+Option+↓ 复制当前行到下一行 Command+Option+↑ 复制当前行到上一行 Comm ...
 - Android——Android Studio导入SlidingMenu类库的方法
			
Android Studio导入SlidingMenu类库的方法(其他类库应该也适用) 本篇文章主要介绍了"Android Studio导入SlidingMenu类库的方法(其他类库应该 ...
 - Java编程的逻辑 (53) - 剖析Collections - 算法
			
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
 - hbase源码系列(一)Balancer 负载均衡
			
看源码很久了,终于开始动手写博客了,为什么是先写负载均衡呢,因为一个室友入职新公司了,然后他们遇到这方面的问题,某些机器的硬盘使用明显比别的机器要多,每次用hadoop做完负载均衡,很快又变回来了. ...
 - HashSet与TreeSet 区别
			
HashSetHashSet有以下特点 不能保证元素的排列顺序,顺序有可能发生变化 不是同步的 集合元素可以是null,但只能放入一个null当向HashSet集合中存入一个元素时,HashSe ...
 - 自己用过的一些比较有用的css3新属性
			
css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开始慢慢的去了解并使用css3(还有html5),因为我觉得这是一种趋势,它是一种已经被制定的标准.我并不 ...