1. 程式人生 > 實用技巧 >阿里雲的金融風控-貸款違約預測

阿里雲的金融風控-貸款違約預測

一、賽題資料

資料大家可以到官網去下載:https://tianchi.aliyun.com/competition/entrance/531830/information需要報名後才可以下載資料

賽題以預測使用者貸款是否違約為任務,資料集報名後可見並可下載,該資料來自某信貸平臺的貸款記錄,總資料量超過120w,包含47列變數資訊,其中15列為匿名變數。為了保證比賽的公平性,將會從中抽取80萬條作為訓練集,20萬條作為測試集A,20萬條作為測試集B,同時會對employmentTitle、purpose、postCode和title等資訊進行脫敏。

欄位表

FieldDescription
id 為貸款清單分配的唯一信用證標識
loanAmnt 貸款金額
term 貸款期限(year)
interestRate 貸款利率
installment 分期付款金額
grade 貸款等級
subGrade 貸款等級之子級
employmentTitle 就業職稱
employmentLength 就業年限(年)
homeOwnership 借款人在登記時提供的房屋所有權狀況
annualIncome 年收入
verificationStatus 驗證狀態
issueDate 貸款發放的月份
purpose 借款人在貸款申請時的貸款用途類別
postCode 借款人在貸款申請中提供的郵政編碼的前3位數字
regionCode 地區編碼
dti 債務收入比
delinquency_2years 借款人過去2年信用檔案中逾期30天以上的違約事件數
ficoRangeLow 借款人在貸款發放時的fico所屬的下限範圍
ficoRangeHigh 借款人在貸款發放時的fico所屬的上限範圍
openAcc 借款人信用檔案中未結信用額度的數量
pubRec 貶損公共記錄的數量
pubRecBankruptcies 公開記錄清除的數量
revolBal 信貸週轉餘額合計
revolUtil 迴圈額度利用率,或借款人使用的相對於所有可用迴圈信貸的信貸金額
totalAcc 借款人信用檔案中當前的信用額度總數
initialListStatus 貸款的初始列表狀態
applicationType 表明貸款是個人申請還是與兩個共同借款人的聯合申請
earliesCreditLine 借款人最早報告的信用額度開立的月份
title 借款人提供的貸款名稱
policyCode 公開可用的策略_程式碼=1新產品不公開可用的策略_程式碼=2
n系列匿名特徵 匿名特徵n0-n14,為一些貸款人行為計數特徵的處理

二、資料分析

2.1主要內容

  • 資料總體瞭解:
    • 讀取資料集並瞭解資料集大小,原始特徵維度;
    • 通過info熟悉資料型別;
    • 粗略檢視資料集中各特徵基本統計量;
  • 缺失值和唯一值:
    • 檢視資料缺失值情況
    • 檢視唯一值特徵情況
  • 深入資料-檢視資料型別
    • 類別型資料
    • 數值型資料
      • 離散數值型資料
      • 連續數值型資料
  • 資料間相關關係
    • 特徵和特徵之間關係
    • 特徵和目標變數之間關係
  • 用pandas_profiling生成資料報告

2.2 程式碼示例

2.2.1 匯入資料分析及視覺化過程需要的庫

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import warnings
warnings.filterwarnings('ignore')

2.2.2 讀取檔案

data_train = pd.read_csv('F:/python/阿里雲金融風控-貸款違約預測/train.csv')
data_test_a = pd.read_csv('F:/python/阿里雲金融風控-貸款違約預測/testA.csv')

2.2.3 總體瞭解

data_test_a.shape  #(200000, 48)
data_train.shape  #(800000, 47)
data_train.columns
data_train.info()
data_train.describe()
data_train.head(3).append(data_train.tail(3))

2.2.4 檢視資料集中特徵缺失值,唯一值等

print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')
#There are 22 columns in train dataset with missing values.
# nan視覺化
missing = data_train.isnull().sum()/len(data_train)
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()

檢視訓練集測試集中特徵屬性只有一值的特徵

one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 1]
one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]
print(one_value_fea,one_value_fea_test )
#['policyCode'] ['policyCode']
data_train['policyCode'].value_counts() 
#1.0    800000
#Name: policyCode, dtype: int64
#可以刪除
data_train=data_train.drop(['policyCode'],axis=1)
data_test_a=data_test_a.drop(['policyCode'],axis=1)
print(data_train.shape,data_test_a.shape)
data_train.columns,data_test_a.columns

2.2.5 檢視特徵的數值型別有哪些,物件型別有哪些

  • 特徵一般都是由類別型特徵和數值型特徵組成
  • 類別型特徵有時具有非數值關係,有時也具有數值關係。比如‘grade’中的等級A,B,C等,是否只是單純的分類,還是A優於其他要結合業務判斷。
  • 數值型特徵本是可以直接入模的,但往往風控人員要對其做分箱,轉化為WOE編碼進而做標準評分卡等操作。從模型效果上來看,特徵分箱主要是為了降低變數的複雜性,減少變數噪音對模型的影響,提高自變數和因變數的相關度。從而使模型更加穩定
data_train.info()
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))

['id',
 'loanAmnt',
 'term',
 'interestRate',
 'installment',
 'employmentTitle',
 'homeOwnership',
 'annualIncome',
 'verificationStatus',
 'isDefault',
 'purpose',
 'postCode',
 'regionCode',
 'dti',
 'delinquency_2years',
 'ficoRangeLow',
 'ficoRangeHigh',
 'openAcc',
 'pubRec',
 'pubRecBankruptcies',
 'revolBal',
 'revolUtil',
 'totalAcc',
 'initialListStatus',
 'applicationType',
 'title',
 'n0',
 'n1',
 'n2',
 'n2.1',
 'n4',
 'n5',
 'n6',
 'n7',
 'n8',
 'n9',
 'n10',
 'n11',
 'n12',
 'n13',
 'n14']
['grade', 'subGrade', 'employmentLength', 'issueDate', 'earliesCreditLine']

數值型變數分析,數值型肯定是包括連續型變數和離散型變數的,找出來

#過濾數值型類別特徵
def get_numerical_serial_fea(data,feas):
    '''
    目的:劃分數值型變數中的連續變數和分類變數
    data:需要劃分的資料集
    feas:需要區分的特徵的名稱
    返回:連續變數和分類變數 的list集合
    '''
    numerical_serial_fea = []
    numerical_noserial_fea = []
    for fea in feas:
        temp = data[fea].nunique()
        if temp <= 10:
            numerical_noserial_fea.append(fea)
            continue
        numerical_serial_fea.append(fea)
    return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(data_train,numerical_fea)
numerical_serial_fea,numerical_noserial_fea

(['id',
  'loanAmnt',
  'interestRate',
  'installment',
  'employmentTitle',
  'annualIncome',
  'purpose',
  'postCode',
  'regionCode',
  'dti',
  'delinquency_2years',
  'ficoRangeLow',
  'ficoRangeHigh',
  'openAcc',
  'pubRec',
  'pubRecBankruptcies',
  'revolBal',
  'revolUtil',
  'totalAcc',
  'title',
  'n0',
  'n1',
  'n2',
  'n2.1',
  'n4',
  'n5',
  'n6',
  'n7',
  'n8',
  'n9',
  'n10',
  'n13',
  'n14'],
 ['term',
  'homeOwnership',
  'verificationStatus',
  'isDefault',
  'initialListStatus',
  'applicationType',
  'n11',
  'n12'])

在仔細檢視每個數值型的類別變數