LR模型快速生成SQL脚本
LR模型快速生成SQL脚本
由于经常需要部署新LR模型,需要以SQL的方式在数仓环境中运行。
固化LR模型的形式是excel文件,所以写了一个脚本解析这个excel文件,完成模型的快速SQL化
LR模型部署模板
第一行是名称列可以不用管,第二行是线性模型基础得分
第三行开始:第一列是表中的列,第二列是表中的列的所在的区间,第三列是区间对应的分数
区间可以适配四种格式:1.{'missing'}空类型 2.[-inf,) 以最小值开始的区间 3.[,) 正常的数字区间 4.[, inf) 以最大值结束的区间
var_name | interval | score |
---|---|---|
base_score | 999 | 999 |
column_name | {'missing'} | 3 |
column_name | [-inf, 2.0) | 4 |
column_name | [2.0, 3.0) | 5 |
column_name | [3.0, 4.0) | 6 |
column_name | [4.0, inf) | 7 |
解析excel代码
依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
##正式代码
import java.io.FileInputStream
import org.apache.poi.ss.usermodel.DataFormatter
import org.apache.poi.xssf.usermodel.XSSFWorkbook
object parse_excel {
def main(args: Array[String]): Unit = {
val inputStream = new FileInputStream("bs_small.xlsx")
val model_name = "model_name"
val date = "20230419"
val workbook = new XSSFWorkbook(inputStream)
val column_case_string = new StringBuilder
val row_length = workbook.getSheetAt(0).getLastRowNum
// 选择要读取的工作表(这里选择第一个工作表)
val sheet = workbook.getSheetAt(0)
var base_score = 0
val total_score_stringBuilder = new StringBuilder
val column_string = new StringBuilder
// 遍历每一行,并读取每一列的数据
for (row <- 1 to row_length) {
val row_data = sheet.getRow(row)
val formatter = new DataFormatter()
val col_name = formatter.formatCellValue(row_data.getCell(0))
val interval = formatter.formatCellValue(row_data.getCell(1))
val score = formatter.formatCellValue(row_data.getCell(2))
val pre_col = if (row - 1 > row_length) "aaa" else formatter.formatCellValue(sheet.getRow(row - 1).getCell(0))
val next_col = if (row + 1 > row_length) "bbb" else formatter.formatCellValue(sheet.getRow(row + 1).getCell(0))
if (row == 1) {
base_score = score.toInt //拿到基础分
total_score_stringBuilder.append(base_score)
}
else {
if (interval.contains("missing")) { //判断为空的默认分数
column_string.append(col_name + ",")
column_case_string.append(" case when " + col_name + " is null then " + score + " ")
}
else if (interval.contains("[-inf")) { //小于第二个参数
if (!pre_col.eq(col_name)) { //判断当前没有miss的时候 直接一个最小值
column_string.append(col_name + ",")
val value = interval.split(",").apply(1).trim.replaceAll("\\)", "").toDouble.toInt
column_case_string.append(" case when " + col_name + " < " + value + " then " + score + " ")
} else {
val value = interval.split(",").apply(1).trim.replaceAll("\\)", "").toDouble.toInt
column_case_string.append("when " + col_name + " < " + value + " then " + score + " ")
}
}
else if (interval.contains("inf)")) { //大于等于第一个参数
val value = interval.split(",").apply(0).trim.replaceAll("\\[", "").toDouble.toInt
column_case_string.append("when " + col_name + " >= " + value + " then " + score + " ")
}
else {
val value = interval.split(",").apply(1).trim.replaceAll("\\)", "").toDouble.toInt
column_case_string.append("when " + col_name + " < " + value + " then " + score + " ")
}
}
if (row != 1 && !next_col.eq(col_name)) { //生成最终的as语句和 select 外层的base_score+列
total_score_stringBuilder.append("+")
total_score_stringBuilder.append(model_name)
total_score_stringBuilder.append("_")
total_score_stringBuilder.append(col_name)
column_case_string.append(" else 0 end as " + model_name + "_" + col_name + "," + "\r\n")
}
}
total_score_stringBuilder.append(" as ")
total_score_stringBuilder.append(model_name)
println(
s"""
select
${column_string}
${total_score_stringBuilder.toString()}
from (
select
${column_case_string.toString()}
${column_string}
'' as mm
from table where dt='${date}'
)t
""".stripMargin)
}
}
搬砖多年终不得要领,遂载源码看之望得真经。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求