项目简介
信用风险:未履行合同的义务而造成的经济损失的风险。
评分卡:以分数的形式来衡量风险几率的一种手段,分数越高越安全。
数据来源:Kaggle
有15万条的样本数据,
– 基本属性:包括了借款人当时的年龄。
– 偿债能力:包括了借款人的月收入、负债比率。
– 信用往来:两年内35-59天逾期次数、两年内60-89天逾期次数、两年内90天或高于90天逾期的次数。
– 财产状况:包括了开放式信贷和贷款数量、不动产贷款或额度数量。
– 贷款属性:暂无。
– 其他因素:包括了借款人的家属数量(不包括本人在内)。
– 时间窗口:自变量的观察窗口为过去两年,因变量表现窗口为未来两年。
标号 | 变量标签 | 变量解释 |
---|---|---|
x0 | SeriousDlqin2yrs | 好客户和坏客户 |
x1 | RevolvingUtilizationOfUnsecuredLines | 无担保放款的循环利用 |
x2 | age | 借款人借款时的年龄 |
x3 | NumberOfTime30-59DaysPastDueNotWorse | 35-59天逾期但不糟糕次数 |
x4 | DebtRatio | 负债比率 |
x5 | MonthlyIncome | 月收入 |
x6 | NumberOfOpenCreditLinesAndLoans | 开放式信贷和贷款数量 |
x7 | NumberOfTimes90DaysLate | 90天逾期次数 |
x8 | NumberRealEstateLoansOrLines | 不动产贷款或额度数量 |
x9 | NumberOfTime60-89DaysPastDueNotWorse | 60-89天逾期但不糟糕次数 |
x10 | NumberOfDependents | 家属数量 |
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] =['Microsoft YaHei']
plt.rcParams['axes.unicode_minus']=False
import seaborn as sns
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, auc
import os
os.chdir(r'\信用评分\GiveMeSomeCredit')
df=pd.read_csv('cs-training.csv')
states={
"Unnamed: 0":"用户ID",
"SeriousDlqin2yrs":"好坏客户",
"RevolvingUtilizationOfUnsecuredLines":"可用额度比值",
"age":"年龄",
"NumberOfTime30-59DaysPastDueNotWorse":"逾期30-59天笔数",
"DebtRatio":"负债率",
"MonthlyIncome":"月收入",
"NumberOfOpenCreditLinesAndLoans":"信贷数量",
"NumberOfTimes90DaysLate":"逾期90天笔数",
"NumberRealEstateLoansOrLines":"固定资产贷款量",
"NumberOfTime60-89DaysPastDueNotWorse":"逾期60-89天笔数",
"NumberOfDependents":"家属数量"}
df.rename(columns=states,inplace=True)
df.head()
数据预处理
df.info()
def missing_values_table(df):
#全部缺失值
mis_val =df.isnull().sum()
#缺失值比例
mis_val_percent =100*df.isnull().sum()/len(df)
#能成一个表
mis_val_table=pd.concat([mis_val,mis_val_percent],axis=1)
#改列名
mis_val_table_ren_columns=mis_val_table.rename(
columns={
0:'缺失值',1:'缺失比例'})
#对缺失值排序
mis_val_table_ren_columns=mis_val_table_ren_columns[mis_val_table_ren_columns.iloc[:,1]!=0]\
.sort_values('缺失比例',ascending=False).round(1)
#打印出表
print("数据有"+str(df.shape[1])+"列.\n"
"其中"+str(mis_val_table_ren_columns.shape[0])+
"列含有缺失值.")
#返回确实行列
return mis_val_table_ren_columns #显示缺失值和表示缺失值函数
missing_values_table(df)
缺失值
"家属数量"变量缺失值比较少,直接删除,对总体模型不会造成太大影响。对缺失值处理完之后,删除重复项。
df=df[df.家属数量.notnull()].drop_duplicates()
“月收入”缺失率比较大,采用随机森林法,根据变量之间的相关关系填补缺失值
# 用随机森林对缺失值预测填充函数
def set_missing(df):
# 把已有的数值型特征取出来
# process_df = df.iloc[:,1:]
process_df = df.iloc[:,[6,1,2,3,4,5,7,8,9,10,11]]
# 分成已知该特征和未知该特征两部分
known = process_df[process_df.月收入.notnull()].values
unknown = process_df[process_df.月收入.isnull()].values
# X为特征属性值
X = known[:,1:]
# y为结果标签值
y = known[:,0]
# fit到RandomForestRegressor之中
rfr = RandomForestRegressor(random_state=0,n_estimators=200,max_depth=3,n_jobs=-1)
rfr.fit(X,y)
# 用得到的模型进行未知特征值预测
predicted = rfr.predict(unknown[:,1:]).round(0)
print(predicted)
# 用得到的预测结果填补原缺失数据
df.loc[(df.月收入.isnull()), '月收入'] = predicted
return df
df=set_missing(df)
异常值
缺失值处理完毕后,我们还需要进行异常值处理。异常值是指明显偏离大多数抽样数据的数值,比如个人客户的年龄为0时,通常认为该值为异常值。这里用盖帽法处理。
盖帽法:整行替换数据框里99%以上和1%以下的点,将99%以上的点值=99%的点值;小于1%的点值=1%的点值。
df.年龄.hist(bins=50)
#盖帽法
def blk(floor,root):
def f(x):
if x<floor:
x=floor
elif x>root:
x=root
return x
return f
q1=df.年龄.quantile(0.01)
q99=df.年龄.quantile(