最近在做金融科技建模的时候,字段里面很多缺少值得时候,模型对于新用户的预测会出现很大的不稳定,即PSI较大的情况。

虽然我们依据字段IV值得大小不断的在调整字段且开发新变量,但是很多IV值很大的字段直接用平均值、或者0代替显然不够合理。

所以,我们在尝试把字段缺失值当作需要预测的值,把该字段不缺失的当作y,用其他字段当作X,去预测该字段缺失值得值。不同于机器学习的回归和分类预测。

这里的预测结果是一个具体的值,它的范围从负无穷到正无穷都有可能。

  数据直接读存于Hive,代码如下:

  1. import org.apache.spark.sql.{DataFrame, Row, SQLContext, SaveMode}
  2. import org.apache.spark.{SparkConf, SparkContext}
  3. import org.apache.spark.mllib.linalg.{Vector, Vectors}
  4. import org.apache.spark.ml.regression.LinearRegression
  5. import org.apache.spark.mllib.regression.LabeledPoint
  6. import org.apache.spark.ml.regression.LinearRegressionModel
  7. import org.apache.spark.sql.hive.HiveContext
  8. import org.apache.spark.sql.types.{DoubleType, StringType, StructField, StructType}
  9. import scala.collection.mutable.ArrayBuffer
  10. // 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
  11. //l on p.order_id=l.order_src where l.cnt_addbook_one<>0
  12. //
  13. object predictcnt_addbook_one20180201 {
  14. def main(args: Array[String]): Unit = {
  15. val cf = new SparkConf().setAppName("ass").setMaster("local")
  16. val sc = new SparkContext(cf)
  17. val sqlContext = new SQLContext(sc)
  18. val hc = new HiveContext(sc)
  19. import sqlContext.implicits._
  20.  
  21. val data = hc.sql(s"select * from lkl_card_score.fieldValuePredictModel3 where cnt_addbook_one<>0 and cnt_addbook_one%2=1").map {
  22. row =>
  23. val arr = new ArrayBuffer[Double]()
  24. //剔除label、phone字段
  25. for (i <- until row.size) {
  26. if (row.isNullAt(i)) {
  27. arr += 0.0
  28. }
  29. else if (row.get(i).isInstanceOf[Int])
  30. arr += row.getInt(i).toDouble
  31. else if (row.get(i).isInstanceOf[Double])
  32. arr += row.getDouble(i)
  33. else if (row.get(i).isInstanceOf[Long])
  34. arr += row.getLong(i).toDouble
  35. else if (row.get(i).isInstanceOf[String])
  36. arr += 0.0
  37. }
  38. LabeledPoint(row.getLong().toDouble,Vectors.dense(arr.toArray))
  39. }.toDF("Murder","features")
  40.  
  41. // 建立模型,预测谋杀率Murder
  42. // 设置线性回归参数
  43.  
  44. val lr1 = new LinearRegression()
  45. val lr2 = lr1.setFeaturesCol("features").setLabelCol("Murder").setFitIntercept(true)
  46. // RegParam:正则化
  47. val lr3 = lr2.setMaxIter().setRegParam(0.3).setElasticNetParam(0.8)
  48. // 将训练集合代入模型进行训练
  49.  
  50. val lr = lr3
  51. val lrModel = lr.fit(data)
  52. // 输出模型全部参数
  53. lrModel.extractParamMap()
  54. println(s"Coefficients: ${lrModel.coefficients} Intercept: ${lrModel.intercept}")
  55. lrModel.write.overwrite().save(s"hdfs://ns1/user/songchunlin/model/predictcnt_addbook_one20180202")
  56. // 模型进行评价
  57. val trainingSummary = lrModel.summary
  58. println(s"numIterations: ${trainingSummary.totalIterations}")
  59. println(s"objectiveHistory: ${trainingSummary.objectiveHistory.toList}")
  60. trainingSummary.residuals.show()
  61. println(s"RMSE: ${trainingSummary.rootMeanSquaredError}")
  62. println(s"r2: ${trainingSummary.r2}")
  63. val predict = hc.sql(s"select * from lkl_card_score.fieldValuePredictModel3 where cnt_addbook_one<>0 and cnt_addbook_one%2=0").map {
  64. row =>
  65. val arr = new ArrayBuffer[Double]()
  66. //剔除label、phone字段
  67. for (i <- until row.size) {
  68. if (row.isNullAt(i)) {
  69. arr += 0.0
  70. }
  71. else if (row.get(i).isInstanceOf[Int])
  72. arr += row.getInt(i).toDouble
  73. else if (row.get(i).isInstanceOf[Double])
  74. arr += row.getDouble(i)
  75. else if (row.get(i).isInstanceOf[Long])
  76. arr += row.getLong(i).toDouble
  77. else if (row.get(i).isInstanceOf[String])
  78. arr += 0.0
  79. }
  80. (row.getString(),Vectors.dense(arr.toArray))
  81. }.toDF("order_src","features")
  82.  
  83. val models=LinearRegressionModel.load("hdfs://ns1/user/songchunlin/model/predictcnt_addbook_one20180202")
  84. val prediction =models.transform(predict)
  85.  
  86. // val predictions = lrModel.transform(vecDF)
  87. println("输出预测结果")
  88. val predict_result: DataFrame =prediction.selectExpr("order_src","prediction")
  89. val pre2=prediction.map(row=>Row(row.get().toString,row.get().toString))
  90. val schema = StructType(
  91. List(
  92. StructField("order_id", StringType, true),
  93. StructField("cnt_addbook_one", StringType, true)
  94. )
  95. )
  96. val scoreDataFrame = hc.createDataFrame(pre2,schema)
  97. scoreDataFrame.count()
  98. scoreDataFrame.write.mode(SaveMode.Overwrite).saveAsTable("lkl_card_score.predictcnt_addbook_one20180202")
  99.  
  100. // predict_result.write.mode(SaveMode.Overwrite).saveAsTable("lkl_card_score.fieldValuePredictModel3_prediction20180131")
  101. // predict_result.foreach(println(_))
  102. // sc.stop()
  103.  
  104. }
  105. }

用模型预测未参加训练的数据,计算预测的数据和真实数据相关性为0.99553818714507836,有很大的价值。

  1. select corr(cast(l.cnt_addbook_one as double),cast(p.cnt_addbook_one as double)) from lkl_card_score.predictcnt_addbook_one20180202 l
  2. join lkl_card_score.fieldValuePredictModel3 p on l.order_id=p.order_src
  3. ;

 

spark LinearRegression 预测缺失字段的值的更多相关文章

  1. Oracle 判断某個字段的值是不是数字

    转:https://my.oschina.net/bairrfhoinn/blog/207835 摘要: 壹共有三种方法,分别是使用 to_number().regexp_like() 和 trans ...

  2. Mysql 修改字段默认值

    环境:MySQL 5.7.13 问题描述:建表的时候,users_info表的role_id字段没有默认值,后期发现注册的时候,需要提供给用户一个默认角色,也就是给role_id字段一个默认值. 当前 ...

  3. PHP多维数组根据其中一个字段的值排序

    平时简单的一维数组或者简单的数组排序这里就不多作介绍,这里主要是针对平时做项目中的可能遇到的情况,根据多维数组中的其中一个排序.用到的php函数是:array_multisort. 思路:获取其中你需 ...

  4. SQL Server2000导出数据时包含主键、字段默认值、描述等信息

    时经常用SQL Server2000自带的导出数据向导将数据从一台数据库服务器导出到另一台数据库服务器: 结果数据导出了,但表的主键.字段默认值.描述等信息却未能导出,一直没想出什么方法,今天又尝试了 ...

  5. 通过反射得到object[]数组的类型并且的到此类型所有的字段及字段的值

    private string T_Account(object[] list) { StringBuilder code = new StringBuilder(); //得到数据类型 Type t ...

  6. 向已写好的多行插入sql语句中添加字段和值

    #region 添加支款方式--向已写好的多行插入sql语句中添加字段和值 public int A_ZhifuFS(int diqu) { ; string strData = @"SEL ...

  7. sql如何将同个字段不同值打印在一行

    group_concat(distinct(img)) group by id通过id分组把img的值打印在一行group_concat()通常和group by一起使用,功能是把某个字段的值打印在一 ...

  8. C# SQLiteDataReader获得数据库指定字段的值

    获得数据库指定字段的值,赋给本地变量 (1)如下,获得userinfo数据表里的字段"userid"."orgid", string userid=" ...

  9. mssql查询某个值存在某个表里的哪个字段的值里面

    第一步:创建 查询某个值存在某个表里的哪个字段的值里面 的存储过程 create proc spFind_Column_In_DB ( @type int,--类型:1为文字类型.2为数值类型 )-- ...

随机推荐

  1. 简洁的python测试框架——Croner

    [本文出自天外归云的博客园] Croner简介 这是一个非常简洁的测试框架,是基于python3的nose进行二次开发的. Github地址 可以随意的在此基础上进行扩展以支持jenkins等其他扩展 ...

  2. linux下保护视力、定时强制锁定软件: Workrave

    超负荷地工作会累坏身体的,而且效率也不高,所以工作一段时间就应该休息一下.长时间在电脑前一动不动,很容易患上“重复性劳损”,即 Repetitive Strain Injury (RSI).具体现象大 ...

  3. spring batch初识

    Spring Batch是什么?  Spring Batch是一个基于Spring的企业级批处理框架,按照我师父的说法,所有基于Spring的框架都是使用了spring的IoC特性,然后加上自己的一些 ...

  4. php 裁剪图片类

    <?php /* *说明:函数功能是把一个图像裁剪为任意大小的图像,图像不变形 * 参数说明:输入 需要处理图片的 文件名,生成新图片的保存文件名,生成新图片的宽,生成新图片的高 * writt ...

  5. 深入理解IoC和DI

    本文章转载自: https://segmentfault.com/a/1190000005602011 最近在研究php的lumen框架和phalcon框架,这两个框架的底层架构都用到了IoC,DI, ...

  6. SpringMVC @SessionAttributes 使用详解以及源码分析

    @sessionattributes @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Docum ...

  7. mosquitto简单应用

    1. 简述 一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机 ...

  8. knockout.js模板绑定之利用Underscore.js模板引擎示例

    View代码 <h1>People</h1> <ul data-bind="template: { name: 'peopleList' }"> ...

  9. 放弃winform的窗体吧,改用html作界面,桌面应用程序UI的新的开发方式。

    做过很多winform项目,都为winform控件头疼不已.想实现一些漂亮的样子总是很难.我这里列举几个缺点: 1.winform控件大多是 绝对布局 ,你需要给出准确的坐标.那么在实现居中效果就会很 ...

  10. HashTable和HashMap的区别详解

    一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的, ...