I.评分卡介绍
之前介绍了决策引擎的规则集、决策流,以及决策树、决策表、决策矩阵等功能实现,文章参考:
信用评分模型是一个量化工具,利用可观察到的借款人特征变量计算出一个数值(得分)来代表债务人的信用风险,并将借款人归类于不同的等级风险。
Wikipedia
贷前:A卡(Application score card 申请评分卡),用于筛选准入,申请授信。
贷中:B卡(Behavior score card 行为评分卡),用于风险预警,额度升降。
贷后:C卡(Collection score card 催收评分卡),用于贷后管理,催收策略。

scorecards:scorecard:name: scorecard_1#rule partrules:rule:rule_name: "amout_1"rule_group: "amout_group"conditions:condition:feature: amoutoperator: LEvalue: 5000logic:decision: 5rule:rule_name: "amout_2"rule_group: "amout_group"conditions:condition:feature: amoutoperator: GTvalue: 5000condition:feature: amoutoperator: LTvalue: 10000logic: ANDdecision: -3rule:rule_name: "amout_3"rule_group: "amout_group"conditions:condition:feature: amoutoperator: GEvalue: 10000logic:decision: -6rule:rule_name: "sex_1"rule_group: "sex_group"conditions:condition:feature: sexoperator: EQvalue: Mlogic:decision: 10rule:rule_name: "sex_2"rule_group: "sex_group"conditions:condition:feature: sexoperator: EQvalue: Flogic:decision: 5#decision expression partdecision:logic: SUMoutput: ((score))
type ScoreCard struct {Name string `yaml:"name"`Depends string `yaml:"depends"`Rules []Rule `yaml:"rules,flow"`Decision Decision `yaml:"decision"`}
func (sc *ScoreCard) parse() float64 {log.Printf("scorecard %s parse ...\n", sc.Name)var result = make([]string, 0)for _, rule := range sc.Rules {if rule.parse() {result = append(result, rule.Decision)}}return parseScoreCard(result, sc.Decision.Logic, sc.Decision.Output)}
func parseScoreCard(scores []string, logic string, output string) float64 {var score float64switch logic {case configs.Sum:scoreStr, _ := operator.Math(strings.Join(scores, "+"))score = scoreStr.(float64)}expr := strings.Replace(output, configs.ScoreReplace, strconv.FormatFloat(score, 'f', -1, 64), -1)result, _ := operator.Math(expr)return result.(float64)}
func TestScoreCard(t *testing.T) {internal.SetFeature("amout", 7999)internal.SetFeature("sex", "F")dsl := dslparser.LoadDslFromFile("scorecard.yaml")rs := dsl.ParseScoreCard(dsl.ScoreCards[0])if rs == "2" {t.Log("result is ", rs)} else {t.Error("result error,expert 2, result is ", rs)}}

func (sc *ScoreCard) parse() float64 {log.Printf("scorecard %s parse ...\n", sc.Name)var result = make(map[string]string, 0)for _, rule := range sc.Rules {if _, exists := result[rule.RuleGroup]; !exists {if rule.parse() { //hitresult[rule.RuleGroup] = rule.Decision}}}var scores = make([]string, 0)for _, v := range result {scores = append(scores, v)}return parseScoreCard(scores, sc.Decision.Logic, sc.Decision.Output)}
通过改造后,已执行成功的规则组则不再执行。


rule:rule_name: "amout_1"rule_group: "amout_group"conditions:condition:feature: amoutoperator: LEvalue: 5000logic:decision: [5, 1.2]
func Math(expression string) (interface{}, error) {expr, _ := govaluate.NewEvaluableExpression(expression)result, err := expr.Evaluate(nil)return result, err}

构建评分卡一般流程如下:
数据探索:获取数据,EDA ( Exploratory Data Analysis ) 探索数据分析 特征选取:特征分箱,WOE 编码,基于 IV、stepwise 特征筛选
样本选取:筛选样本并划分训练集、测试集、OOT
逻辑回归:评分卡一般使用逻辑回归构建模型
评分卡转换:转为业务需要数值,易于分箱的分数
验证上线:评分卡模型部署及 abtest 验证
至此,决策引擎核心功能均已实现,但一个生产级系统还有很多细节问题未处理,如异常及错误日志处理、并发网络处理,还有一些辅助功能,如热部署、权限、审批、基本变量定义等,而一个好的决策引擎对数据、结果的监控必不可少,下一章就实时监控大盘方面给出更多解决方案,敬请关注。
