2020廈門國際銀行數創金融杯建模大賽baseline分享
成績:0.34
比賽地址:https://www.dcjingsai.com/v2/cmptDetail.html?id=439&=76f6724e6fa9455a9b5ef44402c08653&ssoLoginpToken=&sso_global_session=e44c4d57-cd19-4ada-a1d3-a5250252bf86&sso_session=irjO90jPA0%205ytlVRkI1fA%3D%3D
賽題背景
在數字金融時代,大資料、人工智能技術在銀行業內的發展日新月異,業內各機構都在加速數字化轉型發展,廈門國際銀行作為有特色的科技領先型中小銀行,多年來始終堅持發揮數字金融科技力量,踐行“數字賦能”理念,持續推進智慧風控、智慧營銷、智慧運營、智慧管理,運用人工智能和大資料分析技術建立智能化客戶服務模式和金融智慧營銷服務體系,提升營銷程序的智慧化、精準化水平,在為客戶提供更貼心更具可用性的金融服務,
? 廈門國際銀行聯合廈門大學資料挖掘研究中心,為搭建一個行業交流平臺,與社會各界精英共同探索機器學習和人工智能等熱門技術問題,攜手DataCastle資料城堡共同舉辦“2020第二屆廈門國際銀行“數創金融杯”建模大賽“,本屆大賽以“金融+科技”為理念,著力于金融營銷中的真實場景,總獎金達31萬元,
任務
隨著科技發展,銀行陸續打造了線上線下、豐富多樣的客戶觸點,來滿足客戶日常業務辦理、渠道交易等客戶需求,面對著大量的客戶,銀行需要更全面、準確地洞察客戶需求,在實際業務開展程序中,需要發掘客戶流失情況,對客戶的資金變動情況預判;提前/及時針對客戶進行營銷,減少銀行資金流失,本次競賽提供實際業務場景中的客戶行為和資產資訊為建模物件,一方面希望能借此展現各參賽選手的資料挖掘實戰能力,另一方面需要選手在復賽中結合建模的結果提出相應的營銷解決方案,充分體現資料分析的價值,
Label說明
label -1 下降
label 0 維穩
label 1 提升
官方說明
客戶貢獻度主要和客戶的aum值有關
評價函式KAPPA
Kappa系數是一個用于一致性檢驗的指標,也可以用于衡量分類的效果,因為對于分類問題,所謂一致性就是模型預測結果和實際分類結果是否一致,kappa系數的計算是基于混淆矩陣的,取值為-1到1之間,通常大于0,
基于混淆矩陣的kappa系數計算公式如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kP1yqr6Y-1604027964570)(https://www.zhihu.com/equation?tex=kappa+%3D+%5Cfrac%7Bp_o-p_e%7D%7B1-p_e%7D+)]
其中:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EZJSQjE6-1604027964572)(https://www.zhihu.com/equation?tex=p_o+%3D+%5Cfrac+%7B%E5%AF%B9%E8%A7%92%E7%BA%BF%E5%85%83%E7%B4%A0%E4%B9%8B%E5%92%8C%7D%7B%E6%95%B4%E4%B8%AA%E7%9F%A9%E9%98%B5%E5%85%83%E7%B4%A0%E4%B9%8B%E5%92%8C%7D)] ,其實就是acc,
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Oddrpc4s-1604027964573)(https://www.zhihu.com/equation?tex=p_e+%3D+%5Cfrac%7B%5Csum_%7Bi%7D%7B%E7%AC%ACi%E8%A1%8C%E5%85%83%E7%B4%A0%E4%B9%8B%E5%92%8C+%2A+%E7%AC%ACi%E5%88%97%E5%85%83%E7%B4%A0%E4%B9%8B%E5%92%8C%7D%7D%7B%28%5Csum%7B%E7%9F%A9%E9%98%B5%E6%89%80%E6%9C%89%E5%85%83%E7%B4%A0%7D%29%5E2%7D+)] ,即所有類別分別對應的“實際與預測數量的乘積”,之總和,除以“樣本總數的平方”,
具體可以參考這個網址:
https://zhuanlan.zhihu.com/p/67844308
資料介紹
參考比賽網址,任務與資料
方案
在觀察資料后發現,每個季度的最后一個月都有B6,B7,B8,而對于測驗集,他的最后一個月的cust_no包含了絕大部分cust_no,要預測客戶未來的情況走向,采用的是最后一個季度的情況進行預測,其中以下三個cust_no經過合并特征后丟失了,前兩個月的合并后也一樣丟失了:[‘0xb2d0afb2’, ‘0xb2d2ed87’, ‘0xb2d2d9d2’],這里先把他們的label都設為0.丟掉了含有NAN的列,
#沒找到這三個cust_no,摸獎,
low=pd.DataFrame()
low['cust_no']=['0xb2d0afb2', '0xb2d2ed87', '0xb2d2d9d2']
low['label']=[0,0,0]
基礎特征
目前并沒有做什么特征,只是簡單的對I3,I8,I12進行了encoder,然后以I3進行分組訓練(客戶等級),其它的就是全梭哈,
le = LabelEncoder()
train_B7['I3'] = le.fit_transform(train_B7['I3'].astype(str))
test_B7['I3'] = le.transform(test_B7['I3'].astype(str))
le = LabelEncoder()
train_B7['I8'] = le.fit_transform(train_B7['I8'].astype(str))
test_B7['I8'] = le.transform(test_B7['I8'].astype(str))
le = LabelEncoder()
train_B7['I12'] = le.fit_transform(train_B7['I12'].astype(str))
test_B7['I12'] = le.transform(test_B7['I12'].astype(str))
predictionsB4 = pd.DataFrame()
predictionsB7 = pd.DataFrame()
scoresB7 = list()
for eve_id in tqdm(test_B7.I3.unique()):
prediction,score= run_lgb_id(train_B7, test_B7, target='label', eve_id=eve_id)
predictionsB7=predictionsB7.append(prediction)
scoresB7.append(score)
采用的資料
對訓練集,只采用了9月份,12月份的資料,測驗集也采用的是3月份資料
# 1.讀取檔案:
train_label_3=pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_label\y_Q3_3.csv')
train_label_4 = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_label\y_Q4_3.csv')
train_3 = pd.DataFrame()
train_4 = pd.DataFrame()
id3_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cust_avli_Q3.csv')
id4_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cust_avli_Q4.csv')
#合并有效客戶的label
train_label_3 = pd.merge(left=id3_data, right=train_label_3, how='inner', on='cust_no')
train_label_4 = pd.merge(left=id4_data, right=train_label_4, how='inner', on='cust_no')
#合并個人資訊
inf3_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cust_info_q3.csv')
inf4_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cust_info_q4.csv')
train_label_3 = pd.merge(left=inf3_data, right=train_label_3, how='inner', on='cust_no')
train_label_4 = pd.merge(left=inf4_data, right=train_label_4, how='inner', on='cust_no')
#第3季度資訊提取
for i in range(9,10):
aum_3=pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\aum_m'+str(i)+'.csv')
be_3 = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\behavior_m' + str(i) + '.csv')
cun_3 = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cunkuan_m' + str(i) + '.csv')
fre_3=pd.merge(left=aum_3,right=be_3,how='inner', on='cust_no')
fre_3=pd.merge(left=fre_3,right=cun_3,how='inner', on='cust_no')
train_3=train_3.append(fre_3)
train_fe3=pd.merge(left=fre_3,right=train_label_3,how='inner', on='cust_no')
train_fe3.to_csv(r'E:\For_test2-10\data\廈門_data\train_feature\train3_fe_B7.csv',index=None)
#第4季度資訊提取
for i in range(12,13):
aum_4=pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\aum_m'+str(i)+'.csv')
be_4 = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\behavior_m' + str(i) + '.csv')
cun_4 = pd.read_csv(r'E:\For_test2-10\data\廈門_data\train_feature\cunkuan_m' + str(i) + '.csv')
fre_4=pd.merge(left=aum_4,right=be_4,how='inner', on='cust_no')
fre_4=pd.merge(left=fre_4,right=cun_4,how='inner', on='cust_no')
train_3=train_3.append(fre_4)
train_fe4=pd.merge(left=fre_4,right=train_label_4,how='inner', on='cust_no')
train_fe4.to_csv(r'E:\For_test2-10\data\廈門_data\train_feature\train4_fe_B7.csv',index=None)
train_B7=[train_fe3,train_fe4]
train_B7=pd.concat(train_B7)
test = pd.DataFrame()
idtest_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\test_feature\cust_avli_Q1.csv')
inftest_data = pd.read_csv(r'E:\For_test2-10\data\廈門_data\test_feature\cust_info_q1.csv')
test_inf = pd.merge(left=inftest_data, right=idtest_data, how='inner', on='cust_no')
# 第3季度資訊提取
for i in range(3, 4):
aum = pd.read_csv(r'E:\For_test2-10\data\廈門_data\test_feature\aum_m' + str(i) + '.csv')
be = pd.read_csv(r'E:\For_test2-10\data\廈門_data\test_feature\behavior_m' + str(i) + '.csv')
cun = pd.read_csv(r'E:\For_test2-10\data\廈門_data\test_feature\cunkuan_m' + str(i) + '.csv')
fre = pd.merge(left=aum, right=be, how='inner', on='cust_no')
fre = pd.merge(left=fre, right=cun, how='inner', on='cust_no')
test = test.append(fre)
test_fe = pd.merge(left=test, right=test_inf, how='inner', on='cust_no')
test_fe.to_csv(r'E:\For_test2-10\data\廈門_data\train_feature\test_fe_B7.csv', index=None)
test_B7=test_fe.dropna(axis=1, how='any')
train_B7=train_B7.dropna(axis=1, how='any')
模型
采用的是LGB模型,5折交叉驗證
def run_lgb_id(df_train, df_test, target, eve_id):
feature_names = list(
filter(lambda x: x not in ['label','cust_no'], df_train.columns))
# 提取 eve_ID 對應的資料集
df_train = df_train[df_train.I3 == eve_id]
df_test = df_test[df_test.I3 == eve_id]
model = lgb.LGBMRegressor(num_leaves=32,
max_depth=6,
learning_rate=0.08,
n_estimators=10000,
subsample=0.9,
feature_fraction=0.8,
reg_alpha=0.5,
reg_lambda=0.8,
random_state=2020)
oof = []
prediction = df_test[['cust_no']]
prediction[target] = 0
kfold = KFold(n_splits=5, random_state=2020)
for fold_id, (trn_idx, val_idx) in enumerate(kfold.split(df_train, df_train[target])):
X_train = df_train.iloc[trn_idx][feature_names]
Y_train = df_train.iloc[trn_idx][target]
X_val = df_train.iloc[val_idx][feature_names]
Y_val = df_train.iloc[val_idx][target]
lgb_model = model.fit(X_train,
Y_train,
eval_names=['train', 'valid'],
eval_set=[(X_train, Y_train), (X_val, Y_val)],
verbose=0,
eval_metric='mse',
early_stopping_rounds=20,
)
pred_val = lgb_model.predict(X_val, num_iteration=lgb_model.best_iteration_)
df_oof = df_train.iloc[val_idx][[target, 'cust_no']].copy()
df_oof['pred'] = pred_val
oof.append(df_oof)
pred_test = lgb_model.predict(df_test[feature_names], num_iteration=lgb_model.best_iteration_)
prediction[target] += pred_test / kfold.n_splits
del lgb_model, pred_val, pred_test, X_train, Y_train, X_val, Y_val
gc.collect()
df_oof = pd.concat(oof)
score = mean_squared_error(df_oof[target], df_oof['pred'])
print('MSE:', score)
return prediction,score
最后采用的是MSE作為線下評價指標
大佬們可以修改一下
可能合并特征的時候把cust_no merge掉了哈哈
線上:0.34左右
代碼很大程度上借鑒了恒佬分享的baseline
第一次分享baseline 不喜勿噴
謝謝大家
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/197069.html
標籤:其他
上一篇:排序
下一篇:ELK日志檔案分析系統、Logstash、ElasticSearch和Kiabana三個開源工具組成(實體部署程序)
