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为数值类型 )-- ...
随机推荐
- 在Jenkins上做一个定时闹钟
[本文出自天外归云的博客园] 利用Jenkins定时任务来做一个闹钟,每天隔一段时间提醒自己一下“你该休息了!别老坐着!出去走一走!珍爱生命,远离久坐!” 首先在Jenkins上创建一个node. 创 ...
- java判断是移动端还是pc端
// \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔), // 字符串在编译时会被转码一次,所以是 "\\b" // \B 是单词内部逻辑间隔(连着的 ...
- swift,NSUserDefaults的swift化封装
NSUserDefaultshtml, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror- ...
- 越狱机器SSH安装与使用
SSH安装html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scroll { ...
- 使用Task代替ThreadPool和Thread
转载:改善C#程序的建议9:使用Task代替ThreadPool和Thread 一:Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的 ...
- 使用livereload实现自动刷新
livereload是一个web开发辅助工具,当我们修改完html.css和js的时候会自动刷新浏览器,解放码农的双手.这样在双屏切图.写js代码的时候会提高很多效率.livereload有很多版本, ...
- Linux系统上传下载命令rz和sz
Linux系统简单易用的上传下载命令rz和sz (2017年7月10日更新) 发布地址(http://oldboy.blog.51cto.com/2561410/588592) (一)安装方法汇总 1 ...
- Android学习记录一——安装环境
一直想接触这块,但是却一直耽搁到现在.找过几回资料,找过几回安装包,这两天受了些刺(gong)激(zi),决定静下心来,一点点开始吃. 接触c#都是从门外汉开始,谈不上任何编程基础,所以接触andro ...
- strtok的基本使用方法
理论知识自己能够百度这里直接上代码 代码的内容是 HDU(杭电)-1106-排序 排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 655 ...
- 在android中配置 slf4j + log4j 日志记录框架
需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j ...