如果分類問題中類別型的因變量可能嚴(yán)重失衡础浮,例如欺詐問題中礼华,欺詐類觀測在樣本集中占少數(shù)勺馆;客戶流失問題中戏售,忠實的客戶也是往往占很少一部分;某營銷活動的響應(yīng)過程中草穆,真正參與的客戶也同樣只是少部分灌灾。
如果數(shù)據(jù)存在嚴(yán)重的不平衡,預(yù)測得出的結(jié)論也是有偏的悲柱,即分類結(jié)果會偏向于較多觀測的類锋喜,一般構(gòu)造1:1的數(shù)據(jù),要么將多的那一類砍掉一部分(欠采樣)豌鸡,要么將少的那一類進(jìn)行Bootstrap抽樣(過采樣)嘿般,前者會丟失隱含信息,后者會形成簡單復(fù)制涯冠,使模型產(chǎn)生過擬合炉奴。
對于不平衡類的分類器評價,使用ROC和AUC作為評價分類器的指標(biāo)
2002年Chawla提出了SMOTE算法蛇更,即合成少數(shù)過采樣技術(shù)瞻赶,是目前處理不平衡數(shù)據(jù)的常用手段,對少數(shù)類別樣本進(jìn)行分析模擬派任,并將人工模擬的新樣本添加到數(shù)據(jù)集中砸逊,進(jìn)而使類別不再失衡。利用KNN技術(shù)掌逛,合成的策略是對每個少數(shù)類樣本a师逸,從它的最近鄰中隨機(jī)選一個樣本b,然后在a豆混、b之間的連線上隨機(jī)選一點作為新合成的少數(shù)類樣本篓像。
XGBoost是Gradient Boosting的一種高效系統(tǒng)實現(xiàn)动知,并不是一種單一算法。xgboos也是以(CART)為基學(xué)習(xí)器的GB算法遗淳,但是擴(kuò)展和改進(jìn)了GDBT拍柒。相比GBDT的優(yōu)點有:
(1)xgboost在代價函數(shù)里自帶加入了正則項,用于控制模型的復(fù)雜度屈暗。
(2)xgboost在進(jìn)行節(jié)點的分裂時,支持各個特征多線程進(jìn)行增益計算脂男,因此算法更快养叛,準(zhǔn)確率也相對高一些。
XGBoost里面的基學(xué)習(xí)器除了支持CART基礎(chǔ)模型宰翅,也可用線性分類器(gblinear)弃甥。而GBDT則特指梯度提升決策樹算法。另外不同于GBDT使用一階導(dǎo)汁讼,XGBoost可以支持不同的損失函數(shù)(用戶可以自定義)淆攻,來優(yōu)化效果,只要函數(shù)一嘿架、二階可導(dǎo)即可瓶珊。除此之外,支持并行運(yùn)算耸彪,提高運(yùn)行效率伞芹;在損失函數(shù)中加了正則項,用來控制模型復(fù)雜度蝉娜,防止過擬合唱较;采用了隨機(jī)森林的思想,對字段進(jìn)行抽樣召川,可以防止過擬合南缓,也可以降低模型計算量。
有別于隨機(jī)森林集成荧呐,還有提升算法AdaBoost汉形,梯度提升算法GBDT,升級版的梯度算法XGBoost,坛增。
AdaBoost在解決分類問題時获雕,是通過改變樣本點的權(quán)重大小,并將各個基礎(chǔ)模型按權(quán)重實現(xiàn)線性組合收捣,最終得到擬合數(shù)據(jù)的提升樹届案;在解決預(yù)測問題時,每一輪基礎(chǔ)模型都是擬合上一輪模型所形成的殘差罢艾,最終將各個基礎(chǔ)模型的預(yù)測值相加楣颠。
不管是分類提升樹尽纽,還是回歸提升樹,都是將各個基礎(chǔ)模型以串聯(lián)的形式構(gòu)成最終的提升樹童漩。
在回歸提升樹中弄贿,如果損失函數(shù)使用的是平方損失或者指數(shù)損失,目標(biāo)函數(shù)的求解會相對簡單矫膨,為了能夠使提升樹試用于更多類型的損失函數(shù)差凹,衍生出GBDT,即利用損失函數(shù)的導(dǎo)函數(shù)作為殘差的近似值侧馅,方便了運(yùn)算也提高了提升樹的靈活性危尿。
AdaBoost和GBDT在構(gòu)建目標(biāo)函數(shù)時都沒有加入反映模型復(fù)雜度的正則項,而XGBoost算法實現(xiàn)了正則化的加入馁痴,進(jìn)而可以防止模型的過擬合谊娇,并在求解最優(yōu)化問題時利用了損失函數(shù)的一階導(dǎo)和二階導(dǎo)。還可以支持并行計算罗晕,支持線性的基礎(chǔ)模型济欢,支持建模字段的隨機(jī)選擇等。
# 讀入數(shù)據(jù)
creditcard = pd.read_csv(r'F:\creditcard.csv')
creditcard.head()
因變量Class表示用戶在交易中是否存在欺詐行為(1表示欺詐小渊,0表示不欺詐)已對原始數(shù)據(jù)做了主成分分析處理法褥,只有2個沒有做(Time交易時間間隔和Amount交易金額)。
# 為確保繪制的餅圖為圓形粤铭,需執(zhí)行如下代碼
plt.axes(aspect = 'equal')
# 統(tǒng)計交易是否為欺詐的頻數(shù)
counts = creditcard.Class.value_counts()
# 繪制餅圖
plt.pie(x = counts, # 繪圖數(shù)據(jù)
labels=pd.Series(counts.index).map({0:'正常',1:'欺詐'}), # 添加文字標(biāo)簽
autopct='%.2f%%' # 設(shè)置百分比的格式挖胃,這里保留一位小數(shù)
)
# 顯示圖形
plt.show()
比例嚴(yán)重不平衡,先用SMOTE算法轉(zhuǎn)換
# 將數(shù)據(jù)拆分為訓(xùn)練集和測試集
# 刪除自變量中的Time變量
X = creditcard.drop(['Time','Class'], axis = 1)
y = creditcard.Class
# 數(shù)據(jù)拆分
X_train,X_test,y_train,y_test = model_selection.train_test_split(X,y,test_size = 0.3, random_state = 1234)
# 導(dǎo)入第三方包
from imblearn.over_sampling import SMOTE
# 運(yùn)用SMOTE算法實現(xiàn)訓(xùn)練數(shù)據(jù)集的平衡
over_samples = SMOTE(random_state=1234)
over_samples_X,over_samples_y = over_samples.fit_sample(X_train, y_train)
#over_samples_X, over_samples_y = over_samples.fit_sample(X_train.values,y_train.values.ravel())
# 重抽樣前的類別比例
print(y_train.value_counts()/len(y_train))
# 重抽樣后的類別比例
print(pd.Series(over_samples_y).value_counts()/len(over_samples_y))
類別比例達(dá)到平衡梆惯,構(gòu)建XGBoost模型(版本受限酱鸭,XGBoost模塊未下載成功,結(jié)果未運(yùn)行)
# 導(dǎo)入第三方包
import xgboost
import numpy as np
# 構(gòu)建XGBoost分類器
xgboost = xgboost.XGBClassifier()
# 使用重抽樣后的數(shù)據(jù)垛吗,對其建模
xgboost.fit(over_samples_X,over_samples_y)
# 將模型運(yùn)用到測試數(shù)據(jù)集中
resample_pred = xgboost.predict(np.array(X_test))
# 返回模型的預(yù)測效果
print('模型的準(zhǔn)確率為:\n',metrics.accuracy_score(y_test, resample_pred))
print('模型的評估報告:\n',metrics.classification_report(y_test, resample_pred))
模型的預(yù)測準(zhǔn)確率超過99%凹髓,而且模型對欺詐交易的覆蓋率高達(dá)88%(正確預(yù)測為欺詐的交易量/實際為欺詐的交易量),對正常交易的覆蓋率高達(dá)99%怯屉,以上為默認(rèn)參數(shù)蔚舀,還可以利用交叉驗證獲得更加參數(shù)組合,下面運(yùn)用ROC曲線驗證模型在測試集上的表現(xiàn)
# 計算欺詐交易的概率值锨络,用于生成ROC曲線的數(shù)據(jù)
y_score = xgboost.predict_proba(np.array(X_test))[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 計算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 繪制面積圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加邊際線
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加對角線
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x軸與y軸標(biāo)簽
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 顯示圖形
plt.show()
面積AUC高達(dá)0.98赌躺,擬合效果非常優(yōu)秀
為了體現(xiàn)SMOTE算法在非平衡數(shù)據(jù)上的價值,利用XGBoost算法直接在非平衡數(shù)據(jù)上建模羡儿,比較差異
# 構(gòu)建XGBoost分類器
xgboost2 = xgboost.XGBClassifier()
# 使用非平衡的訓(xùn)練數(shù)據(jù)集擬合模型
xgboost2.fit(X_train,y_train)
# 基于擬合的模型對測試數(shù)據(jù)集進(jìn)行預(yù)測
pred2 = xgboost2.predict(X_test)
# 混淆矩陣
pd.crosstab(pred2,y_test)
# 返回模型的預(yù)測效果
print('模型的準(zhǔn)確率為:\n',metrics.accuracy_score(y_test, pred2))
print('模型的評估報告:\n',metrics.classification_report(y_test, pred2))
準(zhǔn)確率高達(dá)100%礼患,但是是由于數(shù)據(jù)的不平衡性,導(dǎo)致結(jié)果的有偏
基于非平衡數(shù)據(jù),也繪制ROC曲線缅叠,通過比對AUC的值悄泥,對比兩個模型的好壞
# 計算欺詐交易的概率值,用于生成ROC曲線的數(shù)據(jù)
y_score = xgboost2.predict_proba(X_test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(y_test, y_score)
# 計算AUC的值
roc_auc = metrics.auc(fpr,tpr)
# 繪制面積圖
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
# 添加邊際線
plt.plot(fpr, tpr, color='black', lw = 1)
# 添加對角線
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
# 添加文本信息
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
# 添加x軸與y軸標(biāo)簽
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 顯示圖形
plt.show()
AUC的值為0.97肤粱,相比平衡數(shù)據(jù)所構(gòu)建的模型弹囚,AUC值要小0.1,進(jìn)而驗證了利用SMOTE算法實現(xiàn)數(shù)據(jù)的平衡是有必要的领曼,通過平衡數(shù)據(jù)鸥鹉,可以獲得更加穩(wěn)定和更具泛化能力的模型。