零基礎入門金融風控之貸款違約預測—模型融合

sosososoon發表於2020-09-27

模型融合

模型融合的方式:

  • 平均
    • 簡單平均法
    • 加權平均法
  • 投票
    • 簡單投票法
    • 加權投票法
  • 綜合
    • 排序融合
    • log 融合
  • stacking
    構建多層模型,並利用預測結果再擬合預測。
  • blending
    選取部分資料預測訓練得到預測結果作為新特徵,帶入剩下的資料中預測。
  • boosting / bagging

stacking\blending

  • stacking 將若干基學習器獲得的預測結果,將預測結果作為新的訓練集來訓練一個學習器。首先直接用所有的訓練資料對第一層多個模型進行 K 折交叉驗證,這樣每個模型在訓練集上都有一個預測值,然後將這些預測值做為新特徵對第二層的模型進行訓練。

    在這裡插入圖片描述

  • blending 是將預測的值作為新的特徵和原特徵合併,構成新的特徵,用於預測。為了防止過擬合,將資料集分為 d1 和 d2 兩部分,使用 d1 作為訓練集,d2 作為測試集。第一層在 d1 上訓練多個模型,然後去預測 d2 的label。在第二層裡,直接用 d2 在第一層預測的結果做為新特徵繼續訓練。
     
    在這裡插入圖片描述

  • blending 與 stacking 的不同

    • 由於 stacking 兩層使用的資料不同,所以可以避免資訊洩露的問題
    • 由於 blending 將資料劃分為兩個部分,在最後預測時有部分資料資訊將被忽略
    • blending 第二層的資料較少可能產生過擬合現象

更多細節參見:
模型融合之stacking & blending

參考程式碼

平均

  • 簡單平均
pre = (pre1 + pre2 + pre3 +...+pren )/n
  • 加權平均
pre = w1*pre1 + w2*pre2 + w3*pre3 

投票

  • 簡單投票
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
 
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))
  • 加權投票
# 在VotingClassifier中加入引數 voting='soft', weights=[2, 1, 1],weights用於調節基模型的權重
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
 
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)], voting='soft', weights=[2, 1, 1])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))

stacking

import warnings
warnings.filterwarnings('ignore')
import itertools
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB 
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from mlxtend.plotting import plot_learning_curves
from mlxtend.plotting import plot_decision_regions


# 以python自帶的鳶尾花資料集為例
iris = datasets.load_iris()
X, y = iris.data[:, 1:3], iris.target


clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3], 
                          meta_classifier=lr)


label = ['KNN', 'Random Forest', 'Naive Bayes', 'Stacking Classifier']
clf_list = [clf1, clf2, clf3, sclf]
    
fig = plt.figure(figsize=(10,8))
gs = gridspec.GridSpec(2, 2)
grid = itertools.product([0,1],repeat=2)


clf_cv_mean = []
clf_cv_std = []
for clf, label, grd in zip(clf_list, label, grid):
        
    scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
    print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))
    clf_cv_mean.append(scores.mean())
    clf_cv_std.append(scores.std())
        
    clf.fit(X, y)
    ax = plt.subplot(gs[grd[0], grd[1]])
    fig = plot_decision_regions(X=X, y=y, clf=clf)
    plt.title(label)
 

plt.show()

在這裡插入圖片描述

blending

# 以python自帶的鳶尾花資料集為例
data_0 = iris.data
data = data_0[:100,:]


target_0 = iris.target
target = target_0[:100]
 
#模型融合中基學習器
clfs = [LogisticRegression(),
        RandomForestClassifier(),
        ExtraTreesClassifier(),
        GradientBoostingClassifier()]
 
#切分一部分資料作為測試集
X, X_predict, y, y_predict = train_test_split(data, target, test_size=0.3, random_state=914)


#切分訓練資料集為d1,d2兩部分
X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=914)
dataset_d1 = np.zeros((X_d2.shape[0], len(clfs)))
dataset_d2 = np.zeros((X_predict.shape[0], len(clfs)))
 
for j, clf in enumerate(clfs):
    #依次訓練各個單模型
    clf.fit(X_d1, y_d1)
    y_submission = clf.predict_proba(X_d2)[:, 1]
    dataset_d1[:, j] = y_submission
    #對於測試集,直接用這k個模型的預測值作為新的特徵。
    dataset_d2[:, j] = clf.predict_proba(X_predict)[:, 1]
    print("val auc Score: %f" % roc_auc_score(y_predict, dataset_d2[:, j]))


#融合使用的模型
clf = GradientBoostingClassifier()
clf.fit(dataset_d1, y_d2)
y_submission = clf.predict_proba(dataset_d2)[:, 1]
print("Val auc Score of Blending: %f" % (roc_auc_score(y_predict, y_submission)))

相關文章