https://www.jianshu.com/p/a8037a38e219(原文連接)html
https://www.jianshu.com/p/4b4e0c343d3e(原文連接)python
公司背景算法
Lending Club 創立於2006年,主營業務是爲市場提供P2P貸款的平臺中介服務,公司總部位於舊金山。segmentfault
公司在運營初期僅提供我的貸款服務,至2012年平臺貸款總額達10億美圓規模。bash
2014年12月,Lending Club在紐交所上市,成爲當年最大的科技股IPO。app
2014年後公司開始爲小企業提供商業貸款服務。機器學習
2015年整年Lending Club平臺新設貸款金額達到了83.6億美圓。ide
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 個等級,每一個等級又包含了一、二、三、四、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平臺學習。
https://study.163.com/course/courseMain.htm?courseId=1005988013&share=2&shareId=400000000398149
參考