1. 程式人生 > 其它 >信用評分系統執行原理上篇

信用評分系統執行原理上篇

技術標籤:平凡人筆記

原始碼

https://gitee.com/pingfanrenbiji/Credit-Card-Score

在jupyter中開啟該專案

匯入程式碼庫

#Numpy是以矩陣為基礎的數學計算模組,純數學
importnumpyasnp
#pandas是提供高效能易用資料型別和分析工具的第三方庫
importpandasaspd
#繪製圖形
importmatplotlib.pyplotasplt
#seaborn是基於matplotlib開發的視覺化庫,比matplotlib更加容易使用,而且圖例的風格更加現代化
importseabornassns
#Matplotlib是Python的一個繪相簿。它包含了大量的工具,你可以使用這些工具建立各種圖形,包括簡單的散點圖,正弦曲線,甚至是三維圖形

%matplotlibinline

讀取資料字典

分別解釋下每個變數代表什麼含義

SeriousDlqin2yrs好壞客戶
RevolvingUtilizationOfUnsecuredLines信用卡和個人信用額度的總餘額,除了房地產和沒有分期付款債務,如汽車貸款除以信用額度
age出生年齡
NumberOfTime30-59DaysPastDueNotWorse過去兩年借款35-59天逾期但是不糟糕的次數
DebtRatio每月債務支付、贍養費、生活費用除以毛利
MonthlyIncome月收入
NumberOfOpenCreditLinesAndLoans開放式貸款(分期付款汽車貸款或抵押貸款)和信用額度(信用卡)的次數
NumberOfTimes90DaysLate>=90天逾期
NumberRealEstateLoansOrLines抵押貸款和房地產貸款包括房屋淨值信貸額度
NumberOfTime60-89DaysPastDueNotWorse過去兩年借款60-89天逾期但是不糟糕的次數
NumberOfDependents家屬數量不包括自己

REAL資料型別說明

REAL資料型別儲存單精度浮點數
REAL值需要4個儲存位元組
儲存為REAL型別的值可精確到7個有效數字

讀取訓練資料

df=pd.read_csv("./GiveMeSomeCredit/cs-training.csv").drop("Unnamed:0"
,axis=1)

drop是刪除函式axis=1表示列刪除指定列名為"Unnamed:0"的列

檢視前5行資料

檢視缺失值和異常值

通過info()可以看出一共有150000條資訊,MonthyIncome和NumberOfDependents存在缺失的情況,MonthyIncome缺失29731個數據,NumberOfDependents缺失3924個數據。

資料集計算

df.describe().T.assign(missing_rate=df.apply(lambdax:(len(x)-x.count())/float(len(x))))
使用describe()來看資料集中的計數、均值、最大最小值、標準差和第一、二、三個四分位值,同時增加了缺失率的計算

缺失值處理:

1、由於MonthyIncome缺失較多,因此不適合直接進行刪除,這邊根據變數之間存在的關係來填補缺失值,並採用隨機森林的方法;

2、NumberOfDependents的缺失較少,對於整體的樣本影響有限,因此這邊直接進行刪除操作,後續也可以進行一些其他的填補操作。

隨機森林函式

  • 原理分析:
  • 引數解釋:
random_state:隨機種子

n_estimators:也就是最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,計算量會太大,並且n_estimators到一定的數量後,再增大n_estimators獲得的模型提升會很小,所以一般選擇一個適中的數值。預設是100

max_depth:決策樹最大深度

n_jobs:設定工作的core數量.等於-1的時候,表示cpu裡的所有core進行工作

刪除缺失值、刪除重複值

df.dropna()
df.drop_duplicates()

異常值處理

偏離大多數抽樣資料的數值,通常指測定值中與平均值的偏差超過兩倍標準差的測定值

通常採用離群值檢測的方法對異常值進行檢測
  • 畫一個分箱圖
df["RevolvingUtilizationOfUnsecuredLines"].plot(kind="box",grid=True)

grid=True:顯示網格
  • 使用2來代替大於2的值
revNew=[]
forvalindf.RevolvingUtilizationOfUnsecuredLines:
ifval<=2:
revNew.append(val)
else:
revNew.append(2.)

再次分箱

對age分箱

df.age.plot.box(grid=True)
發現age屬性中存在0值情況,而這些資料明顯是異常值,因此對其進行處理

df=df[df["age"]>0]

對三個屬性進行分箱

df.boxplot(column=["NumberOfTime30-59DaysPastDueNotWorse","NumberOfTime60-89DaysPastDueNotWorse","NumberOfTimes90DaysLate"],rot=30)

rot:int或float,預設為0標籤的旋轉角度(以度為單位)相對於螢幕座標
上面的箱線圖可以看出NumberOfTime30-59DaysPastDueNotWorse,NumberOfTime60-89DaysPastDueNotWorse,NumberOfTimes90DaysLate三個特徵都存在兩個異常值

檢視具體的異常值

df["NumberOfTime30-59DaysPastDueNotWorse"].unique()
df["NumberOfTime60-89DaysPastDueNotWorse"].unique()
df["NumberOfTimes90DaysLate"].unique()

可以看出96和98是異常值資料

  • 用指定列資料的中位數來替換異常值
defreplaceOutlier(data):
New=[]
med=data.median()
forvalindata:
if((val==98)|(val==96)):
New.append(med)
else:
New.append(val)
returnNew

刪除了異常值之後 再看這3個列的箱線圖

檢視DebtRatio的箱線圖

使用中位數絕對偏差進行異常值檢測

第一個引數是指定列資料
第二個引數是閾值

如果列資料是陣列則轉換成array

shape返回是資料表的矩陣行列數

對於矩陣的行數也可以使len(x)函式輸出的矩陣長度也就是所謂的行數

對數列中的每一行取中位數

再用每一行中的每一個數據減去中位數

再對差值取中位數

再用一個公式norm.ppf(0.75)*(每個資料和中位數差距)/每個中位數的中位數得到一個異常值分值

分值大於閾值的話返回true

分值小於閾值返回false

檢測出最小的異常值 用於替換異常值

minUpperBound=min([valfor(val,out)inzip(df.DebtRatio,mad_based_outlier(df.DebtRatio))ifout==True])

這句話的意思是mad_based_outlier(df.DebtRatio)返回true的時候說明大於閾值是異常值

找到所有的異常值然後取最小值得到最小的異常值

  • 替換異常值
大於異常值的數都用異常值替換

檢視這一列的資料情況

畫一個箱線圖

檢視月收入的資料情況

對月收入畫箱線圖

同樣的方式 找最小的異常值 大於最小異常值的數值都用異常值替換

其他引數類似 不重複說了

資料切分

將資料切分成訓練集和測試集

  • 匯入庫
fromsklearn.model_selectionimporttrain_test_split
  • 訓練資料和測試資料分割
Y=df["SeriousDlqin2yrs"]
X=df.iloc[:,1:]
#測試和訓練資料進行3:7的比例進行切分random_state定一個值是的每次執行的時候不會被隨機分
X_train,X_test,Y_train,Y_test=train_test_split(X,Y,test_size=0.3,random_state=123)

train=pd.concat([Y_train,X_train],axis=1)
test=pd.concat([Y_test,X_test],axis=1)

train.to_csv('TrainData.csv',index=False)
test.to_csv('TestData.csv',index=False)

探索性分析

一般用直方圖、散點圖、箱線圖分析

下面利用直方圖和核密度估計畫圖,Age、MonthlyIncome、NumberOfOpenCreditLinesAndLoans大致呈正太分佈,符合統計分析
fig=plt.figure()
#alpha:設定圖表顏色
fig.set(alpha=0.2)
#subplot2grid在一張大圖裡分列幾個小圖
#在網格的特定位置建立軸物件
#允許軸物件跨越多個行或列
#縱軸2,橫軸3位於第一個位置
plt.subplot2grid((2,3),(0,0))
#hist直方圖
#bins設定直方圖中分組的數量
#figsize是一個tuple,用來指定width和height的inch(釐米)
train["age"].plot(kind="hist",bins=30,figsize=(12,6),grid=True)
plt.title("HistofAge")

#解決中文的顯示問題
plt.rcParams["font.sans-serif"]=["SimHei"]
#解決儲存影象是負號'-'顯示為方塊的問題
plt.rcParams["axes.unicode_minus"]=False

plt.tight_layout()#調整子圖之間的間距,緊湊顯示影象
plt.show()

特徵選擇

1、變數分箱將連續變數離散化將多狀態的離散變數合併成少狀態

2、變數分箱重要性

a穩定性避免特徵中無意義的波動對評分帶來波動

b健壯性避免極端值的影響

3、變數分箱優勢

a可以將缺失值作為獨立的箱帶入模型中

b將所有的變數變換到相似的尺度上

變數分箱劣勢

a計算量大

b分箱之後需要編碼

4、變數分箱常用方法

a有監督

a-1Best-Ks

a-2ChiMerge(卡放分箱)

b無監督

b-1等距

b-2等頻

b-3聚類

後續

下一篇寫下特徵分箱等實現邏輯