策略类服务的设计实践

来源:互联网 发布:遗传算法与svm 编辑:程序博客网 时间:2024/06/08 09:13

一、        引言

       先前基本在做功能业务性产品服务的研发,近期有机会主导设计研发多个策略模型类服务,切身的体会到策略类服务相对于常规功能性产品服务在架构设计上存在较多不同之处。本文会针对这些不同之处,介绍我自己针对策略模型类服务的设计实践。

概念:

       功能业务性产品:根据自身产品定位,给用户提供各类相关实用的功能,这类功能操作结果是确定的。典型的例如微信中聊天功能:给A发了消息,A的微信的聊天框就会出现该消息;支付宝的转账: 给A转账100元,A的账户中就会多出100元。

       策略模型类产品:根据用户特性、场景、服务后台数据不同,给出结果会存在不同。 不同用户使用同一服务,得到结果可能会不同;同一用户使用同一类性不同服务,得到结果也可能不同。例如搜索和广告推荐。

 

二、        策略类和业务类的服务的区别

1、 开发流程存在差异,策略模型类产品实验性特别强,需要设计各类小流量实验评估

由于策略类服务的输出结果具备不确定性,同一种功能使用不同策略和模型,结果都会存在差异。往往策略设计者无法预知该策略是否正向有效,所以需要事先设计小流量实验,通过A/B测试等方法进行评估,对照确认新策略是否正向。而纯功能性产品,产品经理在前期的用户反馈、用户调研中,可能就已经充分确定该功能是用户所需要的,重要是做好交互设计以及在上线后进行交互等细节优化。

2、 策略模型类产品对数据依赖强,数据驱动性强

简单的策略可以是基于特征参数的规则系统,复杂一些策略会依赖于机器学习模型的预测结果。这些都会依赖较多数据进行策略制定,特别是机器学习模型是基于大数据训练,在模型的训练以及模型更新中都依赖离线数据流。而常规的业务类程序,很少依赖于离线数据流,更多是基于数据库等在线数据存储即可。

 

三、        策略类服务的设计实践

针对以上策略类程序和业务类程序之间区别,整理出策略类程序特有的4个设计要点

1、 多策略支持

由于一个新策略的上线,策略设计者在上线前,策略设计者无法知道策略是否正向。他必须要通过小流量的方式进行实验评估,通过A/B测试等评估方式,通过数据指标证明新策略相对老策略更好。为了更快地找到好的策略,更快地迭代,经常需要有多个策略同时在线上进行小流量实验。一个不好策略,一但验证不正向,相应地策略代码就会废弃,代码的失效速度也比业务类程序代码变动速度快,所以也要考虑策略代码可维护性。

同时很多相似的策略,可能只是少量细节不同,在业务层也有很多类似逻辑。

针对以上特点

1) 应用设计模式中策略模式

设计一个策略接口,来定义策略行为;

通过抽闲策略类封装同一类主策略的各类通用方法,同时在抽象类中可以将策略接口方法通过模板模式实现,封装所有策略处理中的相同流程(如输入通用的预处理、通用策略公式计算逻辑、日志输出等),留出少量个性化的待实现方法。

          具体的策略则继承抽象策略类,添加个性的策略逻辑或参数即可。

策略设计模式可参考:http://blog.csdn.net/hguisu/article/details/7558249/。

2) 应用工厂模式来创建策略

在具体获取策略时,通过统一的工厂方法,用策略名参数来创建各类策略,统一和简化策略的创建代码。

3) 流量分配层

流量分配根据特定实验方案需要,有很多种不同的做法。例如按照用户id、各类用户属性()用户所在区域、用户的教育程度等)进行筛选后分组,也有按照流量发生的时间段进行划分等,在划分的过程中,对筛选出的流量,也会按照一定原则(通常通过一定随机算法)分成实验组和对照组。

流量分配层,统一承担所有策略实验的流量分组分配的功能。抽象出策略选择器接口、策略选择器工厂两个概念,策略选择器接口输入是流量接入层组织所有流量分配所需的参数集合,返回是该请求对应的具体策略。常规维护一个策略选择器即可,如果在研发过程出现特别大的流量分配的方案调整,可以新建新的策略选择器,通过策略策略选择器工厂进行切换。

通过以上的流量分配层以及策略设计模式,我们能灵活高效地实现线上的多策略实验并行。

2、多模型支持

   模型升级时,为对比模型升级或不同算法的效果,也需要线上支持多模型在线。类似于多策略支持,可以通过策略模式、工厂模式来设计模型接口以及模型创建工厂,在流量适配层,确定流量分配以及模型版本,在具体策略中通过模型版本号来获取具体的模型。

3、 数据正确性保障

策略类强依赖数据,如果数据出现问题,策略效果就可能出现很大问题,甚至是负向效果,所以策略程序设计必须要多考虑如何保障数据的正确性,在数据出现问题能及时监控到。策略类依赖的数据流分为两类:离线数据流和在线数据流。

1) 离线数据流

机器学习模型的训练依赖于特征数据,对于需要持续更新的模型,测试好特征程序会持续调度,产生最新的特征数据。最新离线特征数据可能因为上游数据源或数据传输等原因,会出现各种各样的新问题。离线特征处理调度程序中需要设计比较完备的数据校验逻辑,保证如果最新特征数据出现问题,能及时发现。这一块设计可以参考另一篇博文《基于spark的大数据提取校验框架》

2) 在线数据流

在线数据包括从请求端带过来的参数以及从离线导入到线上的特征等数据。

请求参数可根据业务知识添加各类缺失、异常值等判断。

离线导入到线上的特征,由于存在一个从导入导入再在线获取的过程,过程中可能会出现数据丢失或导入错误等问题。因此,我在离线数据生成时,对离线特征集生成一个MD5的签名一起导入,在读取到特征数据后,基于读取到数据进行签名,和离线的MD5签名值做对比校验,这样可以及时发现特征从离线导入到在线过程中出现的问题。

4、 模型测试

模型测试包括线上服务和离线特征处理部分逻辑一致性测试、模型离线预测效果和线上实际预测效果的一致性测试。

1)线上服务和离线特征处理部分逻辑一致性测试

由于离线模型的训练代码和线上的模型预测代码是不同的,线上和离线获取特征的来源不同,但是又要求特征处理逻辑一致。这一块有两个方式来处理:一方面尽量将让在线和离线复用同一套特征处理代码,代码复用性越高,逻辑一致性出问题可能性也越低,同样后续维护的风险也小。另一方面,设计数据驱动方式进行批量自动化测试,在离线模型训练代码中,设计在交付时能生成一大批原始数据以及离线模型的预测结果,在线部分将这些离线特征环境灌入到测试数据环境中,同时在线程序设计一个测试模式,支持在接受到测试请求后,将模型预测结果放入到请求返回中。这样测试程序载入离线的原始请求数据以及离线预测结果,对服务发起请求,比对在线中的模型预测结果和离线预测结果即可快速基于数据驱动方式进行自动化模型测试,大大提高模型升级等测试效率。

2)模型离线预测效果和线上实际预测效果的一致性测试

离线效果好模型,在应用到线上后,可能会效果不好。 除了模型泛化能力这个模型通用的问题,还可能是因为线上模型和离线模型的数据来源差异导致。线上模型的特征数据有部分是通过请求,而离线的特征数据来源是日志,这两部分可能因为线上bug等各种原因存在差异。 所以在模型正式上线,建议尽量设计空跑的机制,引入流量预测,但不影响业务策略,业务策略依然用之前方式处理。这样积累了一段时间线上特征日志以及预测结果后,结合线上的真实标注,评估线上空跑的模型准确性是否和离线的准确性一致。

 

四、              总结

       以上为我通过实际策略类项目总结的策略类程序设计一些具体实践思路,后续我整理下代码样例,供大家实际参考或复用。此外,由于策略的效果存在很大的不确定性,往往需要通过很多很多轮的迭代才能实验出好的策略,因此,架构设计师除了通过工程的手段加速策略实验的迭代周期、保障数据流的稳定性、提升策略升级和测试效率以外,也要多参与到策略设计和优化工作中。毕竟决定策略类程序最终的效果的核心因素是一个好的策略,而好策略和差策略有时候有可能只有一些细节上差异,任何参与项目人员在这些策略细节上都能有较大发挥的空间。

     整理了体现以上设计思路的样例项目放在github上,仓库地址:https://github.com/neowgz/strategy-service-sample  链接

 

 

       

0 0
原创粉丝点击