作者简介
潘鹏举,携程酒店研发 BI 经理,负责酒店服务相关的业务建模工作,主要研究方向是用机器学习实现业务流程自动化、系统智能化、效率最优化,专注于算法实践和应用。
我们经常会碰到一个问题:用了复杂的GBDT或者xgboost大大提升了模型效果,可是在上线的时候又犯难了,工程师说这个模型太复杂了,我没法上线,满足不了工程的要求,你帮我转换成LR吧,直接套用一个公式就好了,速度飞速,肯定满足工程要求。这个时候你又屁颠屁颠用回了LR,重新训练了一下模型,心里默骂千百遍:工程能力真弱。
这些疑问,我们以前碰到过,通过不断的摸索,试验出了不同的复杂机器学习的上线方法,来满足不同场景的需求。在这里把实践经验整理分享,希望对大家有所帮助。(我们的实践经验更多是倾向于业务模型的上线流程,广告和推荐级别的部署请自行绕道)。
首先在训练模型的工具上,一般三个模型训练工具,Spark、R、Python。这三种工具各有千秋,以后有时间,我写一下三种工具的使用心得。针对不同的模型使用场景,为了满足不同的线上应用的要求,会用不同的上线方法:
一、总结来说,大体分这三种场景,请大家对号入座,酌情使用。
以上三种做法,都会用SOA里面进行数据处理和变换,只有部分变换会在提供的Function或者类进行处理,一般性都建议在SOA里面处理好,否则性能会变慢。 大概场景罗列完毕,简要介绍一下各不同工具的线上应用的实现方式;
二、如何转换PMML,并封装PMML
大部分模型都可以用PMML的方式实现,PMML的使用方法调用范例见:
三、各个算法工具的工程实践:
这里我介绍另一种的上线方式:Rserve。
具体实现方式是:用SOA调用Rserve的方式去实现,我们会在服务器上部署好R环境和安装好Rserve,然后用JAVA写好SOA接口,调用Rserve来进行预测;
Rserve方式可以批量预测,跟PMML的单个预测方式相比,在少数据量的时候,PMML速度更快,但是如果是1000一次一批的效率上看,Rserve的方式会更快; 用Rserve上线的文件只需要提供两个: - 模型结果文件(XX.Rdata) - 预测函数(Pred.R);
Rserve_1启动把模型结果(XX.Rdata)常驻内存。预测需要的输入Feature都在Java里定义好不同的变量,然后你用Java访问Rserve_1,调用Pred.R进行预测,获取返回的List应用在线上。最后把相关的输入输出存成log进行数据核对。
Pred.R <- function(x1,x2,x3){
data <- cbind(x1,x2,x3)
# feature engineering
score <- predict(modelname, data, type = 'prob')
return(list(score))
}
Spark模型的上线就相对简单一些,我们用scala训练好模型(一般性都用xgboost训练模型)然后写一个Java Class,直接在JAVA中先获取数据,数据处理,把处理好的数据存成一个数组,然后调用模型Class进行预测。模型文件也会提前load在内存里面,存在一个进程里面,然后我们去调用这个进程来进行预测。所以速度蛮快的。
四、只用Linux的Shell来调度模型的实现方法-简单粗暴;
因为有些算法工程师想快速迭代,把模型模拟线上线看一下效果,所以针对离线预测的模型形式,还有一种最简单粗暴的方法,这种方法开发快速方便,具体做法如下:
predict.sh的写法如下:
# 数据导出
data_filename = xxx
file_date = xxx
result = xxx
updatedt = xxx
cd path
hive -e "USE tmp_xxxdb;SELECT * FROM db.table1;" > ${data_filname};
# R脚本预测
Rscript path/predict.R $file_date
if [ $? -ne 0 ]
then
echo "Running RScript Failure"
fi
# R预测的结果导入Hive表
list1="use tmp_htlbidb;
load data local inpath 'path/$result'
overwrite into table table2 partition(dt='${updatedt}');"
hive -e "$list1"
3. 最后用Crontab来进行调度,很简单,如何设置crontab,度娘一下就好了:
>crontab -e
-------------------------
### 每天5点进行预测模型;
0 5 * * * sh predict.sh
五、说完了部署上线,说一下模型数据流转的注意事项: