Python銀行機器學(xué)習(xí):回歸、隨機森林、KNN近鄰、決策樹、高斯樸素貝葉斯、支持向量機s
原文鏈接:http://tecdat.cn/?p=26219?
原文出處:拓端數(shù)據(jù)部落公眾號
銀行數(shù)據(jù)集
我們的數(shù)據(jù)集描述
該數(shù)據(jù)與銀行機構(gòu)的直接營銷活動相關(guān),營銷活動基于電話。通常,需要與同一客戶的多個聯(lián)系人聯(lián)系,以便訪問產(chǎn)品(銀行定期存款)是否會(“是”)或不會(“否”)訂閱。
y - 客戶是否訂閱了定期存款?(二進(jìn)制:'是','否')
我們的目標(biāo)是選擇最好的回歸模型來讓客戶訂閱或不訂閱定期存款。我們將使用如下算法:
線性回歸
隨機森林回歸
KNN近鄰
決策樹
高斯樸素貝葉斯
支持向量機
選擇最佳模型的決定將基于:
準(zhǔn)確性
過采樣
數(shù)據(jù)準(zhǔn)備
在本節(jié)中,我們加載數(shù)據(jù)。我們的數(shù)據(jù)有 45211 個變量。
輸入變量:
銀行客戶數(shù)據(jù)
1 - 年齡(數(shù)字)
2 - 工作:工作類型(分類:'行政'、'藍(lán)領(lǐng)'、'企業(yè)家'、'女傭'、'管理'、'退休'、'自雇'、'服務(wù)'、'學(xué)生'、'技術(shù)員'、'失業(yè)'、'未知')
3 - 婚姻:婚姻狀況(分類:'離婚'、'已婚'、'單身'、'不詳';注:'離婚'指離婚或喪偶)。
4 - 教育(分類:'基礎(chǔ)4年'、'基礎(chǔ)6年'、'基礎(chǔ)9年'、'高中'、'文盲'、'專業(yè)課程'、'大學(xué)學(xué)位'、'未知')
5 - 違約:是否有違約的信貸?(分類: '沒有', '有', '未知')
6-住房:是否有住房貸款?(分類: '否', '是', '未知')
7 - 貸款:有個人貸款嗎?
8 - contact: 聯(lián)系通信類型(分類:'手機', '電話')。
9 - 月:最后一次聯(lián)系的年份月份(分類:'一月', '二月', '三月', ..., '十一月', '十二月')
10 - day_of_week:最后一次聯(lián)系的星期(分類:'mon', 'tue', 'wed', 'thu', 'fri')
11 - 持續(xù)時間:最后一次聯(lián)系的持續(xù)時間,以秒為單位(數(shù)字)。
12 - 活動:在這個活動期間為這個客戶進(jìn)行的接觸次數(shù)(數(shù)字,包括最后一次接觸)。
13 - pdays: 在上次活動中最后一次與客戶聯(lián)系后的天數(shù)(數(shù)字,999表示之前沒有與客戶聯(lián)系)。
14 - 以前:在這次活動之前,為這個客戶進(jìn)行的接觸次數(shù)(數(shù)字)。
15 - 結(jié)果:上次營銷活動的結(jié)果(分類:"失敗"、"不存在"、"成功")。
社會和經(jīng)濟背景屬性
16 - emp.var.rate:就業(yè)變化率--季度指標(biāo)(數(shù)值)。
17 - cons.price.idx:消費者價格指數(shù)--月度指標(biāo)(數(shù)值)。
18 - cons.conf.idx:消費者信心指數(shù)--月度指標(biāo)(數(shù)字)。
19 - euribor3m:銀行3個月利率--每日指標(biāo)(數(shù)值)
20 - nr.employed: 雇員人數(shù) - 季度指標(biāo)(數(shù)字)
輸出變量(所需目標(biāo)):
?y - ?客戶是否認(rèn)購了定期存款?(二進(jìn)制: '是', '否')
data.head(5)

我們的下一步是查看變量的形式以及是否存在缺失值的問題。
df1 = data.dtypes
df1

df2 = data.isnull().sum()
df2

我們的下一步是計算所有變量的值。
data['y'].value_counts()

data['job'].value_counts()

data['marital'].value_counts()

data['education'].value_counts()

data['housing'].value_counts()

data['loan'].value_counts()

data['contact'].value_counts()

data['month'].value_counts()

data['poutcome'].value_counts()

描述性統(tǒng)計
數(shù)值總結(jié)
data.head(5)

改變因變量 y 的值。代替 no - 0 和代替 yes - 1。
data['y'] = data['y'].map({'no': 0, 'yes': 1})
data.columns

對于我們的每個變量,我們繪制一個箱線圖來查看是否有任何可見的異常值。
plt.figure(figsize=[10,25])
ax = plt.subplot(611)
sns.boxplot(data['age'],orient="v")






我們可以看到許多可見的異常值,尤其是在 balance 、 campaign 、 pdays 的情況下。在?pdays ,我們可以看到很多變量都在分位數(shù)范圍之外。這個變量是一個特例,它被解碼為 -1,這就是我們的圖看起來像這樣的原因。在表示變量之前的箱線圖的情況下,它表示在此活動之前執(zhí)行的聯(lián)系數(shù)量,在這種情況下,我們還可以注意到許多超出分位數(shù)范圍的值。
直方圖
我們的下一步是查看連續(xù)變量的分布和直方圖
我們可以看到?jīng)]有一個變量具有正態(tài)分布。
plt.figure(figsize=[10,20])
plt.subplot(611)
g = sns.distplot(data["age"], color="r")
我們的下一步是查看因變量 y 與每個變量或連續(xù)變量之間的關(guān)系。
g = sns.FacetGrid(data, col='y',size=4)
g.map
從這些變量中我們可以得到的最有趣的觀察是,大多數(shù)說不的人年齡在20-40歲之間,在月底的第20天,大多數(shù)人也拒絕了這個提議。
?
分類總結(jié)
我們制作僅包含分類變量的數(shù)據(jù)子集,以便更輕松地繪制箱線圖
data_categorical = data[['job',
'marital',
'education',
'default', 'housing',
'loan','month', 'y']]
?

我們還查看了分類變量,看看是否有一些有趣的特征
從上面的條形圖中可以看出,最有趣的結(jié)果來自變量:婚姻狀況、教育和工作。
從代表婚姻狀況的圖表來看,大多數(shù)人都已婚。
正如我們在代表教育的圖表上看到的那樣 - 最大的是接受過中等教育的人數(shù)。
在約伯的情況下,我們可以看到大多數(shù)人都有藍(lán)領(lǐng)和管理工作。
我們還想在馬賽克圖上查看我們的分類變量與 y 變量之間的關(guān)系。
plt.rcParams['font.size'] = 16.0

正如我們所見,大多數(shù)人都拒絕了該提議。就地位而言,已婚的人說“不”最多。

在可變違約的情況下,大多數(shù)沒有違約信用的人也拒絕了該提案。

大多數(shù)有住房貸款的人也拒絕了該提議。

大多數(shù)沒有貸款的人拒絕了這個提議。
數(shù)據(jù)挖掘
data.head(5)

我們想更深入地研究我們的變量,看看我們是否可以用它們做更多的事情。
我們的下一步是使用 WOE 分析。
finv, IV = datars(data,data.y)
IV

基于對我們有用的 WOE 分析變量是:pdays、previous、job、housing、balance、month、duration、poutcome、contact。
在下一步中,我們決定根據(jù) WOE 結(jié)果和變量的先前結(jié)果刪除無用的列。
我們刪除的其中一個列是 poutcome,盡管它的 WOE 很高,但我們決定刪除它,因為從 prevois 分析中我們看到它有許多未知的觀察結(jié)果。
在可變持續(xù)時間的情況下,我們也可以看到WOE相當(dāng)大,甚至可以說這個結(jié)果有點可疑。我們決定根據(jù) WOE 結(jié)果放棄它,因為我們的模型應(yīng)該根據(jù)過去的數(shù)據(jù)說明是否建議給某個人打電話。
在可變接觸的情況下,我們放棄了它,因為對我們來說,接觸形式在我們的模型中沒有用。
我們還刪除了變量 day 因為它對我們沒有用,因為這個變量代表天數(shù),而該變量的 WOE 非常小。我們刪除的最后一個變量是變量 pdays,盡管這個變量 WOE 的結(jié)果非常好,但它對我們來說并不是一個有用的變量。
我們分析中剩下的列:
?

特征選擇和工程
要執(zhí)行我們的算法,我們首先需要將字符串更改為二進(jìn)制變量。
data = pd.get_dummies(data=data, columns = ['job', 'marital', 'education' , 'month'], \
prefix = ['job', 'marital', 'education' , 'month'])

我們更改了列的名稱。
data.head(5)

創(chuàng)建虛擬變量后,我們進(jìn)行了 Pearson 相關(guān)。
age = pearsonr(data['age'], data['y'])

sns.heatmap(corr

我們選擇了數(shù)字列來檢查相關(guān)性。正如我們所看到的,沒有相關(guān)性。
我們查看因變量和連續(xù)變量之間的關(guān)系。
pylab.show()

交叉驗證
經(jīng)過所有準(zhǔn)備工作,我們終于可以將數(shù)據(jù)集拆分為訓(xùn)練集和測試集。
算法的實現(xiàn)
邏輯回歸
K=5
kf = KFold(n_splits=K, shuffle=True)
logreg = LogisticRegression()


[[7919 ? 81] [ 956 ? 86]]


[[7952 ? 60] [ 971 ? 59]]


[[7871 ? 82] [1024 ? 65]]

[[7923 ? 69] [ 975 ? 75]]
決策樹
dt2 = tree.DecisionTreeClassifier(random_state=1, max_depth=2)
[[7986 ? ?0] [1056 ? ?0]]
[[7920 ? 30] [1061 ? 31]]
[[8021 ? ?0] [1021 ? ?0]]
[[7938 ? 39] [1039 ? 26]]
隨機森林
random_forest = RandomForestClassifier
[[7825 ?183] [ 870 ?164]]


[[7774 ?184] [ 915 ?169]]


[[7770 ?177] [ 912 ?183]]


[[7818 ?196] [ 866 ?162]]


KNN近鄰
classifier = KNeighborsClassifier(n_neighbors =13,metric = 'minkowski' , p=2)
print("Mean accuracy: ",accuracyknn/K)
print("The best AUC: ", bestaucknn)


[[7987 ? 30] [1010 ? 15]]


[[7989 ? 23] [1017 ? 13]]


[[7920 ? 22] [1083 ? 17]]


[[7948 ? 21] [1052 ? 21]]


高斯樸素貝葉斯
kf = KFold(n_splits=K, shuffle=True)
gaussian = GaussianNB()

[[7321 ?633] [ 699 ?389]]
[[7291 ?672] [ 693 ?386]]
[[7300 ?659] [ 714 ?369]]
[[7327 ?689] [ 682 ?344]]
models = pd.DataFrame({
'Model': ['KNN', 'Logistic Regression',
'Naive Bayes', 'Decision Tree','Random Forest'],
'Score': [ accuracyknn/K, accuracylogreg/K,
accuracygnb/K, accuracydt/K, accuracyrf/K],
'BestAUC': [bestaucknn,bestauclogreg,bestaucgnb,
bestaucdt,bestaucrf]})
我們看到根據(jù) AUC 值的最佳模型是樸素貝葉斯我們不應(yīng)該太在意最低的 R2 分?jǐn)?shù),因為數(shù)據(jù)非常不平衡(很容易預(yù)測 y=0)。在混淆矩陣中,我們看到它預(yù)測了漂亮的價值真正值和負(fù)值。令我們驚訝的是,決策樹的 AUC 約為 50%。
欠采樣
我們嘗試對變量 y=0 進(jìn)行欠采樣
gTrain, gValid = train_test_split
邏輯回歸
predsTrain = logreg.predict(gTrainUrandom)
predsTrain = logreg.predict(gTrain20Urandom)
predsTrain = logreg.predict(gTrrandom)
決策樹
print("Train AUC:", metrics.roc_auc_score(ygTrds))

隨機森林
print("Train AUC:", metrics.roc_auc_score(ygTr, predsTrain),
"Valid AUC:", metrics.roc_auc_score(ygVd, preds))

KNN近鄰
print("Train AUC:", metrics.roc_auc_score(ygTrm, predsTrain),
"Valid AUC:", metrics.roc_auc_score(ygVal10, preds))

高斯樸素貝葉斯
print("Train AUC:", metrics.roc_auc_score(ygTraom, predsTrain),
"Valid AUC:", metrics.roc_auc_score(ygid, preds))

過采樣
我們嘗試對變量 y=1 進(jìn)行過采樣
feates = datolist()
print(feures)
feaes.remove('y')

print(gTrainOSM.shape)
smt = SMOT
(32345, 39)smt = SMOT
(32595, 39)ygTrain10OSM=gTrain10OSM['y']
gTrain10OSM=gTrain10OSM.drop(columns=['y'])
邏輯回歸
print("Train AUC:", metrics.roc_auc_score(ygTrin10SM, predsTrain),
"Valid AUC:", metrics.roc_auc_score(ygValid, preds))

決策樹
dt2.fit(,ygTranOS)
predsTrain = dtpreict(TrainOSM)
preds = dt2.predict(gValid)

隨機森林
random_forest.fit(rainOSM, ygTranOS)
predsTrain = random_forest.prect(gTraiOSM)
p

KNN近鄰
classifier.fit(granOSM, yTanOSM)
predsTrain = classifier.predict(gTaiSM)
preds = classifier.predict(Vaid)

高斯樸素貝葉斯
gaussian.fit(gTriOM, ygrainM)
predsTrain = gaussian.predcti)

結(jié)論
我們看到欠采樣和過采樣變量 y 對 AUC 沒有太大幫助。

最受歡迎的見解
1.從決策樹模型看員工為什么離職
2.R語言基于樹的方法:決策樹,隨機森林
3.python中使用scikit-learn和pandas決策樹
4.機器學(xué)習(xí):在SAS中運行隨機森林?jǐn)?shù)據(jù)分析報告
5.R語言用隨機森林和文本挖掘提高航空公司客戶滿意度
6.機器學(xué)習(xí)助推快時尚精準(zhǔn)銷售時間序列
7.用機器學(xué)習(xí)識別不斷變化的股市狀況——隱馬爾可夫模型的應(yīng)用
8.python機器學(xué)習(xí):推薦系統(tǒng)實現(xiàn)(以矩陣分解來協(xié)同過濾)
9.python中用pytorch機器學(xué)習(xí)分類預(yù)測銀行客戶流失