Python深度學(xué)習(xí)簡明實戰(zhàn)教程來了搏存。別猶豫了瑰步,趕緊從零開始,搭建你自己的第一個深度學(xué)習(xí)模型吧璧眠!
想不想了解如何用Python快速搭建深度神經(jīng)網(wǎng)絡(luò)缩焦,完成數(shù)據(jù)分類任務(wù)?本文一步步為你展示這一過程责静,讓你初步領(lǐng)略深度學(xué)習(xí)模型的強(qiáng)大和易用袁滥。
煩惱
作為一名數(shù)據(jù)分析師,你來到這家跨國銀行工作已經(jīng)半年了灾螃。
今天上午题翻,老板把你叫到辦公室,面色凝重腰鬼。
你心里直打鼓嵌赠,以為自己捅了什么簍子。幸好老板的話讓你很快打消了顧慮熄赡。
他發(fā)愁姜挺,是因為最近歐洲區(qū)的客戶流失嚴(yán)重,許多客戶都跑到了競爭對手那里接受服務(wù)了彼硫。老板問你該怎么辦炊豪?
你脫口而出“做好客戶關(guān)系管理啊拧篮!”
老板看了你一眼溜在,緩慢地說“我們想知道哪些客戶最可能在近期流失”。
沒錯他托,在有魚的地方釣魚掖肋,才是上策。
你明白了自己的任務(wù)——通過數(shù)據(jù)鎖定即將流失的客戶赏参。這個工作志笼,確實是你這個數(shù)據(jù)分析師分內(nèi)的事兒沿盅。
你很慶幸,這半年做了很多的數(shù)據(jù)動態(tài)采集和整理工作纫溃,使得你手頭就有一個比較完備的客戶數(shù)據(jù)集腰涧。
下面你需要做的,就是如何從數(shù)據(jù)中“沙里淘金”紊浩,找到那些最可能流失的客戶窖铡。
可是,該怎么做呢坊谁?
你拿出歐洲區(qū)客戶的數(shù)據(jù)费彼,端詳起來。
客戶主要分布在法國口芍、德國和西班牙箍铲。
你手里掌握的信息,包括他們的年齡鬓椭、性別颠猴、信用、辦卡信息等小染∏涛停客戶是否已流失的信息在最后一列(Exited)。
怎么用這些數(shù)據(jù)來判斷顧客是否會流失呢裤翩?
以你的專業(yè)素養(yǎng)春畔,很容易就判斷出這是一個分類問題,屬于機(jī)器學(xué)習(xí)中的監(jiān)督式學(xué)習(xí)岛都。但是,你之前并沒有做過實際項目振峻,該如何著手呢臼疫?
別發(fā)愁,我一步步給你演示如何用Python和深度神經(jīng)網(wǎng)絡(luò)(或者叫“深度學(xué)習(xí)”)來完成這個分類任務(wù)扣孟,幫你鎖定那些即將流失的客戶烫堤。
環(huán)境
工欲善其事,必先利其器凤价。我們先來安裝和搭建環(huán)境鸽斟。
首先是安裝Python。
請到這個網(wǎng)址下載Anaconda的最新版本利诺。
請選擇左側(cè)的Python 3.6版本下載安裝富蓄。
其次是新建文件夾,起名為demo-customer-churn-ann慢逾,并且從這個鏈接下載數(shù)據(jù)立倍,放到該文件夾下灭红。
(注:樣例數(shù)據(jù)來自于匿名化處理后的真實數(shù)據(jù)集,下載自superdatascience官網(wǎng)口注。)
打開終端(或者命令行工具)变擒,進(jìn)入demo-customer-churn-ann目錄,執(zhí)行以下命令:
jupyter notebook
瀏覽器中會顯示如下界面:
點擊界面右上方的New按鈕寝志,新建一個Python 3 Notebook娇斑,起名為customer-churn-ann。
準(zhǔn)備工作結(jié)束材部,下面我們開始清理數(shù)據(jù)悔醋。
清理
首先账阻,讀入數(shù)據(jù)清理最常用的pandas和numpy包。
import numpy as np
import pandas as pd
從customer_churn.csv
里讀入數(shù)據(jù):
df = pd.read_csv('customer_churn.csv')
看看讀入效果如何:
df.head()
這里我們使用了head()
函數(shù),只顯示前5行巢音。
可以看到棘脐,數(shù)據(jù)完整無誤讀入榛了。但是并非所有的列都對我們預(yù)測用戶流失有作用曙强。我們一一甄別一下:
- RowNumber:行號,這個肯定沒用刃麸,刪除
- CustomerID:用戶編號智政,這個是順序發(fā)放的间校,刪除
- Surname:用戶姓名揭绑,對流失沒有影響,刪除
- CreditScore:信用分?jǐn)?shù)陈惰,這個很重要畦徘,保留
- Geography:用戶所在國家/地區(qū),這個有影響抬闯,保留
- Gender:用戶性別井辆,可能有影響,保留
- Age:年齡溶握,影響很大杯缺,年輕人更容易切換銀行,保留
- Tenure:當(dāng)了本銀行多少年用戶睡榆,很重要萍肆,保留
- Balance:存貸款情況,很重要胀屿,保留
- NumOfProducts:使用產(chǎn)品數(shù)量塘揣,很重要,保留
- HasCrCard:是否有本行信用卡宿崭,很重要亲铡,保留
- IsActiveMember:是否活躍用戶,很重要,保留
- EstimatedSalary:估計收入奖蔓,很重要赞草,保留
- Exited:是否已流失,這將作為我們的標(biāo)簽數(shù)據(jù)
上述數(shù)據(jù)列甄別過程吆鹤,就叫做“特征工程”(Feature Engineering)厨疙,這是機(jī)器學(xué)習(xí)里面最常用的數(shù)據(jù)預(yù)處理方法。如果我們的數(shù)據(jù)量足夠大檀头,機(jī)器學(xué)習(xí)模型足夠復(fù)雜轰异,是可以跳過這一步的。但是由于我們的數(shù)據(jù)只有10000條暑始,還需要手動篩選特征搭独。
選定了特征之后,我們來生成特征矩陣X廊镜,把剛才我們決定保留的特征都寫進(jìn)來牙肝。
X = df.loc[:,['CreditScore', 'Geography', 'Gender', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'HasCrCard', 'IsActiveMember', 'EstimatedSalary']]
看看特征矩陣的前幾行:
X.head()
顯示結(jié)果如下:
2017-11-19_19-2-2_snapshots-01.jpg
特征矩陣構(gòu)建準(zhǔn)確無誤,下面我們構(gòu)建目標(biāo)數(shù)據(jù)y嗤朴,也就是用戶是否流失配椭。
y = df.Exited
y.head()
0 1
1 0
2 1
3 0
4 0
Name: Exited, dtype: int64
此時我們需要的數(shù)據(jù)基本上齊全了。但是我們發(fā)現(xiàn)其中有幾列數(shù)據(jù)還不符合我們的要求雹姊。
要做機(jī)器學(xué)習(xí)股缸,只能給機(jī)器提供數(shù)值,而不能是字符串吱雏《匾觯可是看看我們的特征矩陣:
X.head()
2017-11-19_19-2-2_snapshots-01.jpg
顯然其中的Geography和Gender兩項數(shù)據(jù)都不符合要求。它們都是分類數(shù)據(jù)歧杏。我們需要做轉(zhuǎn)換镰惦,把它們變成數(shù)值。
在Scikit-learn工具包里面犬绒,專門提供了方便的工具LabelEncoder
旺入,讓我們可以方便地將類別信息變成數(shù)值。
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder1 = LabelEncoder()
X.Geography= labelencoder1.fit_transform(X.Geography)
labelencoder2 = LabelEncoder()
X.Gender = labelencoder2.fit_transform(X.Gender)
我們需要轉(zhuǎn)換兩列凯力,所以建立了兩個不同的labelencoder茵瘾。轉(zhuǎn)換的函數(shù)叫做fit_transform
。
經(jīng)過轉(zhuǎn)換咐鹤,此時我們再來看看特征矩陣的樣子:
X.head()
2017-11-19_19-2-11_snapshots-03.jpg
顯然拗秘,Geography和Gender這兩列都從原先描述類別的字符串,變成了數(shù)字慷暂。
這樣是不是就完事大吉了呢聘殖?
不對,Gender還好說行瑞,只有兩種取值方式奸腺,要么是男,要么是女血久。我們可以把“是男性”定義為1突照,那么女性就取值為0氧吐。兩種取值只是描述類別不同,沒有歧義翠拣。
而Geography就不同了然想。因為數(shù)據(jù)集里面可能的國家地區(qū)取值有3種滑燃,所以就轉(zhuǎn)換成了0(法國)昂验、1(德國)既琴、2(西班牙)占婉。問題是,這三者之間真的有序列(大懈Χ鳌)關(guān)系嗎逆济?
答案自然是否定的。我們其實還是打算用數(shù)值描述分類而已磺箕。但是取值有數(shù)量的序列差異奖慌,就會給機(jī)器帶來歧義。它并不清楚不同的取值只是某個國家的代碼松靡,可能會把這種大小關(guān)系帶入模型計算简僧,從而產(chǎn)生錯誤的結(jié)果。
解決這個問題雕欺,我們就需要引入OneHotEncoder
涎劈。它也是Scikit-learn提供的一個類,可以幫助我們把類別的取值轉(zhuǎn)變?yōu)槎鄠€變量組合表示阅茶。
咱們這個數(shù)據(jù)集里蛛枚,可以把3個國家分別用3個數(shù)字組合來表示。例如法國從原先的0脸哀,變成(1, 0, 0)
蹦浦,德國從1變成(0, 1, 0)
,而西班牙從2變成(0, 0, 1)
撞蜂。
這樣盲镶,再也不會出現(xiàn)0和1之外的數(shù)字來描述類別,從而避免機(jī)器產(chǎn)生誤會蝌诡,錯把類別數(shù)字當(dāng)成大小來計算了溉贿。
特征矩陣?yán)锩妫覀冎恍枰D(zhuǎn)換國別這一列浦旱。因為它在第1列的位置(從0開始計數(shù))宇色,因而categorical_features
只填寫它的位置信息。
onehotencoder = OneHotEncoder(categorical_features = [1])
X = onehotencoder.fit_transform(X).toarray()
這時候颁湖,我們的特征矩陣數(shù)據(jù)框就被轉(zhuǎn)換成了一個數(shù)組宣蠕。注意所有被OneHotEncoder轉(zhuǎn)換的列會排在最前面,然后才是那些保持原樣的數(shù)據(jù)列甥捺。
我們只看轉(zhuǎn)換后的第一行:
X[0]
array([ 1.00000000e+00, 0.00000000e+00, 0.00000000e+00,
6.19000000e+02, 0.00000000e+00, 4.20000000e+01,
2.00000000e+00, 0.00000000e+00, 1.00000000e+00,
1.00000000e+00, 1.00000000e+00, 1.01348880e+05])
這樣抢蚀,總算轉(zhuǎn)換完畢了吧?
沒有镰禾。
因為本例中皿曲,OneHotEncoder轉(zhuǎn)換出來的3列數(shù)字唱逢,實際上是不獨立的。給定其中兩列的信息屋休,你自己都可以計算出其中的第3列取值惶我。
好比說,某一行的前兩列數(shù)字是(0, 0)
博投,那么第三列肯定是1。因為這是轉(zhuǎn)換規(guī)則決定的盯蝴。3列里只能有1個是1毅哗,其余都是0。
如果你做過多元線性回歸捧挺,應(yīng)該知道這種情況下虑绵,我們是需要去掉其中一列,才能繼續(xù)分析的闽烙。不然會落入“虛擬變量陷阱”(dummy variable trap)翅睛。
我們刪掉第0列,避免掉進(jìn)坑里黑竞。
X = np.delete(X, [0], 1)
再次打印第一行:
X[0]
array([ 0.00000000e+00, 0.00000000e+00, 6.19000000e+02,
0.00000000e+00, 4.20000000e+01, 2.00000000e+00,
0.00000000e+00, 1.00000000e+00, 1.00000000e+00,
1.00000000e+00, 1.01348880e+05])
檢查完畢捕发,現(xiàn)在咱們的特征矩陣處理基本完成。
但是監(jiān)督式學(xué)習(xí)很魂,最重要的是有標(biāo)簽(label)數(shù)據(jù)扎酷。本例中的標(biāo)簽就是用戶是否流失。我們目前的標(biāo)簽數(shù)據(jù)框遏匆,是這個樣子的法挨。
y.head()
0 1
1 0
2 1
3 0
4 0
Name: Exited, dtype: int64
它是一個行向量,我們需要把它先轉(zhuǎn)換成為列向量幅聘。你可以想象成把它“豎過來”凡纳。
y = y[:, np.newaxis]
y
array([[1],
[0],
[1],
...,
[1],
[1],
[0]])
這樣在后面訓(xùn)練的時候,他就可以和前面的特征矩陣一一對應(yīng)來操作計算了帝蒿。
既然標(biāo)簽代表了類別荐糜,我們也把它用OneHotEncoder轉(zhuǎn)換,這樣方便我們后面做分類學(xué)習(xí)葛超。
onehotencoder = OneHotEncoder()
y = onehotencoder.fit_transform(y).toarray()
此時的標(biāo)簽變成兩列數(shù)據(jù)狞尔,一列代表顧客存留,一列代表顧客流失巩掺。
y
array([[ 0., 1.],
[ 1., 0.],
[ 0., 1.],
...,
[ 0., 1.],
[ 0., 1.],
[ 1., 0.]])
總體的數(shù)據(jù)已經(jīng)齊全了偏序。但是我們不能把它們都用來訓(xùn)練。
這就好像老師不應(yīng)該把考試題目拿來給學(xué)生做作業(yè)和練習(xí)一樣胖替。只有考學(xué)生沒見過的題研儒,才能區(qū)分學(xué)生是掌握了正確的解題方法豫缨,還是死記硬背了作業(yè)答案。
我們拿出20%的數(shù)據(jù)端朵,放在一邊好芭,等著用來做測試。其余8000條數(shù)據(jù)用來訓(xùn)練機(jī)器學(xué)習(xí)模型冲呢。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
我們看看訓(xùn)練集的長度:
len(X_train)
8000
再看看測試集的長度:
len(X_test)
2000
確認(rèn)無誤舍败。
是不是可以開始機(jī)器學(xué)習(xí)了?
可以敬拓,但是下面這一步也很關(guān)鍵邻薯。我們需要把數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化處理。因為原先每一列數(shù)字的取值范圍都各不相同乘凸,因此有的列方差要遠(yuǎn)遠(yuǎn)大于其他列厕诡。這樣對機(jī)器來說,也是很困擾的营勤。數(shù)據(jù)的標(biāo)準(zhǔn)化處理灵嫌,可以在保持列內(nèi)數(shù)據(jù)多樣性的同時,盡量減少不同類別之間差異的影響葛作,可以讓機(jī)器公平對待全部特征寿羞。
我們調(diào)用Scikit-learn的StandardScaler
類來完成這一過程。
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
注意赂蠢,我們只對特征矩陣做標(biāo)準(zhǔn)化稠曼,標(biāo)簽是不能動的。另外訓(xùn)練集和測試集需要按照統(tǒng)一的標(biāo)準(zhǔn)變化客年。所以你看霞幅,訓(xùn)練集上,我們用了fit_transform
函數(shù)量瓜,先擬合后轉(zhuǎn)換司恳;而在測試集上,我們直接用訓(xùn)練集擬合的結(jié)果绍傲,只做轉(zhuǎn)換扔傅。
X_train
array([[-0.5698444 , 1.74309049, 0.16958176, ..., 0.64259497,
-1.03227043, 1.10643166],
[ 1.75486502, -0.57369368, -2.30455945, ..., 0.64259497,
0.9687384 , -0.74866447],
[-0.5698444 , -0.57369368, -1.19119591, ..., 0.64259497,
-1.03227043, 1.48533467],
...,
[-0.5698444 , -0.57369368, 0.9015152 , ..., 0.64259497,
-1.03227043, 1.41231994],
[-0.5698444 , 1.74309049, -0.62420521, ..., 0.64259497,
0.9687384 , 0.84432121],
[ 1.75486502, -0.57369368, -0.28401079, ..., 0.64259497,
-1.03227043, 0.32472465]])
你會發(fā)現(xiàn),許多列的方差比原先小得多烫饼。機(jī)器學(xué)習(xí)起來猎塞,會更加方便。
數(shù)據(jù)清理和轉(zhuǎn)換工作至此完成杠纵。
決策樹
如果讀過我的《貸還是不貸:如何用Python和機(jī)器學(xué)習(xí)幫你決策荠耽?》一文,你應(yīng)該有一種感覺——這個問題和貸款審批決策很像氨仍濉铝量!既然在該文中倘屹,決策樹很好使,我們繼續(xù)用決策樹不就好了慢叨?
好的纽匙,我們先測試一下經(jīng)典機(jī)器學(xué)習(xí)算法表現(xiàn)如何。
從Scikit-learn中拍谐,讀入決策樹工具狼速。然后擬合訓(xùn)練集數(shù)據(jù)膘格。
from sklearn import tree
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X_train, y_train)
然后嗦玖,利用我們建立的決策樹模型做出預(yù)測闷供。
y_pred = clf.predict(X_test)
打印預(yù)測結(jié)果:
y_pred
array([[ 1., 0.],
[ 0., 1.],
[ 1., 0.],
...,
[ 1., 0.],
[ 1., 0.],
[ 0., 1.]])
這樣看不出來什么荷辕。讓我們調(diào)用Scikit-learn的classification_report
模塊蔫仙,生成分析報告类茂。
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
precision recall f1-score support
0 0.89 0.86 0.87 1595
1 0.51 0.58 0.54 405
avg / total 0.81 0.80 0.81 2000
經(jīng)檢測冗疮,決策樹在咱們的數(shù)據(jù)集上够坐,表現(xiàn)得還是不錯的寸宵。總體的準(zhǔn)確率為0.81元咙,召回率為0.80梯影,f1分?jǐn)?shù)為0.81,已經(jīng)很高了庶香。對10個客戶做流失可能性判斷甲棍,它有8次都能判斷正確。
但是赶掖,這樣是否足夠感猛?
我們或許可以調(diào)整決策樹的參數(shù)做優(yōu)化,嘗試改進(jìn)預(yù)測結(jié)果奢赂。
或者我們可以采用深度學(xué)習(xí)陪白。
深度
深度學(xué)習(xí)的使用場景,往往是因為原有的模型經(jīng)典機(jī)器學(xué)習(xí)模型過于簡單膳灶,無法把握復(fù)雜數(shù)據(jù)特性咱士。
我不準(zhǔn)備給你講一堆數(shù)學(xué)公式,咱們動手做個實驗轧钓。
請你打開這個網(wǎng)址序厉。
你會看到如下圖所示的深度學(xué)習(xí)游樂場:
右側(cè)的圖形,里面是藍(lán)色數(shù)據(jù)毕箍,外圈是黃色數(shù)據(jù)弛房。你的任務(wù)就是要用模型分類兩種不同數(shù)據(jù)。
你說那還不容易而柑?我一眼就看出來了庭再。
你看出來沒有用捞奕。通過你的設(shè)置,讓機(jī)器也能正確區(qū)分拄轻,才算數(shù)颅围。
圖中你看到許多加減號。咱們就通過操縱它們來玩兒一玩兒模型恨搓。
首先院促,點圖中部上方的"2 HIDDEN LAYERS"左側(cè)減號,把中間隱藏層數(shù)降低為1斧抱。
然后常拓,點擊"2 neurons"上面的減號,把神經(jīng)元數(shù)量減少為1辉浦。
把頁面上方的Activation函數(shù)下拉框打開弄抬,選擇“Sigmoid”。
現(xiàn)在的模型宪郊,其實就是經(jīng)典的邏輯回歸(Logistic Regression)掂恕。
點擊左上方的運行按鈕,我們看看執(zhí)行效果弛槐。
由于模型過于簡單懊亡,所以機(jī)器絞盡腦汁,試圖用一條直線切分二維平面上的兩類節(jié)點乎串。
損失(loss)居高不下店枣。訓(xùn)練集和測試集損失都在0.4左右,顯然不符合我們的分類需求叹誉。
下面我們試試增加層數(shù)和神經(jīng)元數(shù)量鸯两。這次點擊加號,把隱藏層數(shù)加回到2长豁,兩層神經(jīng)元數(shù)量都取2甩卓。
再次點擊運行。
經(jīng)過一段時間蕉斜,結(jié)果穩(wěn)定了下來逾柿,你發(fā)現(xiàn)這次電腦用了兩條線,把平面切分成了3部分宅此。
測試集損失下降到了0.25左右机错,而訓(xùn)練集損失更是降低到了0.2以下。
模型復(fù)雜了父腕,效果似乎更好一些弱匪。
再接再厲,我們把第一個隱藏層的神經(jīng)元數(shù)量增加為4看看。
點擊運行萧诫,不一會兒有趣的事情就發(fā)生了斥难。
機(jī)器用一條近乎完美的曲線把平面分成了內(nèi)外兩個部分。測試集和訓(xùn)練集損失都極速下降帘饶,訓(xùn)練集損失甚至接近于0哑诊。
這告訴我們,許多時候模型過于簡單帶來的問題及刻,可以通過加深隱藏層次镀裤、增加神經(jīng)元的方法提升模型復(fù)雜度,加以改進(jìn)缴饭。
目前流行的劃分方法暑劝,是用隱藏層的數(shù)量多少來區(qū)分是否“深度”。當(dāng)神經(jīng)網(wǎng)絡(luò)中隱藏層數(shù)量達(dá)到3層以上時颗搂,就被稱為“深度神經(jīng)網(wǎng)絡(luò)”担猛,或者“深度學(xué)習(xí)”。
久聞大名的深度學(xué)習(xí)丢氢,原來就是這么簡單傅联。
如果有時間的話,建議你自己在這個游樂場里多動手玩兒一玩兒卖丸。你會很快對神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)有個感性認(rèn)識纺且。
框架
游樂場背后使用的引擎盏道,就是Google的深度學(xué)習(xí)框架Tensorflow稍浆。
所謂框架,就是別人幫你構(gòu)造好的基礎(chǔ)軟件應(yīng)用猜嘱。你可以通過調(diào)用它們衅枫,避免自己重復(fù)發(fā)明輪子,大幅度節(jié)省時間朗伶,提升效率弦撩。
支持Python語言的深度學(xué)習(xí)的框架有很多,除了Tensorflow外论皆,還有PyTorch, Theano和MXNet等益楼。
我給你的建議是,找到一個你喜歡的軟件包点晴,深入學(xué)習(xí)使用感凤,不斷實踐來提升自己的技能。千萬不要跟別人爭論哪個深度學(xué)習(xí)框架更好粒督。一來蘿卜白菜各有所愛陪竿,每個人都有自己的偏好;二來深度學(xué)習(xí)的江湖水很深屠橄,言多有失族跛。說錯了話闰挡,別的門派可能會不高興喲。
我比較喜歡Tensorflow礁哄。但是Tensorflow本身是個底層庫长酗。雖然隨著版本的更迭,界面越來越易用姐仅。但是對初學(xué)者來說花枫,許多細(xì)節(jié)依然有些過于瑣碎,不容易掌握掏膏。
初學(xué)者的耐心有限劳翰,挫折過多容易放棄。
幸好馒疹,還有幾個高度抽象框架佳簸,是建立在Tensorflow之上的。如果你的任務(wù)是應(yīng)用現(xiàn)成的深度學(xué)習(xí)模型颖变,那么這些框架會給你帶來非常大的便利生均。
這些框架包括Keras, TensorLayer等。咱們今天將要使用的腥刹,叫做TFlearn马胧。
它的特點,就是長得很像Scikit-learn衔峰。這樣如果你熟悉經(jīng)典機(jī)器學(xué)習(xí)模型佩脊,學(xué)起來會特別輕松省力。
實戰(zhàn)
閑話就說這么多垫卤,下面咱們繼續(xù)寫代碼吧威彰。
寫代碼之前,請回到終端下穴肘,運行以下命令歇盼,安裝幾個軟件包:
pip install tensorflow
pip install tflearn
執(zhí)行完畢后,回到Notebook里评抚。
我們呼叫tflearn框架豹缀。
import tflearn
然后,我們開始搭積木一樣慨代,搭神經(jīng)網(wǎng)絡(luò)層邢笙。
首先是輸入層。
net = tflearn.input_data(shape=[None, 11])
注意這里的寫法鱼响,因為我們輸入的數(shù)據(jù)鸣剪,是特征矩陣。而經(jīng)過我們處理后,特征矩陣現(xiàn)在有11列筐骇,因此shape的第二項寫11债鸡。
shape的第一項,None铛纬,指的是我們要輸入的特征矩陣行數(shù)厌均。因為我們現(xiàn)在是搭建模型,后面特征矩陣有可能一次輸入告唆,有可能分成組塊輸入棺弊,長度可大可小,無法事先確定模她。所以這里填None。tflearn會在我們實際執(zhí)行訓(xùn)練的時候懂牧,自己讀入特征矩陣的尺寸侈净,來處理這個數(shù)值。
下面我們搭建隱藏層僧凤。這里我們要使用深度學(xué)習(xí)畜侦,搭建3層。
net = tflearn.fully_connected(net, 6, activation='relu')
net = tflearn.fully_connected(net, 6, activation='relu')
net = tflearn.fully_connected(net, 6, activation='relu')
activation剛才在深度學(xué)習(xí)游樂場里面我們遇到過躯保,代表激活函數(shù)旋膳。如果沒有它,所有的輸入輸出都是線性關(guān)系途事。
Relu函數(shù)是激活函數(shù)的一種验懊。它大概長這個樣子。
如果你想了解激活函數(shù)的更多知識盯孙,請參考后文的學(xué)習(xí)資源部分鲁森。
隱藏層里祟滴,每一層我們都設(shè)置了6個神經(jīng)元振惰。其實至今為之,也不存在最優(yōu)神經(jīng)元數(shù)量的計算公式垄懂。工程界的一種做法骑晶,是把輸入層的神經(jīng)元數(shù)量,加上輸出層神經(jīng)元數(shù)量草慧,除以2取整桶蛔。咱們這里就是用的這種方法,得出6個漫谷。
搭好了3個中間隱藏層仔雷,下面我們來搭建輸出層。
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net)
這里我們用兩個神經(jīng)元做輸出,并且說明使用回歸方法碟婆。輸出層選用的激活函數(shù)為softmax电抚。處理分類任務(wù)的時候,softmax比較合適竖共。它會告訴我們每一類的可能性蝙叛,其中數(shù)值最高的,可以作為我們的分類結(jié)果公给。
積木搭完了借帘,下面我們告訴TFlearn,以剛剛搭建的結(jié)構(gòu)淌铐,生成模型肺然。
model = tflearn.DNN(net)
有了模型,我們就可以使用擬合功能了腿准。你看是不是跟Scikit-learn的使用方法很相似呢狰挡?
model.fit(X_train, y_train, n_epoch=30, batch_size=32, show_metric=True)
注意這里多了幾個參數(shù),我們來解釋一下释涛。
-
n_epoch
:數(shù)據(jù)訓(xùn)練幾個輪次加叁。 -
batch_size
:每一次輸入給模型的數(shù)據(jù)行數(shù)。 -
show_metric
:訓(xùn)練過程中要不要打印結(jié)果唇撬。
以下就是電腦輸出的最終訓(xùn)練結(jié)果它匕。其實中間運行過程看著更激動人心,你自己試一下就知道了窖认。
Training Step: 7499 | total loss: ?[1m?[32m0.39757?[0m?[0m | time: 0.656s
| Adam | epoch: 030 | loss: 0.39757 - acc: 0.8493 -- iter: 7968/8000
Training Step: 7500 | total loss: ?[1m?[32m0.40385?[0m?[0m | time: 0.659s
| Adam | epoch: 030 | loss: 0.40385 - acc: 0.8487 -- iter: 8000/8000
--
我們看到訓(xùn)練集的損失(loss)大概為0.4左右豫柬。
打開終端,我們輸入
tensorboard --logdir=/tmp/tflearn_logs/
然后在瀏覽器里輸入http://localhost:6006/
可以看到如下界面:
這是模型訓(xùn)練過程的可視化圖形扑浸,可以看到準(zhǔn)確度的攀升和損失降低的曲線烧给。
打開GRAPHS標(biāo)簽頁,我們可以查看神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)圖形喝噪。
我們搭積木的過程础嫡,在此處一目了然。
評估
訓(xùn)練好了模型酝惧,我們來嘗試做個預(yù)測吧榴鼎。
看看測試集的特征矩陣第一行。
X_test[0]
array([ 1.75486502, -0.57369368, -0.55204276, -1.09168714, -0.36890377,
1.04473698, 0.8793029 , -0.92159124, 0.64259497, 0.9687384 ,
1.61085707])
我們就用它來預(yù)測一下分類結(jié)果晚唇。
y_pred = model.predict(X_test)
打印出來看看:
y_pred[0]
array([ 0.70956731, 0.29043278], dtype=float32)
模型判斷該客戶不流失的可能性為0.70956731巫财。
我們看看實際標(biāo)簽數(shù)據(jù):
y_test[0]
array([ 1., 0.])
客戶果然沒有流失。這個預(yù)測是對的哩陕。
但是一個數(shù)據(jù)的預(yù)測正確與否平项,是無法說明問題的赫舒。我們下面跑整個測試集,并且使用evaluate函數(shù)評價模型闽瓢。
score = model.evaluate(X_test, y_test)
print('Test accuarcy: %0.4f%%' % (score[0] * 100))
Test accuarcy: 84.1500%
在測試集上号阿,準(zhǔn)確性達(dá)到84.15%,好樣的鸳粉!
希望在你的努力下扔涧,機(jī)器做出的準(zhǔn)確判斷可以幫助銀行有效鎖定可能流失的客戶,降低客戶的流失率届谈,繼續(xù)日進(jìn)斗金枯夜。
說明
你可能覺得,深度學(xué)習(xí)也沒有什么厲害的嘛艰山。原先的決策樹算法湖雹,那么簡單就能實現(xiàn),也可以達(dá)到80%以上的準(zhǔn)確度曙搬。寫了這么多語句摔吏,深度學(xué)習(xí)結(jié)果也無非只提升了幾個百分點而已。
首先纵装,準(zhǔn)確度達(dá)到某種高度后征讲,提升是不容易的。這就好像學(xué)生考試橡娄,從不及格到及格诗箍,付出的努力并不需要很高;從95分提升到100挽唉,卻是許多人一輩子也沒有完成的目標(biāo)滤祖。
其次,在某些領(lǐng)域里瓶籽,1%的提升意味著以百萬美元計的利潤匠童,或者幾千個人的生命因此得到拯救。
第三塑顺,深度學(xué)習(xí)的崛起汤求,是因為大數(shù)據(jù)的環(huán)境。在許多情況下茬暇,數(shù)據(jù)越多首昔,深度學(xué)習(xí)的優(yōu)勢就越明顯寡喝。本例中只有10000條記錄糙俗,與“大數(shù)據(jù)”的規(guī)模還相去甚遠(yuǎn)。
學(xué)習(xí)資源
如果你對深度學(xué)習(xí)感興趣预鬓,推薦以下學(xué)習(xí)資源巧骚。
首先是教材赊颠。
第一本是Deep Learning,絕對的經(jīng)典劈彪。
第二本是Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems竣蹦,深入淺出,通俗易懂沧奴。
其次是MOOC痘括。
推薦吳恩達(dá)(Andrew Ng)教授在Coursera上的兩門課程。
一門是機(jī)器學(xué)習(xí)滔吠。這課推出有年頭了纲菌,但是非常有趣和實用。具體的介紹請參考拙作《機(jī)器學(xué)習(xí)哪里有這么玄疮绷?》以及《如何用MOOC組合掌握機(jī)器學(xué)習(xí)翰舌?》。
一門是深度學(xué)習(xí)冬骚。這是個系列課程椅贱,包括5門子課程。今年推出的新課只冻,自成體系庇麦,但是最好有前面那門課程作為基礎(chǔ)。
討論
你對深度學(xué)習(xí)感興趣嗎喜德?之前有沒有做過深度學(xué)習(xí)項目女器?你掌握了哪些深度學(xué)習(xí)框架?有沒有什么建議給初學(xué)者住诸?歡迎留言驾胆,把心得分享給大家,我們一起交流討論贱呐。
喜歡請點贊丧诺。還可以微信關(guān)注和置頂我的公眾號“玉樹芝蘭”(nkwangshuyi)。
如果你對數(shù)據(jù)科學(xué)感興趣奄薇,不妨閱讀我的系列教程索引貼《如何高效入門數(shù)據(jù)科學(xué)驳阎?》,里面還有更多的有趣問題及解法馁蒂。