https://www.jianshu.com/p/a8037a38e219(原文鏈接)
- 背景
- 目的
- 數據集獲取
- 數據處理
一、背景
公司背景
Lending Club 創立於2006年,主營業務是為市場提供P2P貸款的平台中介服務,公司總部位於舊金山。
公司在運營初期僅提供個人貸款服務,至2012年平台貸款總額達10億美元規模。
2014年12月,Lending Club在紐交所上市,成為當年最大的科技股IPO。
2014年后公司開始為小企業提供商業貸款服務。
2015年全年Lending Club平台新設貸款金額達到了83.6億美元。
2016年上半年Lending club爆出違規放貸丑聞,創始人離職,股價持續下跌,全年虧損額達1.46億美元。
作為P2P界的鼻祖,Lending club跌宕起伏的發展歷史還是挺吸引人的。
此處再順便介紹一下什么是P2P。概括起來可以這樣理解,“所有不涉及傳統銀行做媒介的信貸行為都是P2P”。簡單點來說,P2P公司不會出借自有資金,而是充當“中間人”的角色,讓借款人與出借人相親相愛。
借款人高興的是拿到了貸款,而且過程快速便利,免遭傳統銀行手續眾多的折磨;出借人高興的是借出資金的投資回報遠高於存款利率;那么中間人高興的是用服務換到了流水(拿的便是事成之后的抽成) 最后實現三贏。
貸款標准
借款人提交申請后,Lending Club 會根據貸款標准進行初步審查。貸款人需要滿足以下標准才能借款:
1.FICO 分數在660 分以上

2.債務收入比例低於40%
3.信用報告反應以下情況:至少有兩個循環賬戶正在使用,最近6 個月不超過5 次被調查,至少36 個月的信用記錄
貸款等級
貸款分為A、B、C、D、E、F、G 7 個等級,每個等級又包含了1、2、3、4、5 五個子級。
二、目的
研究影響貸款等級的相關因素,並探尋潛藏在數據背后的一些規律
三、數據集獲取
選取2016年第一季度、第二季度的數據集以及特征變量的說明文檔。


說明:部分重要的特征變量似乎缺失,多次下載的數據集中缺少fico分數、fico_range_low、fico_range_high等與fico相關的特征,所以在形成結論進行總結的時候,這些特征的結論將從相關的報告中獲取。
四、數據處理
在對數據進行處理前,我們需要對數據有一個整體的認識
lendData.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 133891 entries, 0 to 133890 Columns: 110 entries, id to total_il_high_credit_limit dtypes: float64(86), object(24) memory usage: 100.1+ MB
從上述的信息中可以看出:
1.133891行數據,110個特征變量
2.110個特征變量中有86個是浮點數類型,24個是Object對象。
獲取到的信息還是太少,接下來可以通過下面的方法,得到數值型數據和Object基類的數據分布。
lendData.select_dtypes(include=['O']).describe().T\ .assign(missing_pct=lendData.apply(lambda x : (len(x)-x.count())/len(x)))
篩選出object對象的對應信息,可分別得到非空值數量、unique數量,最大頻數變量,最大頻數,以及新添加一列特征變量missing_pct,表示值缺失的比重。

從圖表中可以得到部分信息:
1.貸款共7個等級,占比最多的是B級
2.還款的形式有兩種,占比最多的是36個月
3.貸款人中大多數人工齡10+年
4.貸款人的房屋狀況大多是抵押貸款
5.大多數人貸款的目的是債務整合
6.id與desc特征的數據缺失率高達0.99,間接表明這兩個特征可以刪除掉。
同樣可以按照這種方式對浮點型的數據進行數據預覽,得到均值、標准差、四分位數以及數據的缺失比重等信息。
空值、異常值處理
得到上述的信息后,我們可以根據缺失比重進行數據的清洗。在這里按照60%的閾值刪除數據。最后得到100個特征變量。
原始數據集存在異常值情況,如特征變量emp_length(工齡)數據中包含‘n/a’的數據,產生原因為公式應用的錯誤無法找到原值,而且占比較小,清除后剩余124947行數據。
除去異常值,還包括對空值的處理,對於較為重要的特征來說,如果缺失值占比較小,可以通過填補均值進行處理。
application_joint['il_util'] = application_joint['il_util'].replace('NaN',application_joint['il_util'].mean())
特征篩選
特征篩選在數據預處理中是很關鍵的一步,這一步對后序的分析、挖掘有很大的影響。
經過初步的數據清洗后,我們得到了100個特征變量,這其中包括一些與最終研究目的完全無關的變量,一部分方差值很小、無法得到更多信息的變量。雖然100個特征變量不算多,但如果去掉一些無用的特征減少數據維度,且有一定的降噪效果,那么這一步是必須要做的。
這里的篩選標准如下:
1.與最終研究目的無關的特征
2.方差值太小,無法獲取有用信息的特征
3.不可解釋的特征
我們的研究目的是探討影響貸款等級的眾多因素,關鍵特征grade代表的就是不同的貸款等級,如果想剔除與grade無關的特征,那么可以用相關系數來處理。
相關系數:研究變量之間線性相關程度的量
具體要如何處理呢?特征grade中包含A、B、C、D等七個貸款等級,做數值計算之前,需要將Object類型轉換為數值類型。
#貸款等級Object類型轉為數值類型 grade = lendData['grade'].replace('A',1) grade = grade.replace('B',2) grade = grade.replace('C',3) grade = grade.replace('D',4) grade = grade.replace('E',5) grade = grade.replace('F',6) grade = grade.replace('G',7)
轉換過后,我們可以將特征中所有的數值類型的數據與貸款等級進行相關系數計算。
dicti = {} #計算兩組數的相關系數 for i in range(0,len(lendData.select_dtypes(include=['float64']).columns)): try: dicti[lendData.columns[i]] = np.corrcoef(lendData[lendData.columns[i]].dropna(),grade)[0,1] print(lendData.columns[i],np.corrcoef(lendData[lendData.columns[i]].dropna(),grade)[0,1]) except Exception as e: continue
經過數據可視化得到下面的相關系數分布圖。

經過篩選后,得到54個特征(不包括未轉換數據類型的其他Object類型特征),其中total_rec_int(目前為止收到的利息)、bc_util(銀行卡流動余額與信貸限額比率)、acc_open_past_24mths(過去24個月內的交易量)、open_il_12m(過去12個月內開設的分期付款帳戶數)等特征與貸款等級呈正相關關系。total_rev_hi_lim(總的周轉信用額度)、total_rec_prncp(迄今收到的本金)、mths_since_recent_bc(自最近銀行卡帳戶開立以來的幾個月)等特征與貸款等級呈明顯的負相關關系。
同時,我們注意到這樣的一個問題,在相關系數的分布中,有一部分相關系數較高的特征是由貸款等級來確定的(比如說貸款總金額、未償還的本金、迄今收到的本金、利息等等,都是確定貸款等級之后才有的信息),而不是決定貸款等級的因素,因果關系不成立。這樣的特征即使於貸款等級相關性高,也與最終的目的無關。
相關系數只是篩選的一種標准,具體的特征留存還需要根據對貸款業務的理解,有所保留的刪減特征。
之后我們對上述的54個特征進行方差篩選,對於方差值較小、變化幅度較小的特征進行剔除,當然要綜合考慮。
from sklearn.feature_selection import VarianceThreshold #方差選擇法,返回值為特征選擇后的數據 #參數threshold為方差的閾值 lend = VarianceThreshold(threshold=2).fit_transform(lendData.select_dtypes(include=['float64']))

針對上述的特征進行進一步的方差篩選。其中特征collections_12_mths_ex_med無法解釋/與研究目標無關,delinq_2yrs、acc_now_delinq很重要,其余特征無法判斷,先保留看看。
特征重要性
經過初步特征篩選后,我們發現相關系數因素有些單一,並不能確定哪個特征更為重要,更需要進行深度探索。經過搜索得知GBDT算法可以算出變量的重要性。因為lending club貸款數據中並不包含“分類”變量target,所以GBDT通用的特征選擇方法無法使用。
經過搜索找到了造好的輪子(取個巧),直接得到了算法計算后的結果,如下圖所示。

其中dti(借款人每月已還債務總額占總債務計算的比率)、bc_util(所有銀行卡賬戶的總流動余額與信貸限額/信用額度的比率)、mo_sin_old_rec_ti_op(自最早的周轉帳戶開立以來的月份)等特征較為重要。
Tip: 綜上結合相關系數與特征重要性,去掉無因果關系的、重要性較低的特征,我們得到如下的篩選后的特征。

可能大家會注意到在篩選特征的過程中只針對數值型特征進行篩選,那么Object類型的特征呢?
根據前面得到的信息,共有24個Object類型的特征,其中有大部分特征是貸款后的才有的信息,並不能決定貸款等級。而且,在查看特征重要性中已包括Object類型的特征,如home_ownership(房屋所有權狀態,包括租賃、擁有、貸款抵押三種類型的值),其余特征並不在考慮范圍內。
數據的前期處理部分就到這里了,下一篇文章將主要對數據進行可視化分析、結論總結等。其實大部分的工作都在數據處理部分,可視化占較少的一部分時間。處理好了數據對后續的工作有很大的影響。
附上在數據分析的過程中遇到的很好的參考資料,包括特征工程(包括對特征的處理、篩選等)、已有的成型的數據分析文章等。
1.機器學習特征選擇
4.相關性分析
- 數據可視化
- 結論
上一篇文章中,我們說到了如何處理數據,並且最后篩選出比較重要的一些特征。按道理來說,接下來我們應該對數據進行去重、歸一化、進行建模了。然而時間、精力有限,且與最終要研究的目的沒多大關系,所以這一部分並沒有進行深層研究。
接下來我們從數據可視化開始說起,探究潛藏在數據背后的信息。
五、數據可視化
首先我們來看一下2016年第一季度業務開展情況,主要是放款筆數,金額,期限等情況
perform_data = analysis_data.groupby('month')['loan_amnt'].agg(['count','sum'])#貸款筆數與放貸金額 f, (ax1, ax2) = plt.subplots(2, 1, sharex=True) x = perform_data.index #月份month y1 = perform_data['count']#貸款筆數 sns.barplot(x, y1, ax=ax1) y2 = perform_data['sum']#貸款金額 ax1.set_xlabel("") ax1.set_ylabel("loan_count") sns.barplot(x, y2,ax=ax2) ax2.set_ylabel("loan_amount") sns.despine(bottom=True)

可以看出,1月份至3月份的貸款筆數、貸款金額都在提升。

在同時,第一季度中不同等級的貸款數量都有所增長,其中F、G等級貸款繼續維持在一定的、較低的成交數量,而其他等級貸款的數量和漲幅都較為明顯。
通過兩個圖表我們對第一季度整體的業績有了一些了解,接下來我們將更具體的了解業務的內容,比如說貸款金額、貸款期限以及利率等。
from scipy.stats import norm #貸款金額分布 sns.distplot(analysis_data.loan_amnt,fit=norm,kde=False,color='blue') sns.despine(top=True)

單筆貸款金額在1萬~2萬美元范圍內占比較多,較高金額的貸款數量較少,也間接證明了lending club 主營小額度的貸款項目。
analysis_data.term.value_counts().plot.pie(autopct='%.2f',figsize=(10, 10),colors = ['yellowgreen','lightblue']) #借款周期分布比例

貸款周期分為36個月與60個月,主要以36個月為主,不過60個月的比重也不小。在p2p平台上以短期貸款為主,長期貸款也有,利率較高,但周期較長。借出人收獲利息,承擔風險,而借入人到期要償還本金。貸款周期越長,對借出人來說風險越高。
在國內的環境下,借出人不僅要承擔推遲還款的風險,還要擔心平台跑路、本息全無的高風險;對借入人來說,因為國內缺少健全的征信體系,借款方違約及重復違約成本低。
對國內的情況不再多說,話題繞回來。國外的部分國家已有健全的征信體系,一旦違約還款,違約率不斷上漲,個人征信也會保留記錄,對后序的貸款、買房有很大的影響。所以如果貸款周期較長,且如果沒有固定的工作和固定的收入的話(即使有未定收入也不一定如期償還),償還本金充滿變數,很有可能違約。
所以通過上圖可以看出幾個信息:
1.短期貸款占比重較大,長期貸款占比也不低
2.Lending club平台有較強的風控能力,部分借出方比較信任平台(不怕平台跑路),而借入方對自身的還款能力有一定的信心。
接下來我們再試着對貸款人進行分析,形成一下用戶畫像吧。

從圖中可以看出,貸款人中有37%的比例的人工齡為10年以上。那么,我們可以考慮一下,為什么工齡超過10年的人有貸款需求呢?且占比這么高?
那么可以猜測一下(個人意見),首先可能是工齡越長,貸款通過率越高(篩選后占比較高),其次可能有部分是工作超過10年但是被裁員的(經濟不好),有部分是還有工作但是需要還房貸的(不知道國外的形式),有部分是個人家庭有大筆支出的(個例,占比不大),當然不排除謊報工齡的可能。
至於猜測是否准確個人不能保證,還需要結合當年的經濟形勢,以及職業變動等情況進行綜合判斷,在此不再深究。
#貸款人收入水平 sns.factorplot(x="grade", y="annual_inc", hue="verification_status", data=lendData,order=list('ABCDEFG'),size=15,palette="Paired")

再來看看收入水平的情況。貸款人的收入水平信息分為三種情況:已經過LC驗證,收入來源已驗證,未驗證。這三種情況目前從圖中看不出有什么不同。總之,貸款等級與收入水平在整體上呈正相關的趨勢。
analysis_data.home_ownership.value_counts().plot.pie(autopct='%.2f',figsize=(10, 10),colors= ['red','yellowgreen','lightskyblue']) #借款人住房狀況分布

大多數人的房屋狀態是抵押貸款(大部分人是房奴),只有少部分人有完全的產權。
#貸款等級與住房情況 analysis_data_home = lendData.groupby(['grade','home_ownership'])[['issue_d']].count().apply(lambda x : x/x.sum(level=0)).unstack(level=1)\ .reset_index().set_index('grade')\ .stack(level=0).reset_index(level=1, drop=True) analysis_data_home.plot.barh(stacked=True,figsize=(15,8)).legend(loc='center left', bbox_to_anchor=(1, 0.5))

意外的發現,貸款等級越高的人群,他們的住房情況是抵押貸款的幾率越高,而租房的幾率越低。而擁有完全產權的人群在各個貸款等級的人群中占比差不多。
再來看看他們貸款都干什么了。
sns.countplot(y=analysis_data.purpose) #貸款用途分布 sns.despine(top=True)

可以很明顯的看出debt_consolidation(可以理解為債務整合,借新還舊)占比最高,占比第二高的credit_card也歸屬為同一類。

綜合收入水平與貸款用途得到上圖,我們可以發現在第一季度中,人均收入水平較高的人群貸款用於小生意,家庭生活改善,房子等。而貸款為了債務整合(占比最高)的人群的人均收入水平在整體的中下。
對貸款人群了解的也差不多了,接下來我們看一下資產質量。
如何定義資產質量呢?在這里可以狹義地理解為在一定時期、利率、期限結構下資產所能來帶的收益高低或損失可能,對於貸款來說,借款人償還本息的及時和足額程度、借款人的信用等級、貸款的利率和期限等等都影響到資產的質量。
不過要注意,通常我們認為借款人的還款觀察期最好是在6個月到12個月,因為在這個期限內,借款人還款的表現情況才逐漸趨於穩定。而計算第一季度的delinquent rate(拖欠率)是不具備代表性的,所以在這里就不對第一季度的整體Bad Rate(壞賬率)做進一步的分析了,而是着重觀察不同信用等級下的資產質量。
說實話,關於資產質量的這部分並沒有分析經驗,也是參考了一下大牛的文章引用過來的。文末會給出鏈接,對金融、p2p感興趣的可以自行學習。
回歸正題,既然資產質量與償還利息是否及時、借款人信用等級等等相關,那么就把這些信息整合起來,查看一下不同貸款等級的貸款質量。
在眾多特征中,有個特征變量loan_status(貸款狀態)來描述當前貸款處於什么狀態,其中包括Current、Fully Paid、Charged Off(注銷)、Default、In Grace Period(在寬限期)、Late (16-30 days)(延期16-30天) 、Late (31-120 days)(延期31-120天)這幾種狀態。
#將貸款狀態分為好與壞,好的貸款狀態就是current(在還款期),fully paid(全部償還),剩下的認為是壞的狀態 past_due = ['In Grace Period','Late (16-30 days)', 'Late (31-120 days)', 'Default','Charged Off'] delinquent = ['Late (16-30 days)', 'Late (31-120 days)', 'Default'] lost = ['Default'] charged_off = ['Charged Off'] analysis_data_1 = analysis_data.copy() analysis_data_1['loan_status'] = analysis_data_1['loan_status'].map(lambda x :'Past Due' if x in past_due else x) groupd_grade = analysis_data_1.groupby(['grade','loan_status']) pay_data_2 = groupd_grade.agg({'loan_amnt':'sum','out_prncp':'sum','total_rec_prncp':'sum','total_rec_int':'sum'}) \ .assign(loan_amnt_pct=lambda x : x['loan_amnt']/x.groupby(level=0)['loan_amnt'].sum(), out_prncp_pct=lambda x : x['out_prncp']/x.groupby(level=0)['out_prncp'].sum()) pay_data_2

接下來分別解釋一下特征的含義。total_rec_prncp(迄今收到的本金),
total_rec_int (迄今收到的利息),out_prncp (總資金中剩余的未償還本金),后兩列原數據集中沒有,分別代表當前貸款金額占該等級所有貸款金額的比例, 未償還本金金額占該等級所有未償還本金金額的比例。
我們可以看到,貸款狀態分成了三類,Past Due中包括的都是不好的貸款狀態,用來衡量貸款質量。
之后我們將Past Due(壞的狀態)單獨提取出來

f, (ax1, ax2) = plt.subplots(2, 1, sharex=True) x = past_due_data.index y1 = past_due_data['loan_amnt_pct'] sns.barplot(x, y1, ax=ax1) y2 = past_due_data['out_prncp_pct'] ax1.set_xlabel("") ax1.set_ylabel("loan_amnt_pct") #壞的狀態的貸款所占比例 sns.barplot(x, y2,ax=ax2) ax2.set_ylabel("past_due_rate") #未償還本金的貸款所占比例 sns.despine(bottom=True)

從圖中我們看出,貸款等級越高,貸款質量越高。A等級最好,G等級最差,也從側面看出Lending club的風控水平。
六、結論
通過數據可視化我們對2016年第一季度的數據已經有了一個整體的認識。那么我們最終要研究的問題是否已經找到答案了呢?回答是肯定的。在調查Lending club背景時,我們得到了模糊的線索。在進行數據預處理過程中,我們通過相關系數得到與貸款等級關系密切的特征,后續又通過數據可視化直觀的看到與貸款等級相關的因素。下面就做一下總結。
影響貸款等級的相關因素
1.首先通過背景了解到FICO分數,分數越高,貸款通過的可能性與等級也越高。

2.征信記錄。包括征信查詢、貸款人的不良信用記錄等。征信記錄很重要,並且占據較大的權重。因為過去的信用記錄反映的是這個人潛在的壞賬率,本來嘛LC必須要保障借出人與自身的利益。

3.資產實力。包括收入水平、住房情況、dti等。住房情況在重要性篩選過程中出現,收入水平在數據可視化過程中觀察到明顯的相關性。然而這些特征並不是主要的影響因素,權重較低。
通過上述的總結歸納,我們得知Lending club平台已經有了一個完整的篩選、評級體系,且有足夠的風控水平,通過對信息來源進行核實,以及控制低等級貸款的數量來維持整體貸款的水平,降低壞賬率。雖然現在Lending club的形勢不太樂觀,但在丑聞事件的打擊中它還是挺過來了。不論之后該公司如何發展,至少它成型的風控水平值得國內絕大多數p2p平台學習。
python金融風控評分卡模型和數據分析微專業課(博主親自錄制視頻):http://dwz.date/b9vv
歡迎關注博主主頁,學習python視頻資源,還有大量免費python經典文章
機器學習,統計項目可聯系QQ:231469242