查看原文
其他

干货 | 一个数据分析师眼中的数据预测与监控

束开亮 携程技术中心 2019-05-02

作者简介

 

束开亮,携程大市场部BI团队,负责数据分析与挖掘。同济应用数学硕士,金融数学方向,法国统计学工程师,主修风险管理与金融工程。


前言


商业智能(BI)是企业级大数据分析必不可少的组成部分,除了传统的ETL,数据仓库,可视化报表等应用和展示层技术,如今的BI更是依托大数据工具兼顾且发展了数据的策略和算法层,比如利用R和Python做数据分析和数据挖掘,基于Spark开发算法程序等。


数据科学家和算法工程师的日常工作,如动态监控与预测,搜索排序,推荐系统等位于数据分析金字塔的中上层,其研究结果对商业决策的影响则处于金字塔的顶端。


数据质量决定了算法模型效果的上限,而数据分析的方式和模型的搭建策略则又决定了成果优劣以及其被决策层采纳的可能性大小。


本文将以一个普通数据分析师的视角,阐述BI日常工作中的数据分析方法以及在统计模型搭建过程中的注意事项。鉴于篇幅限制,内容只涉及一些简单的统计模型,如预测和数据监控。


预测与监控


一.非时序预测


在机器学习和深度学习大行其道的当下,一个好的预测模型不在于应用了多么高深的算法,而在于如何从简单的模型开始进行尝试,兼顾业务逻辑,基于某个baseline来控制时间和应用成本。


对于非时序数据或是无明显趋势、季节特征的时序数据,回归和树模型是目前主流的预测方法。


广义线性回归,如线性最小二乘和logistic回归,因其模型的可解释性,从诞生之日至如今依旧发挥着其不可替代的作用,如金融风控中评分卡的开发,医学中对患者生存期限的研究等。


为了处理非线性问题,依托着分布式计算,又孕育出树模型和基于树的boosting模型,如Decision Tree和Xgboost,以及后续的LightGBM和CatBoost等。


考虑到线性回归和logistic回归在处理非线性问题上的短板,以及为了适配模型需对数据做大量的预处理,如填补缺失,防止共线性等,我们自然偏向于树模型来做分类和回归预测,Xgboost便是一个很好的选择。R和Python都提供了xgboost的接口,Python不仅拥有xgb的原生接口,更有适配sklearn的接口,便利了参数的网格搜索。


对于预测任务,我们的应用场景主要分成两类:


  • 离线(T+1)预测,主要针对小批量数据,通过shell脚本调用R或Python的服务器,返回结果。


  • 实时预测,由于线上预测需要实时响应,如在毫秒级内返回模型预测值,跨平台跑模型并不能满足要求。这就需要将模型文件打包成PMML文件供Java调用,响应速度极快。


作为一名数据科学家,不仅要保证数据处理的效率和质量,也要关注模型本身的应用规范。


比如应用Xgboost时,是否对分类变量做了正确的编码。首先,xgb分类器只接受数值型变量,任何的字符型变量都需转换成数值型。


其次,分类器默认数据是连续且是有序的,2一定比1大。 但无序分类变量的特征值之间是没有可比性地,比如变量“城市分类”,其特征值分为:一线城市,新一线城市,二线城市,其他城市。如果将其编码成(1,2,3,4),分类器便会误解为二线城市大于新一线城市,事实上特征值代表的仅是一个类别,不可相互比较。


可行的处理方式是对此类变量采取独热(one-hot)编码,每个特征值都作为一个新的衍生变量,每个衍生变量都是一个二元(0/1)互斥特征,这种编码方式充分考虑了分类变量每个特征值的独特性。当然,如果特征值过多,特征矩阵也会过于稀疏,此时可基于业务逻辑和数据分布对特征值进行分组处理。


模型调参,一个重复却又不可缺的步骤。可能有人觉得调参带来的提升并不明显,不值得费时费力。但这却是数据科学家严谨态度的体现,作者认为调参的目的不仅在于获得模型提升,更在于通过多次实验,基于概率确保模型参数的稳健性。


在实时预测模型中,打包的PMML文件不仅要包含模型文件,还要包含数据的预处理过程,这就需要借助管道(Pipe)将原始数据的处理过程(如编码,标准化,正则化等)和分类器的训练过程串联,再将管道本身打包成PMML文件。


恼人的是,管道一体化的过程限制了特征工程中的个性化发挥,接口提供了一些简单的数据转换函数和自定义函数功能,但这远远不够。此外,网格搜索过程中参数的赋值方式也略有改变。最后,特征重要性的可视化也并不友好,原因在于管道中的数据预处理掩盖了原有的特征名称。(读者如有个人见解,欢迎交流)。


管道中的网格搜索还需注意:假设通过sklearn接口预先定义了分类器,后利用管道包装了数据预处理过程和分类器,那么在网格搜索时,参数赋值相比传统方式将有所改变。


定义分类器:

                           

定义管道:


普通的网格搜索方式:


Pipe中的搜索方式:


Python的help文档中指出了Pipe中的参数赋值采取二级结构:(分类器__参数:值),而非传统方式:(参数:值)。

 

二、时序监控与预测


时序监控,主要还是针对各业务指标的异常值检测以及模型上线后的稳定性检测。


业务指标的异常检测多是单变量的检测,而提及单变量异常检测,首先想到的便是3 sigma原则。和线性回归中的极大似然估计类似,3 sigma准则的应用前提需假设原始数据满足或近似满足正态分布,而实际数据往往具体一定的偏态性。作为数据科学家,切莫不假思索的去应用惯用的准则,而应从数据的分布出发找到合适的途径来分析数据,比如对偏态的数据采用Box-Cox转换。


其次,业务指标的监控是个双重任务,一是要及时发现数据中的异常,二是要对未来一天或是一段时间进行预测。如果能找到一个统计模型同时处理这二重任务,问题会显得简单多,可一个特定的模型往往很难适应多个场景。


以某个业务指标为例,下图展示了指标近几年的走势,天的时序图有非常明显的季节效应和增长趋势,同时也可观察到一些节假日对业务指标的影响。



STL时间序列分解法可针对此类数据做异常检测和时间序列预测。模型的核心由里外双重循环构成,内循环主要利用局部加权回归对季节效应和趋势做平滑处理,外循环将根据内循环的拟合效果重新调节观测值的权重,观测值偏离大的点权重低。


举例说明,在内循环中,预测点处的函数值:取某一邻域(窗口)内所有点(支持缺失值处理)进行加权回归,假设邻近权重函数如下(仅为假设,非STL中的邻近权重设置):




上图可以看出参与回归的点x离越近,权重越高,自身的权重为1。


内循环的局部加权回归属于非参数模型,可用来解决非线性问题,但是当数据量较大时,算法则需要更多的存储来重新计算各观测点的权重。


STL中经过一轮内循环,得到趋势和季节项,那么每个点的余项可由观测值减去趋势和季节项得到。余项反应了观测点的稳定性,外循环将根据余项大小重新赋予各观测点一个稳健权重p(x)。新一轮的内循环将以w(x)×p(x)  作为新的权重参与趋势和季节效应的平滑处理,而p(x)threshold则成为我们判断观测是否异常的准则,threshold可由自己给定,权重p(x)较小的观测被判定为异常。


下图是原始数据和STL模型中分解出的季节项,趋势项,和余项序列,红色×符号标记了数据中的异常值。


可以发现趋势项单调且具一定的线性性。按照此模式去预测,T+1天的预测值不会有太大偏差,但T+h天的预测值必会受到趋势项的作用,偏离正常范围而显得过高。此外,模型也未考虑到节假日因素的影响。


如果专注于预测的高精度,Prophet模型是一个不错的选择。模型通过Fourier转换可分解多周期序列,且在趋势处理上也有了新的创新,比如考虑环境和系统的承载力,提出阻滞增长和分段线性增长的想法。


阻滞增长模式:此模式中的趋势(增长)函数如下



其中,参数C是环境或系统的最大承载。函数g(x)一阶导数大于零,二阶导数在(xm)上大于零,所以g(x)的增长速度会逐渐放缓趋于饱和状态。取C=1,k=1,=2 增长趋势如下:



分段线性模式:不同时间段的增长速率不同,此模式中的趋势(增长)函数如下



其中,k是线性增长率,m是漂移项,向量δ的每个分量对应了不同时段的调节增长率,向量Y的每个分量对应了不同时段的调节漂移,示性函数向量a(t)指示了当前时刻是否属于某个时间分段。分段增长的模式也可和阻滞增长模式相结合产生更为复杂的增长模式。


在节假日问题的处理上,Prophet假设各节假日影响相互独立,且根据历史节假日的影响归纳出一个先验分布,如。那么时间序列中节假日的影响函数可表示为:



考虑n个节假日,k就是一个n维向量,每个分量满足相同的正态分布,示性函数向量Z(t)指示了当前时刻t是否属于某个节假日。


笔者认为节假日影响的先验分布假设过于理想化,同方差意味着各节假日的影响强度是相同的,而实际上不同的节假日对业务指标的影响是有很大区别的,比如春节假期对火车票购买量的促进程度会远大于小长假。当然,也可尝试修改先验分布,但试错的方式也会带来工作成本增加和时间的消耗。


针对此问题,有人在时间序列中引入协变量来辅助预测,比如一个时间序列模型加上一个树模型。虽然这种方法没有太多的理论支持,但是实际应用中却十分有效,时间序列模型抓住了树模型很难解释的季节和趋势因素,而树模型又补充非线性的其他因素,二者的结合不失为一个很好的创意。一般时间序列模型的分解式:



g(t)为趋势,s(t)为季节,ε(t)为噪声。考虑节假日因素的序列分解式:



h(t)为节假日影响函数,如Prophet模型中h(t)的设置。利用树模型如xgb解释节假日影响因素的序列分解式:



为t时刻的特征向量,特征工程中往往会对节假日做日期对齐处理以及通过日期变量衍生出其他子特征。建模时先通过时间序列模型拟合趋势和季节项,得到的余项再用xgb来拟合。


结束语


数据分析与挖掘离不开统计知识和算法设计,不同场景下的问题解决方案各有不同。数据分析师不仅要有良好的知识素养,也要深谙业务背景,更缺不了工程师团队的付出。


文章仅涉及作者工作中的轻任务,以及自身的一点思考,鉴于学识和经验的局限,文中措辞如有疏忽,恳请指出。同时也欢迎读者一起交流,分享自己在日常工作中遇到的难题和解决思路。

 

参考文献:


[1].Taylor S J, Letham B.Forecasting at Scale[J]. 2017.

[2].Livera A M D, Hyndman R J,Snyder R D. Forecasting Time Series With Complex Seasonal Patterns UsingExponential Smoothing[J]. Monash Econometrics & Business Statistics WorkingPapers, 2011, 106(496):1513-1527.

[3].Chen T, Guestrin C. XGBoost:AScalable Tree Boosting System[C]// ACM SIGKDD International Conference on KnowledgeDiscovery and Data Mining. ACM, 2016:785-794.

[4].Cleveland R B. STL : ASeasonal-Trend Decomposition Procedure Based on Loess[J]. Journal of OfficialStatistics, 1990, 6(1):3-33.


【推荐阅读】




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存