信用評分系統執行原理上篇
阿新 • • 發佈:2020-12-09
技術標籤:平凡人筆記
原始碼
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聚類
後續
下一篇寫下特徵分箱等實現邏輯