前言
记一次薅羊毛用户风险评判的机制以及其应用
借用模型为风控贷前评分卡
根据iv,woe值计算区块得分系数以及输出card用以适配不同业务场景
所有敏感信息已做脱敏处理。
一、风险用户识别原理
总有一些用户是想要通过某些作弊手法获取不正当利益的,关于获取方式这里不做披露,只分析如何通过用户行为甄别用户的风险得分以判断是否为高风险用户
二、步骤以及代码展示
1.用户抽取
本人是jupyterlab的忠实用户,比较适合数据分析以及基础建模人员,如果在服务器上运行直接“!”加上sql语句即可提取数据进行分析以及建模
!hive -e "select * from xx.xxxx where dt = xxxxx and xxx<>xxx" > ./data/用户画像/table1.txt
df1 = pd.read_table('table1.csv',sep=',')
jupyterlab的配置教程如下
jupyterlab小白配置
2.用户数据基本处理
# 列举几个常用的
df1 = df1.drop_duplicates(['id','child_id'])
df1.fillna(0)
df1['id'] = df1['id'].astype('object')
3.特征工程建立
特征工程建立分很多种,有线下预建立然后匹配,有线上直接生成工程
该模型还在优化中,暂拿以下举例:
1.用户薅羊毛一般在拉新上做猫腻,所以就可以看该用户短时间的最短邀请间隔作为一个特征
# 先转化为时间格式
df1['invitetime'] = pd.to_datetime(df1['invitetime'])
# 再按照时间排序
df1= df1.sort_values('invitetime')
# 转化为方便计算的列表
timePoints = df1[df1['id']=='123123]['createtime'].tolist()
# 撰写函数类
class Solution:
def findMinDifference(self, timePoints) -> int:
d = []
[bisect.insort(d,(c-timePoints[0]).seconds) for c in timePoints]
# print(d[-1],d[0])
# d[-1] += d[0]
return min(d[i] - d[i - 1] for i in range(1, len(d)))
print("该名用户123123的最短邀请间隔为:",Solution().findMinDifference(timePoints))
该名用户的最短邀请间隔为: 12
这里我们精细为秒,毕竟有些黑产机刷嘛
然后就可以将类放到列上逐步执行
list1 = []
for i in df1['id'].tolist():
df_temp = df1['id']==i
timePoints = df_temp['invitetime'].tolist()
list1.append(Solution().findMinDifference(timePoints))
df1 = pd.concat([df1,pd.DataFrame(data=list1,columns={'shortest_invitetime'}),axis=1])
这样就可以有了每个用户的最小邀请间隔啦
当然了也可以采取这种方法
def shortest_invitetime(i):
df_temp = df1['id']==i
timePoints = df_temp['invitetime'].tolist()
return Solution().findMinDifference(timePoints)
df1['shortest_invitetime'] = df1['invitetime'].apply(lambda x:shortest_invitetime(x))
只不过这样时间复杂度上要慢一点啦
类似的特征构造还有一天邀请用户数,一天低价订单数之类的,由于信息保密性就不一一列举啦
4.模型与评分卡建立
评分卡模型的原理:
- 通过将各属性值按分箱处理,计算整体的权重值
- 根据权重值结果计算该箱得分,比如邀请次数在1-3次的为10分,4-8的为30分,9次以上的为100分等等
- 根据用户所在分箱范围获得每个属性值的子得分,之后将每个属性值的子得分汇合则为该用户的风险得分
模型建立步骤则是:
- 使用评分卡函数包分箱,当然也可以自己写函数分箱评分卡分箱建立
- 使用分类模型输出预测标签值
- 通过标签值以及各属性值所在分区的位置输出用户风险得分
简单拿一个被人上传过的评分卡举例,来源github-scorecardpy
使用gitgub上已导入的库进行分区并计算权重
关于woe和iv的计算可以看权重值计算
import scorecardpy as sc
dt_s = sc.var_filter(df_model[model_columns], y='target')
train, test = sc.split_df(dt_s, 'target').values()
bins = sc.woebin(dt_s, y='target')
train_woe = sc.woebin_ply(train, bins)
test_woe = sc.woebin_ply(test, bins)
y_train = train_woe.loc[:,'target']
X_train = train_woe.loc[:,train_woe.columns != 'target']
y_test = test_woe.loc[:,'target']
X_test = test_woe.loc[:,train_woe.columns != 'target']
用一个简单的逻辑回归试下,自己调参哦
# logistic regression ------
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(penalty='l1', C=0.9, solver='saga', n_jobs=-1)
lr.fit(X_train, y_train)
# lr.coef_
# lr.intercept_
之后就可以有评分卡和预测值啦
# predicted proability
train_pred = lr.predict_proba(X_train)[:,1]
test_pred = lr.predict_proba(X_test)[:,1]
# 评分卡生成
card = sc.scorecard(bins, lr, X_train.columns)
# 得分生成
train_score = sc.scorecard_ply(train, card, print_step=0)
test_score = sc.scorecard_ply(test, card, print_step=0)
score = sc.scorecard_ply(df_model, card, only_total_score = False)
可以简单的看下socre大致范围哦
sns.distplot(score)
总结
关于分数的基准值默认是600,当然了也可以自己设置,分数越高风险越大,当然了这种评分卡只是相当于金融信贷贷前评分卡啦,也就是A卡,我们可以通过这种方式来决定他是否可以进行某种行为奥,例如购买礼品,兑换奖品等
衍生出来的模型还有,用户登录行为风险,用户消费行为风险,既可以拆分为多个模型生成多方面的风险得分,也可以汇总到一起得出用户自身风险得分,主要看业务场景的使用啦
初来乍到,巨佬轻喷