文章目錄
1.招商銀行2020FinTech精英訓練營數據賽道比賽簡介
一、賽題背景
在當今大數據時代,信用評分不僅僅用在辦理信用卡、貸款等金融場景,類似的評分產品已經觸及到我們生活的方方面面,比如借充電寶免押金、打車先用後付等,甚至在招聘、婚戀場景都有一席之地。
招行作爲金融科技的先行者,APP月活用戶數上億,APP服務不僅涵蓋資金交易、理財、信貸等金融場景,也延伸到飯票、影票、出行、資訊等非金融場景,可以構建用戶的信用評分,基於信用評分爲用戶提供更優質便捷的服務。
二、課題研究要求
本次大賽爲參賽選手提供了兩個數據集(訓練數據集和評分數據集),包含用戶標籤數據、過去60天的交易行爲數據、過去30天的APP行爲數據。希望參賽選手基於訓練數據集,通過有效的特徵提取,構建信用違約預測模型,並將模型應用在評分數據集上,輸出評分數據集中每個用戶的違約概率。
三、評價指標
AUC:AUC的全名是Area Under Curve,
AUC的介紹
AUC的定義很複雜:分別隨機從政府樣本集中抽取一個正負樣本,正樣本的預測值大於負樣本的概率。
簡單來說就是就是ROC曲線下的面積,理論最小值爲0.5。
我們先來看看混淆矩陣:
混淆矩陣中有着TN、FP、FN、TP的概念,其意義如下:
True negative(TN),稱爲真陰率,表明實際是負樣本預測成負樣本的樣本數。
False positive(FP),稱爲假陽率,表明實際是負樣本預測成正樣本的樣本數。
False negative(FN),稱爲假陰率,表明實際是正樣本預測成負樣本的樣本數。
True positive(TP),稱爲真陽率,表明實際是正樣本預測成正樣本的樣本數。
然後看看混淆矩陣:
由此引出True Positive Rate(真陽率)、False Positive(僞陽率)兩個概念:
ROC就可以登場了:ROC曲線的橫軸是FPRate,縱軸是TPRate,當二者相等時,即y=x,如下圖。
所以說,AUC就說希望儘可能提高1樣本的分類準確率,對於本題來說就是要儘可能找去信用不好的用戶。
如果大家有興趣多瞭解一下,推薦大家一個知天易or逆天難的博客:https://blog.csdn.net/u013019431/article/details/93138953
四、數據說明
1.訓練數據集_tag.csv,評分數據集_tag.csv提供了訓練數據集和評分數據集的用戶標籤數據;
2.訓練數據集_trd.csv,評分數據集_trd.csv提供了訓練數據集和評分數據集的用戶60天交易行爲數據;
3.訓練數據集_beh.csv,評分數據集_ beh.csv提供了訓練數據集和評分數據集的用戶30天APP行爲數據;
4.數據說明.xlsx爲數據集字段說明和數據示例;
5.提交樣例:
5.1採⽤UTF-8⽆BOM編碼的txt⽂件提交,⼀共提交⼀份txt⽂件。
5.2輸出評分數據集中每個用戶違約的預測概率,輸出字段爲:用戶標識和違約預測概率,用\t分割,每個用戶的預測結果爲一行,注意不能有遺漏的數據或多出的數據。
2.數據處理部分
1.對用戶標籤數據的處理
確失數據
首先查看我們的數據,發現有很三列缺失值挺多,建議不要。
然後是對於那些\N和~的亂數據,
這些數據我也把它們當成了確失數據,個人猜測可能是用戶填寫的時候不小心按了回車鍵吧。
那麼這裏怎麼處理呢,我用到了隨機森林填充的方法,這種方法適用於幾個個特徵大量數據缺失,其他特徵卻很完整的情況。
首先找到我們完整的列,即不含空值也不含那些亂七八糟的數據的列。
然後找到那些不完整的列,由於發現有三列是字母型的列,先刪除他們,之後再處理
接下來定義我們的隨機森林替換函數,並使用
from sklearn.ensemble import RandomForestRegressor
def add_wrong(df,col):
process_df = df.loc[:,(col,'age','l6mon_daim_aum_cd','bk1_cur_year_mon_avg_agn_amt_cd','pl_crd_lmt_cd','perm_crd_lmt_cd','cur_debit_cnt','cur_credit_cnt','cur_debit_min_opn_dt_cnt','cur_credit_min_opn_dt_cnt','cur_debit_crd_lvl')]
#僅選取部分列,
#f分成已知特徵值和位置特徵值兩部分
know = process_df.loc[(process_df[col]!='\\N') & (process_df[col]!='~')].as_matrix()
unknow = process_df.loc[(process_df[col]=='\\N') | (process_df[col]=='~')].as_matrix()
Y = know[:,0]
X = know[:,1:]
rfr = RandomForestRegressor(random_state = 0, n_estimators=200, max_depth=3, n_jobs = -1)
rfr.fit(X,Y)
predicted = rfr.predict(unknow[:,1:])
df.loc[(df[col]=='\\N') | (df[col]=='~'),col] = predicted
return df
for col in a:
add_wrong(data_tag,col)
好了,現在來處理那些字母型的屬性
如何把字母型的變成數字型的我的另一篇文章也說到了三種改變數據類型的方法,這裏就看一下代碼,提一下,這裏會把A、B、0以外的數據變成空值。
class_mapping = {label: idx for idx, label in [[0,'A'],[1,'B'],[2,'O'],[3,'Z']]}
data_tag['mrg_situ_cd'] = data_tag['mrg_situ_cd'].map(class_mapping)
data_tag.mrg_situ_cd.value_counts()
最後,同樣用隨機森林來填補一下缺失值就好啦
from sklearn.ensemble import RandomForestRegressor
def add_missing(df,col):
process_df = df.loc[:,(col,'age','l6mon_daim_aum_cd','bk1_cur_year_mon_avg_agn_amt_cd','pl_crd_lmt_cd','perm_crd_lmt_cd','cur_debit_cnt','cur_credit_cnt','cur_debit_min_opn_dt_cnt','cur_credit_min_opn_dt_cnt','cur_debit_crd_lvl')]
#僅選取部分列,
#f分成已知特徵值和位置特徵值兩部分
know = process_df[process_df[col].notnull()].as_matrix()
unknow = process_df[process_df[col].isnull()].as_matrix()
Y = know[:,0]
X = know[:,1:]
rfr = RandomForestRegressor(random_state = 0, n_estimators=200, max_depth=3, n_jobs = -1)
rfr.fit(X,Y)
predicted = rfr.predict(unknow[:,1:])
df.loc[df[col].isnull(), col] = predicted
return df
2.對用戶交易數據的處理——按周統計
考慮到銀行的很多業務都是按周開展的,所以我按周來統計了一些信息,怎麼按周統計或是按月統計,我的這篇文章也總結了,
首先就是把時間格式化並變成索引:
data_trd['trx_tm'] = pd.to_datetime(data_trd['trx_tm']) #將數據類型轉換爲日期類型
data_trd = data_trd.set_index('trx_tm') # 將date設置爲index
1.按周統計收入和支出和對應次數
data_trd_group = data_trd.groupby(['id','Dat_Flg1_Cd']).resample('w').sum()
data_trd_group_weekly_amt_iao=data_trd_group.pivot_table (index ='id' , columns= ['trx_tm','Dat_Flg1_Cd'],values='cny_trx_amt' ,aggfunc='sum') .fillna(0)
結果是這個樣子的:
data_trd_group_times = data_trd.groupby(['id','Dat_Flg1_Cd']).resample('w').count()
data_trd_group_times.drop(['id','Dat_Flg1_Cd'], axis=1, inplace=True)
data_trd_group_weekly_times_iao=data_trd_group_times.pivot_table (index ='id' , columns= ['trx_tm','Dat_Flg1_Cd'],values='cny_trx_amt' ,aggfunc='sum') .fillna(0)
2按周統計各支付方式的次數、金額以及每種支付方式的佔比
類似於1
3.統計每週每個人收支一級分類爲1、2、3的次數和金額
類似於1
3.對用戶APP行爲的處理
這部分數據沒用,能力有限,不好意思。
4.數據融合
就是將tag表和交易表合在一起,我用的是並集合並,缺失值填充爲-10.
3.建模調參部分
lightgbm模型
LightGBM是個快速的,分佈式的,高性能的基於決策樹算法的梯度提升框架。可用於排序,分類,迴歸以及很多其他的機器學習任務中。2017年1月,微軟發佈首個穩定版LightGBM,對於一個新的算法,大家都習慣和以前的算法進行對比,反正只需知道一件事:LightGBM牛逼就行了。
在不同數據集上的對比
計算速度的對比,完成相同的訓練量XGBoost通常耗費的時間是LightGBM的數倍之上,在higgs數據集上,它們的差距更是達到了15倍以上。
LightGBM的具體情況,可以看我轉載的一篇大佬博客:
https://blog.csdn.net/lamusique/article/details/95631638
本題中的調參:看了調參教程,發現用了之後對我的幫助真的好小,除了耽誤我的時間當然,可能別的情況下調參會很有用。
給大家提供一個初始值,然後自己嘗試一下改改bagging_fraction、feature_fraction、learning_rate、max_depth、num_leaves這些值就差不多了,
params = {
'boosting_type': 'gbdt','objective':'binary','num_leaves':15,'n_estimators':20000, 'early_stopping_rounds':5000,
'learning_rate':0.01, 'max_depth':6,
'metric':'auc',
'bagging_fraction':0.8, 'feature_fraction': 0.7, # 樣本採樣\特徵採用率
'reg_alpha':0.5, 'reg_lambda': 0.3
}
值得一提的是,如何拆分測試集和驗證集呢,這裏用到了sklearn裏的train_test_split方法:
# 訓練集、驗證集、測試集的劃分
import lightgbm as lgb
from sklearn.cross_validation import train_test_split
X_train, X_valid, y_train, y_valid = train_test_split(data[:-4000].drop(['flag'], axis=1), data[:-4000]['flag'],test_size=4000,random_state=2)
y_train = y_train.ravel()
train_data = lgb.Dataset(X_train, y_train) # 將數據保存到LightGBM二進制文件將使加載更快
valid_data = lgb.Dataset(X_valid, y_valid)
X_test = data[-4000:].drop(['flag'], axis=1)
好啦,以上就是本人第一次參加數據分析類比賽的小小心得,希望對你有點幫助。如果覺得我寫的好的話,求收藏求點贊求關注。