1440359316 发表于 2021-6-2 11:27

python风控模型举例

生成样本

首先,本文用以示例,故使用代码创造的一些假样本。

import numpy as np

import pandas as pd

n_sample = 1000

df_score = pd.DataFrame({
'user_id': ,

'label':np.random.randint(2, size=n_sample),

'score': 900*np.random.random(size=n_sample),

'term': 20201+np.random.randint(5, size=n_sample)

})



然后我们统计下分term的总人数,坏人数和坏人比例:

df_score.groupby('term').agg(total=('label', 'count'),

bad=('label', 'sum'),

bad_rate=('label', 'mean'))



02

区分度指标

计算区分度指标KS、AUC、GINI的helper function如下:

from sklearn.metrics import roc_auc_score, roc_curve

def get_auc(ytrue, yprob):

auc = roc_auc_score(ytrue, yprob)

if auc < 0.5:

auc = 1 - auc

return auc

def get_ks(ytrue, yprob):

fpr, tpr, thr = roc_curve(ytrue, yprob)

ks = max(abs(tpr - fpr))

return ks

def get_gini(ytrue, yprob):

auc = get_auc(ytrue, yprob)

gini = 2 * auc - 1

return gini

这里对原有sklearn的auc计算做了一点修改,如果AUC<0.5的话会返回1-AUC, 这样能忽略区分度的方向性。

然后对每个term做区分度的计算:

df_metrics = pd.DataFrame({
'auc': df_score.groupby('term').apply(lambda x: get_auc(x['label'], x['score'])),

'ks': df_score.groupby('term').apply(lambda x: get_ks(x['label'], x['score'])),

'gini': df_score.groupby('term').apply(lambda x: get_gini(x['label'], x['score']))

})



这里先分成2步:

简单对随机生成的信用分按固定分数区间分段;

按照分段计算PSI:使用pivot_table把数据按照term进行排列计算每个term上的人数比例。

df_score['score_bin'] = pd.cut(df_score['score'], )

df_total = pd.pivot_table(df_score,

values='user_id',

index='score_bin',

columns=['term'],

aggfunc="count",

margins=True)

df_ratio = df_total.div(df_total.iloc[-1, :], axis=1)



根据人数比例计算PSI再放回表格内

eps = np.finfo(np.float32).eps

lst_psi = list()

for idx in range(1, len(df_ratio.columns)-1):

last, cur = df_ratio.iloc+eps, df_ratio.iloc+eps

psi = sum((cur-last) * np.log(cur / last))

lst_psi.append(psi)

df_ratio.append(pd.Series(+lst_psi+,

index=df_ratio.columns,

name='psi'))



统计总人数分布和坏用户比例的分布,其实在上面计算PSI的时候已经计算出人数分布,就是上面的df_ratio:

df_total = pd.pivot_table(df_score,

values='user_id',

index='score_bin',

columns=['term'],

aggfunc="count",

margins=True)

df_ratio = df_total.div(df_total.iloc[-1, :], axis=1)
剩余内容请前往原文查看
————————————————
版权声明:本文为CSDN博主「你一直在玩儿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_33758343/article/details/112962601

页: [1]
查看完整版本: python风控模型举例