风控策略

风控:

风控策略是有许多规则组成的一个用以实现机构风险控制目标的规则集合,一般通过调用风控策略变量(也就是数据),模拟业务调用规则引擎,执行最后输出决策结果

主要有风控规则测试(针对结果状态进行测试,分为命中和未命中两个状态),风控模型测试(通过样本特征,得出模型输出结果),决策流测试(规则集与风控模型进行一定的条件分流或者串联后的测试流程),

静态规则:对不同的预期结果进行遍历

阈值规则:等价类以及边界值校验 Equivalent class(0.5.9.10)IVEC- Invalid Equivalent class(null.-1.9.5)

规则包括多个变量且以一定的逻辑组合  a or b and c -判定+条件(阈值覆盖的方法)覆盖

对照测试:创建风控模型,包括需要的样本特征以及预期输出结果,并使用样本特征数据调用规则引擎执行,对比输出结果与预期结果一致

 

简单的单侧可以实现自动化测试,步骤为入参json-参数组合-预期结果

取值范围一般考虑使用等价类、边界值、判定表等方法,白盒使用判定、条件覆盖,路径覆盖,

 

java单测:

//package Price;

//

//public class Price extends TestCase(){

//    Price price = new Price();

//    public void pirce1(){

//        context.put("barginprice",300000);

//        context.put("purchaseprice",290000);

//        context.put("redives",5743);

//        context.put("commerical",5882);

//        Object result = runnerExc(express context);

//        System.out.println(result);

//        Assert.assertEquals(0,result);

//    }

//}

 

RF脚本:

#!/usr/bin/env python3

 

import logging

import datetime

import time

import math

import DataFile.v3params

 

logging.basicConfig(level = logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

 

def getApplicationScoreV3(json):

    '''

    获取v3申请评分

 

    json:同盾、年龄(身份证)、天行、百融、前海

    '''

    td_woe = 0.64639017

    age_woe = 0

    tx_result = 1

 

    # 计算td_woe

    TONGDUN_RISK_SYNC = json.get('TONGDUN_RISK_SYNC', None)

    if (TONGDUN_RISK_SYNC):

        final_score = TONGDUN_RISK_SYNC.get('tongdun_score', None)

        if (final_score is not None):

            if (final_score <= 0):

                td_woe = -1.18744338

            elif (final_score <= 12):

                td_woe = -0.49966371

            elif (final_score <= 22):

                td_woe = 0.16083263

            elif (final_score <= 30):

                td_woe = 0.66510287

            elif (final_score <= 39):

                td_woe = 0.76188007

            else:

                td_woe = 1.18448923

        logging.debug(final_score)

        logging.debug(td_woe)

 

    # 计算age_woe

    idCardNo = json['idCardNo']

    birth = slice(6, 14)

    birthday = idCardNo[birth]

    birthDate = datetime.datetime.strptime(birthday, '%Y%m%d')

    now = time.strftime('%Y%m%d')

    nowDate = datetime.datetime.strptime(now, '%Y%m%d')

    deltaBirth = nowDate - birthDate

    age17 = datetime.timedelta(17 * 365.25)

    age22 = datetime.timedelta(22 * 365.25)

    age25 = datetime.timedelta(25 * 365.25)

    age30 = datetime.timedelta(30 * 365.25)

    age40 = datetime.timedelta(40 * 365.25)

    if deltaBirth >= age17:

        if deltaBirth < age22:

            age_woe = 0.2143331

        elif deltaBirth < age25:

            age_woe = 0.3268093

        elif deltaBirth < age30:

            age_woe = 0.1188442

        elif deltaBirth < age40:

            age_woe = -0.087128

        else:

            age_woe = -0.3891595

    logging.debug(birthday)

    logging.debug(age_woe)

    

    # 天行不良 tx_result

    TIANXING_RISK_BAD_RECORD = json.get('TIANXING_RISK_BAD_RECORD_V2', None)

    # logging.debug(TIANXING_RISK_BAD_RECORD)

    if (TIANXING_RISK_BAD_RECORD):

        tx_hit = TIANXING_RISK_BAD_RECORD.get('result', False)

        if tx_hit:

            tx_result = 0

        else:

            tx_result = 1

    logging.debug(tx_result)

    

    # 百融画像

    BFD_PORTRAIT_RISK = json.get('BFD_PORTRAIT_RISK', None)

    if (BFD_PORTRAIT_RISK):

        scoreconsoff = int(BFD_PORTRAIT_RISK.get('scoreconsoff', 585))

        if (scoreconsoff<=300 or scoreconsoff>1000):

            scoreconsoff = 585

        scoreautosec = int(BFD_PORTRAIT_RISK.get('scoreautosec', 682))

        if (scoreautosec<=300 or scoreautosec>1000):

            scoreautosec = 682

    logging.debug('scoreconsoff:{}'.format(scoreconsoff))

    logging.debug('scoreautosec:{}'.format(scoreautosec))

    

    # 前海

    QIANHAI_TRUST_DEGREE_SCORE = json.get('QIANHAI_TRUST_DEGREE_SCORE', None)

    if (QIANHAI_TRUST_DEGREE_SCORE):

        credoo_score = QIANHAI_TRUST_DEGREE_SCORE.get('trustScore', 450)

        if (credoo_score<300 or credoo_score>900):

            credoo_score = 450

    logging.debug('credoo_score:{}'.format(credoo_score))

 

    logging.debug('----------ScoreCard------------')

    logging.debug('td_woe:{}, age_woe:{}, tx_result:{}, scoreconsoff:{}, scoreautosec:{}, credoo_score:{}'.format(td_woe, age_woe, tx_result, scoreconsoff, scoreautosec, credoo_score))

    

    applicationScoreV3 = 701.0265 - 30 / (math.log(2)) * (5.942776895 + td_woe * 0.4405788 + scoreconsoff * (-0.0021673) + tx_result * (-0.441314) + scoreautosec * (-0.0025141) + credoo_score * (-0.0040202) + age_woe * 0.4655552)

 

    return applicationScoreV3

 

if __name__ == '__main__':

    json = DataFile.v3params.json

    print(f'ApplicationScoreV3 is {getApplicationScoreV3(json)}')

 

 

import math

import logging

 

logging.basicConfig(level = logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

 

def getApplicationScore_nt(n=6, *args, **kwargs):

    credoo_score = kwargs['credoo_score'] if 'credoo_score' in kwargs else 598

    final_score = kwargs['final_score'] if 'final_score' in kwargs else 14

    scoreconsoff = int(kwargs['scoreconsoff'] if 'scoreconsoff' in kwargs else 620)

    scoreautosec = int(kwargs['scoreautosec'] if 'scoreautosec' in kwargs else 704)

    scoreafautofin = int(kwargs['scoreafautofin'] if 'scoreafautofin' in kwargs else 42)

    pc_rcnt_income = float(kwargs['pc_rcnt_income'] if 'pc_rcnt_income' in kwargs else 3.86)

    pc_rcnt_econ = float(kwargs['pc_rcnt_econ'] if 'pc_rcnt_econ' in kwargs else 0.46)

    logging.debug(f'credoo_score:{credoo_score}, final_score:{final_score}, scoreconsoff:{scoreconsoff}, scoreautosec:{scoreautosec}, scoreafautofin:{scoreafautofin}, pc_rcnt_income:{pc_rcnt_income}, pc_rcnt_econ:{pc_rcnt_econ}')

    if n == 6:

        ApplicationScore_nt = 660 - (20/math.log(2))*(math.log(15) + 3.15938981080775 - 0.00586801961406731*credoo_score + 0.0160308049664558*final_score - 0.0937503931902562*pc_rcnt_income - 0.00180187555140517*scoreconsoff - 0.00334407482259153*scoreautosec)

    if n == 12:

        ApplicationScore_nt = 660 - (20/math.log(2))*(math.log(15) - 2.18264992233002 + 0.0385632018345964*scoreafautofin - 0.00552478523047619*credoo_score + 0.0120548154878177*final_score + 0.472130657365639*pc_rcnt_econ)

    return ApplicationScore_nt

 

 

json = {

'credoo_score':778,

'final_score':80,

'scoreconsoff':'800',

'scoreautosec':'800',

'scoreafautofin':'29',

'pc_rcnt_income':'1',

'pc_rcnt_econ':'0'

}

ApplicationScore_06t = getApplicationScore_nt(6, **json)

ApplicationScore_12t = getApplicationScore_nt(12, **json)

logging.debug('ApplicationScore_06t:{},ApplicationScore_12t:{}'.format(ApplicationScore_06t, ApplicationScore_12t))

 

{

    "name":{

        "value":"杨锦庆",

        "varCode":"name",

        "varType":"STRING"

    },

    "idCardNo":{

        "value":"450881199311201237",

        "varCode":"idCardNo",

        "varType":"STRING"

    },

    "mobile":{

        "value":"18978888067",

        "varCode":"mobile",

        "varType":"STRING”

}

posted @ 2019-07-09 22:47  garraw  阅读(749)  评论(0)    收藏  举报