如何将LR的预测概率值转化为分数?
背景:在互联网金融中,一般用LR模型来预测一个借贷用户的好坏,但是LR模型得到的结果是逾期的概率值,如何仅仅给出预测概率值,人一般很难判断这个概率值代表的用户质量好坏,但是如果能够给出分数就比较理解了。而我们一般要把逾期概率转为分数来供公司进行决策,那么如何将逾期概率转化为用户质量的得分,例如0-100呢?
最容易想到的是将逾期率概率值直接乘以100就得到分数了,但是LR得到的概率值往往是不均匀的,比如讲概率值排序后,头部和尾部的概率值较少,大部分概率都集中在中间某个区域,这时这种方法就失效了。
还有一种方法是将概率值进行排序,找出头部的20%概率值映射到80-100分,尾部的20%概率值映射到0-60分,中间的60%概率值映射到60-80分,那么如何将头部的20%概率映射到80-100分呢?可以将概率值作为X,分数score作为Y,计算一个线性回归模型 Y=w1X+w2 。这样,当就可以将概率值通过线性函数映射到分数了。
注意,具体映射到哪个分数区间可以根据业务进行调整。
import numpy as np
from pandas import DataFrame
def score_model(result_train, bins_num=10):
"""
根据输入的样本数据,进行打分模型的训练:
输入数据格式:dict 组成list, dict = {score : ml_model_proba}
输出数据格式:bin_dict = {i:{'left': , 'right': , 'line_train_list'}}
"""
sorted_result_train = sorted(result_train, key=lambda result_train:result_train['score'], reverse=False)
print(len(sorted_result_train))
score_bins = {}
every_len = int(len(sorted_result_train) / bins_num)
print(every_len)
# 30分粒度,做分桶,桶内直线拟合
for i in range(0, bins_num):
left = sorted_result_train[i*every_len]['score']
right = sorted_result_train[(i+1)*every_len-1]['score']
step = 300/bins_num
score_map = [800-i*step, 800-(i+1)*step]
if i == bins_num-1:
right = sorted_result_train[-1]['score']
line_train = np.polyfit([left, right], score_map, 1)
line_train_list = line_train.tolist()
bins = dict()
bins['left'] = left
bins['right'] = right
bins['line_train_list'] = line_train_list
score_bins[i] = bins
return score_bins
def predict_score(score_bins, result_proab):
"""
打分模型:根据输入的result_proab, 按照score_bins进行打分;score_bins就是打分model
"""
proab = result_proab
score = 0
for k,v in score_bins.items():
if proab >= v['left'] and proab < v['right']:
score = v['line_train_list'][0] * proab + v['line_train_list'][1]
break
return score
scores = np.random.random(20)
ids = range(20)
df = DataFrame([ids,scores]).T
df.columns = ["id", "score"]
dic = df.to_dict(orient="records")
print("dic:",dic)
#训练打分模型(将逾期的概率映射为500-800之间的分数,分数越高,用户越好)
score_bins = score_model(dic)
print(score_bins)
#输入pred概率值,输出分数
result_proab = 0.083882018
score = predict_score(score_bins, result_proab)
print("score:", score)