日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

疯狂的机器学习实战-银行营销预测

發(fā)布時間:2024/2/28 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 疯狂的机器学习实战-银行营销预测 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

機(jī)器學(xué)習(xí)實戰(zhàn)-銀行營銷預(yù)測

問題:
數(shù)據(jù)集:
鏈接:https://pan.baidu.com/s/1TUOLr8jFbT38p_iUh1iBsQ
提取碼:1234

銀行營銷數(shù)據(jù)集 這些數(shù)據(jù)與葡萄牙銀行機(jī)構(gòu)的直接營銷活動有關(guān)。這些直接營銷活動是以電話為基礎(chǔ)的。通常來說,銀行機(jī)構(gòu)的客服人員至少需要聯(lián)系一次客戶來得知客戶是否將認(rèn)購銀行的產(chǎn)品(定期存款)。因此,與該數(shù)據(jù)集對應(yīng)的任務(wù)是分類任務(wù),而分類目標(biāo)是預(yù)測客戶是(yes)(no)認(rèn)購定期存款(變量y)。 數(shù)據(jù)集包含四個csv文件: 1) bank-additional-full.csv: 包含所有的樣例(41188)和所有的特征輸入(20),根據(jù)時間排序(從20085月到20109月); 2) bank-additional.csv:1)中隨機(jī)選出10%的樣例(4119)3) bank-full.csv: 包含所有的樣例(41188)17個特征輸入,根據(jù)時間排序。(該數(shù)據(jù)集是更老的版本,特征輸入較少); 4) bank.csv:3)中隨機(jī)選出10%的樣例(4119)。數(shù)據(jù)集的輸入變量是20個特征量,分為數(shù)值變量(numeric)和分類(categorical)變量, 輸出變量為y,即客戶是否已經(jīng)認(rèn)購定期存款(binary: "yes", "no")

策略:使用四個模型先粗測當(dāng)前預(yù)測準(zhǔn)確度,對其中準(zhǔn)確度較高的進(jìn)一步調(diào)優(yōu)

算法簡單介紹:
1.KNN算法
通過以某個數(shù)據(jù)為中心:
? 分析離其最近的K個鄰居的類別;
? 獲得該數(shù)據(jù)可能的類別
? 如果取K=1
? 待分類樣本的類別就是最近鄰居的類
2.SVM算法
SVM(Support Vector Machine)中文名為支持向量機(jī),是常見的一種判別方法。在機(jī)器學(xué)習(xí)領(lǐng)域,是一個有監(jiān)督的學(xué)習(xí)模型,通常用來進(jìn)行模式識別、分類以及回歸分析。
二維上,就是找一分割線W?X+b =0把兩類分開,區(qū)分兩個類別并且能使間隔(margin)最大
3.AdaBoost算法
該算法其實是一個簡單的弱分類算法提升過程,這個過程通過不斷的訓(xùn)練,可以提高對數(shù)據(jù)的分類能力。1. 先通過對N個訓(xùn)練樣本的學(xué)習(xí)得到第一個弱分類器;
2. 將分錯的樣本和其他的新數(shù)據(jù)一起構(gòu)成一個新的N個的訓(xùn)練樣本,通過對這個樣本的學(xué)習(xí)得到第二個弱分類器 ;
3. 將1和2都分錯了的樣本加上其他的新樣本構(gòu)成另一個新的N個的訓(xùn)練樣本,通過對這個樣本的學(xué)習(xí)得到第三個弱分類器;
4. 最后,將各個訓(xùn)練得到的弱分類器組合成強(qiáng)分類器。誤差率低的弱分類器在最終分類器中占的比例較大,反之較小。
4.隨機(jī)森林算法
隨機(jī)森林顧名思義,是用隨機(jī)的方式建立一個森林,森林里面有很多的決策樹組成,隨機(jī)森林的每一棵決策樹之間是沒有關(guān)聯(lián)的。在得到森林之后,當(dāng)有一個新的輸入樣本進(jìn)入的時候,就讓森林中的每一棵決策樹分別進(jìn)行一下判斷,看看這個樣本應(yīng)該屬于哪一類(對于分類算法),然后看看哪一類被選擇最多,就預(yù)測這個樣本為那一類。

完整代碼見最后:

1.導(dǎo)入數(shù)據(jù)

#訓(xùn)練集和測試集的導(dǎo)入 trainfile = pd.read_csv(r'.\bank-additional-full.csv', sep=';') testfile = pd.read_csv(r'.\bank-additional.csv', sep=';')

2.數(shù)據(jù)處理:

  • 缺失值處理:
  • 1.判斷有無顯示的缺失值(為空值的部分) 2.判斷有無隱含缺失值(分析發(fā)現(xiàn)存在很多unknown項) 3.統(tǒng)計每個特征值unknown項數(shù) 4.處理:對unknown項少的使用眾數(shù)替換和行刪除判斷可行性(前后對比準(zhǔn)確率) 對unknown項比較多的(unknown行數(shù)超過總體數(shù)據(jù)集的30%)使用刪除列處理 #判斷數(shù)據(jù)是否讀入完整 print(data.shape) #判斷是否存在缺失數(shù)據(jù)(空值): data.info()

    for col in trainfile.columns:if type(trainfile[col][0]) is str:print('unknown value count in'+col+':'+str(trainfile[trainfile[col]=='unknown']['y'].count()))


    下面驗證對于該數(shù)據(jù)集缺失較多的列刪除后的可行性:

    #刪除unknown大于30%的列 for col in csvfile.columns:if type(csvfile[col][0]) is str:num=csvfile[csvfile[col]=='unknown'][col].count()if num/len(csvfile)>0.3:csvfile.drop(col,axis=1,inplace=True)

    刪除前的4個算法準(zhǔn)確率:
    刪除后的4個算法準(zhǔn)確率:

    (決策樹應(yīng)該改為隨機(jī)森林)

    下面驗證對該數(shù)據(jù)集缺失數(shù)據(jù)替換或者刪除的可行性探究:

    #刪除unknown大于30%的列 for col in csvfile.columns:if type(csvfile[col][0]) is str:if 'unknown' in csvfile[col].tolist():col_mode=csvfile[col].mode()[0]csvfile[col].replace('unkonwn',col_mode,inplace=True)

    替換前:

    替換后:

    # 刪除含有'unknown'的行for index, row in csvfile.iterrows():if ('unknown' in row.values):csvfile.drop([index], inplace=True)

    刪除前:

    刪除后:

    這里我們采取的最高準(zhǔn)確性比較所以選擇的刪除行

    **

    3.特征分析

    **

    1. 分析特征:
    通過分析個特征的數(shù)據(jù)選取其中差異化較大的特征作為最后我們用于模型訓(xùn)練的特征使用
    部分情況如下:



    比如這里的contact分布情況就相差很大所以我們這里就要選擇其作為之后模型訓(xùn)練的一個特征值使用

    比如這里的day_of_week其對結(jié)果數(shù)據(jù)的差異化就不明顯所以不需要選擇其作為最后模型訓(xùn)練的特征值

    2. 特征工程:
    1.對以上選擇的特征值進(jìn)行數(shù)值化編碼(方便處理數(shù)據(jù))
    2.離散化處理,處理數(shù)據(jù)中的極大極小值
    3.對選取特征標(biāo)準(zhǔn)化或者歸一化處理(作用:使得數(shù)據(jù)具有同等重要的作用,特別是在按距離分類的算法如K近鄰算法d=sqrt((a-b)^2…)如果不做歸一化或者標(biāo)準(zhǔn)化處理,如果此時a值較大,b值較小則最后可能對結(jié)果有同等重要性的數(shù)據(jù)只有一個被用上了,因為在距離函數(shù)中a大則其對結(jié)果數(shù)據(jù)起主導(dǎo)作用,b對結(jié)果的影響非常的小,甚至可以忽略。這種情況下,分類的特征就變少了,使得預(yù)測結(jié)果不準(zhǔn)確。(我們要的應(yīng)該是對于那些對結(jié)果數(shù)據(jù)差異化明顯的數(shù)據(jù)盡可能的加入,這樣的預(yù)測準(zhǔn)確率才高)
    4.樣本均衡

    具體過程如下:
    1.二分變量數(shù)值化:

    2.將其它分類變量(包括有序和無序)數(shù)值化

    3.數(shù)據(jù)離散化:
    把無限空間中有限的個體映射到有限的空間中去,以此提高算法的時空效率。
    通俗的說,離散化是在不改變數(shù)據(jù)相對大小的條件下,對數(shù)據(jù)進(jìn)行相應(yīng)的縮小。

    4.數(shù)據(jù)標(biāo)準(zhǔn)化:
    標(biāo)準(zhǔn)化數(shù)據(jù)通過減去均值然后除以方差(或標(biāo)準(zhǔn)差),這種數(shù)據(jù)標(biāo)準(zhǔn)化方法經(jīng)過處理后數(shù)據(jù)符合標(biāo)準(zhǔn)正態(tài)分布,即均值為0,標(biāo)準(zhǔn)差為1,轉(zhuǎn)化函數(shù)為:x =(x - 均值)/方差

    預(yù)處理結(jié)果:

    4.4個模型的簡單測試


    綜上結(jié)果可知:在默認(rèn)值參數(shù)下KNN算法是最優(yōu)的,正確率是最高的。

    5.選擇當(dāng)前最優(yōu)模型并對其調(diào)優(yōu)


    距離參數(shù)通過手動調(diào)整發(fā)現(xiàn)曼哈頓距離最好,對于K值的選擇我們使用for循環(huán)進(jìn)行的查找(本來想使用二分,但是考慮到其不是順序的所以就直接使用的線性查找)
    另外其實這里取K=1時是最大的準(zhǔn)確率在98%,但這其實是因為:
    K值較小就意味著整體模型變得復(fù)雜,容易發(fā)生過擬合
    K值較大就意味著整體模型變得簡單,容易發(fā)生欠擬合
    最終結(jié)果:

    最后我們?nèi)〉腒值為3

    6.對未來的展望:

    優(yōu)點:
    1、通過多種分類模型對比,使我們對題目了解跟全面,結(jié)構(gòu)更清晰,準(zhǔn)確度更高
    2、精度高、對異常值不敏感、無數(shù)據(jù)輸入假定。
    缺點:
    1、對部分屬性進(jìn)行了直接刪除,忽略了數(shù)據(jù)相關(guān)性對結(jié)果的影響;
    2、對部分非有序變量采用直接轉(zhuǎn)變?yōu)閿?shù)字的做法,使變量值之間的權(quán)重不相同;
    展望:
    1、更細(xì)致的特征選擇,如派生屬性;
    2、采用更好的方法解決數(shù)據(jù)不平衡問題,如:代價敏感學(xué)習(xí)方法;
    3、更細(xì)致的調(diào)參;
    4、長視其他分類模型,如:神經(jīng)網(wǎng)絡(luò)等
    5、因為前面是選擇的當(dāng)前最優(yōu)算法,所以可能存在其他三個算法調(diào)優(yōu)之后其準(zhǔn)確度更高的情況。之后可以繼續(xù)嘗試其他算法調(diào)參后的準(zhǔn)確度

    完整代碼:

    import pandas as pd#訓(xùn)練集和測試集的導(dǎo)入 trainfile = pd.read_csv(r'.\bank-additional-full.csv', sep=';') testfile = pd.read_csv(r'.\bank-additional.csv', sep=';')# 數(shù)據(jù)預(yù)處理 def Pretreatment(csvfile):# 刪除'poutcome'-nonexistent占比超過80%csvfile.drop(['poutcome'], axis=1, inplace=True)# 刪除unknown大于30%的列for col in csvfile.columns:if (type(csvfile[col][0])) is str:#只有str類型才有‘unknown’項num = csvfile[csvfile[col] == 'unknown'][col].count()if (num / len(csvfile) > 0.3):csvfile.drop(col, axis=1, inplace=True)# 刪除含有'unknown'的行for index, row in csvfile.iterrows():if ('unknown' in row.values):csvfile.drop([index], inplace=True)# 替換unknown為每列的眾數(shù)# for col in csvfile.columns.tolist():# if (type(csvfile[col][0])) is str:# if ('unknown' in csvfile[col].tolist()):# col_mode = csvfile[col].mode()[0]# csvfile[col].replace('unknown', col_mode, inplace=True)# 分類變量數(shù)值化csvfile.replace(['yes', 'no'], [1, 0], True) # 替換yes,no為1,0;csvfile['nr.employed'].replace([5191.0, 5228.1], [0, 1], True) # 替換nr.employed列元素為0,1;educationlist = ["illiterate", "basic.4y", "basic.6y", "basic.9y", "high.school", "professional.course","university.degree"]educationvalue = [i for i in range(0, len(educationlist))]joblist = ["admin.", "blue-collar", "entrepreneur", "housemaid", "management", "retired", "self-employed","services", "student", "technician", "unemployed"]jobvalue = [i for i in range(0, len(joblist))]maritallist = ["divorced", "married", "single"]maritalvalue = [i for i in range(0, len(maritallist))]contactlist = ["cellular", "telephone"]contactvalue = [0, 1]monthlist = ['month_apr', 'month_aug', 'month_dec', 'month_jul', 'month_jun', 'month_mar', 'month_may', 'month_nov','month_oct', 'month_sep']monthvalue = [i for i in range(0, len(monthlist))]day_of_weeklist = ['day_of_week_fri', 'day_of_week_mon', 'day_of_week_thu', 'day_of_week_tue', 'day_of_week_wed']day_of_weekvalue = [i for i in range(0, len(day_of_weeklist))]csvfile['day_of_week'].replace(day_of_weeklist, day_of_weekvalue, True)csvfile['month'].replace(monthlist, monthvalue, True)csvfile['contact'].replace(contactlist, contactvalue, True)csvfile['job'].replace(joblist, jobvalue, True)csvfile['marital'].replace(maritallist, maritalvalue, True)csvfile['education'].replace(educationlist, educationvalue, True)# # 離散化處理數(shù)據(jù)# csvfile['age']=pd.qcut(csvfile['age'],10)# csvfile['age']=pd.factorize(csvfile['age'])[0]# csvfile['duration']=pd.qcut(csvfile['duration'],10)# csvfile['duration']=pd.factorize(csvfile['duration'])[0]# csvfile['campaign']=pd.qcut(csvfile['campaign'],5,duplicates='drop')# csvfile['campaign']=pd.factorize(csvfile['campaign'])[0]# csvfile['pdays'] = pd.qcut(csvfile['pdays'], 10, duplicates='drop')# csvfile['pdays'] = pd.factorize(csvfile['pdays'])[0]return csvfiledata = Pretreatment(trainfile) data_test = Pretreatment(testfile) #特征對結(jié)果影響分析 # import matplotlib.pyplot as plt # import seaborn as sns # plt.rcParams['font.sans-serif'] = 'SimHei' # plt.figure(figsize=(20, 8), dpi=256) # sns.countplot(x='age', data=data) # plt.title("各年齡段的人數(shù)") # plt.savefig('./1.png') # # plt.figure(figsize=(18, 16), dpi=512) # plt.subplot(221) # sns.countplot(x='contact', data=data) # plt.title("contact分布情況") # # plt.subplot(222) # sns.countplot(x='day_of_week', data=data) # plt.title("day_of_week分布情況") # # # plt.subplot(223)#前面刪列時將其刪除了所以就不需要再分析它了 # # sns.countplot(x='default', data=data) # # plt.title("default分布情況") # # plt.subplot(224) # sns.countplot(x='education', data=data) # plt.xticks(rotation=70) # plt.title("education分布情況") # # plt.savefig('./2.png') # # plt.figure(figsize=(18, 16), dpi=512) # plt.subplot(221) # sns.countplot(x='housing', data=data) # plt.title("housing分布情況") # # plt.subplot(222) # sns.countplot(x='job', data=data) # plt.xticks(rotation=70) # plt.title("job分布情況") # # plt.subplot(223) # sns.countplot(x='loan', data=data) # plt.title("loan分布情況") # # plt.subplot(224) # sns.countplot(x='marital', data=data) # plt.xticks(rotation=70) # plt.title("marital分布情況") # # plt.savefig('./3.png') # # plt.figure(figsize=(18, 8), dpi=512) # plt.subplot(221) # sns.countplot(x='month', data=data) # plt.xticks(rotation=30) # # plt.subplot(222) # sns.countplot(x='poutcome', data=data) # plt.xticks(rotation=30) # plt.savefig('./4.png') # # plt.figure(figsize=(10, 8), dpi=256) # plt.rcParams['axes.unicode_minus'] = False # sns.heatmap(data.corr(), annot=True) # plt.title("各特征的相關(guān)性") # plt.savefig('./5.png') # plt.show()#圖像顯示 from sklearn.preprocessing import LabelEncoderfeatures = ['age','job', 'marital', 'education', 'housing', 'loan', 'contact', 'month', 'duration','campaign', 'pdays', 'previous', 'emp.var.rate', 'cons.price.idx', 'cons.conf.idx', 'euribor3m', 'nr.employed']le_x = LabelEncoder() for feature in features:data[feature] = le_x.fit_transform(data[feature])data_test[feature] = le_x.fit_transform(data_test[feature])col = data.columns.values.tolist()# 數(shù)據(jù)規(guī)范化到正態(tài)分布的數(shù)據(jù) from sklearn.preprocessing import StandardScaler import numpy as npss = StandardScaler() train_x=np.array(data[col[0:-2]]) train_y=data['y']test_x=np.array(data_test[col[0:-2]]) test_y=data_test['y']train_x = ss.fit_transform(train_x) test_x = ss.transform(test_x)from sklearn.ensemble import AdaBoostClassifier from sklearn.metrics import accuracy_score ada = AdaBoostClassifier() ada.fit(train_x, train_y) predict_y = ada.predict(test_x) print("Adaoost準(zhǔn)確率:", accuracy_score(test_y, predict_y))#引入支持向量機(jī)算法 from sklearn.svm import SVC svc = SVC() svc.fit(train_x, train_y) predict_y = svc.predict(test_x) print("svm準(zhǔn)確率:", accuracy_score(test_y, predict_y)) # ans.append(accuracy_score(test_y, predict_y)) # #引入Knn算法 from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score knn = KNeighborsClassifier() knn.fit(train_x, train_y) predict_y = knn.predict(test_x) print("KNN準(zhǔn)確率:", accuracy_score(test_y, predict_y)) from sklearn.tree import DecisionTreeClassifier dtc = DecisionTreeClassifier() dtc.fit(train_x, train_y) predict_y = dtc.predict(test_x) print("隨機(jī)森林準(zhǔn)確率:", accuracy_score(test_y, predict_y))print("由此得KNN算法為當(dāng)前4個算法的最優(yōu)算法,所以我們對KNN算法進(jìn)行進(jìn)一步的調(diào)參,過程如下:")max=0 max_index=1 for i in range(2,30,1):# print(i)knn = KNeighborsClassifier(p=1,n_neighbors=i)#選擇的曼哈頓距離knn.fit(train_x, train_y)predict_y = knn.predict(test_x)KNN2=accuracy_score(test_y, predict_y)if KNN2>max:max=KNN2max_index=iprint("KNN準(zhǔn)確率:", accuracy_score(test_y, predict_y)) print("最優(yōu)k值為:") print(max_index) print("最優(yōu)準(zhǔn)確率:") print(max)

    瘋狂之處在于這個只用了兩天來做 (ó﹏ò。)

    總結(jié)

    以上是生活随笔為你收集整理的疯狂的机器学习实战-银行营销预测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。