【DS】Keras深度學習介紹

筆者邀請您,先思考:

1 您使用過哪些深度學習框架?

2 您用過Keras嗎?您用Keras解決什麼問題?

在本文中,我們將使用Keras構建一個簡單的神經網絡。我們假設您對機器學習包(如scikit-learn)和其他科學包(如panda和Numpy)有一定的瞭解。

訓練一個人工神經網絡

訓練一個人工神經網絡包括以下步驟:

  1. 權值被隨機初始化爲接近零但不是零的數。
  2. 將數據集的觀察餵給輸入層。
  3. 正向傳播(從左到右):激活神經元,得到預測值。
  4. 將預測結果與實際值進行比較並計算誤差。
  5. 反向傳播(從右到左):調整權重。
  6. 重複步驟1 - 5
  7. 當整個訓練集通過神經網絡時,就完成了一個epoch。

業務問題

現在讓我們繼續解決一個真正的業務問題。一家保險公司向你提供了他們客戶先前索賠的數據。保險公司希望你開發一個模型來幫助他們預測哪些索賠看起來是欺詐的。通過這樣做,你希望每年爲公司節省數百萬美元。這是一個分類問題。這些是數據集中的列。

編者按:問題驅動和索賠欺詐,通過幫助公司省錢,以實現數據變現,體現數據,模型和策略的價值。

數據預處理

與許多業務問題一樣,所提供的數據沒有爲我們處理。因此,我們必須以我們的算法能夠接受的方式來準備它。我們從數據集中看到我們有一些分類列。我們需要將這些轉換成0和1,以便我們的深度學習模型能夠理解它們。另一件需要注意的事情是,我們必須將數據集作爲numpy數組提供給模型。下面我們導入必要的包,然後加載到數據集中。

編者按:通過數據預處理的方法和手段,完成好數據的準備工作。

1import pandas as pd
2import numpy as np
3df = pd.read_csv('raw_data/insurance_claims.csv')

然後我們將分類列轉換爲啞變量。

1feats = ['policy_state', 'insured_sex', 'insured_education_level', 'insured_occupation', 'insured_hobbies', 'insured_relationship', 'collision_type', 'incident_severity', 'authorities_contacted', 'incident_state', 'incident_city', 'incident_location', 'property_damage', 'police_report_available', 'auto_make', 'auto_model', 'fraud_reported', 'incident_type']
2
3df_final = pd.get_dummies(df, columns=feats, drop_first=True)

在本例中,我們使用drop_first=True來避免虛擬變量陷阱。例如,如果你有ab c d作爲類別那麼你可以把d作爲啞變量。這是因爲如果某物不屬於a b c,那麼它肯定屬於d,這被稱爲多重共線性。

我們使用sklearn的train_test_split將數據拆分爲訓練集和測試集。

1from sklearn.model_selection import train_test_split

接下來,我們要確保刪除我們預測的列,以防止它泄漏到訓練集和測試集。我們必須避免使用相同的數據集來訓練和測試模型。我們在數據集的末尾設置.values,以便獲得numpy數組。這是我們的深度學習模型接受數據的方式。這一步很重要,因爲我們的機器學習模型需要數組形式的數據。

1X = df_final.drop(['fraud_reported_Y', 'policy_csl', 'policy_bind_date', 'incident_date'],axis=1).values
2y = df_final['fraud_reported_Y'].values

然後我們將數據分割成訓練和測試集。我們使用70%的數據進行訓練,30%的數據進行測試。

1X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

接下來,我們必須使用Sklearn的StandardScaler對數據集進行縮放。由於在深度學習中需要進行大量的計算,特性縮放是必須的。特徵縮放標準化了自變量的範圍。

1from sklearn.preprocessing import StandardScaler
2sc = StandardScaler()
3X_train = sc.fit_transform(X_train)
4X_test = sc.transform(X_test)

構建人工神經網絡(ANN)

我們需要做的第一件事是導入Keras。默認情況下,Keras將使用TensorFlow作爲其後端。

1import keras

接下來,我們需要從Keras導入一些模塊。Sequential模塊用於初始化ANN,Dense模塊用於構建ANN的層。

1from keras.models import Sequential
2from keras.layers import Dense

接下來,我們需要通過創建一個sequence實例來初始化ANN。sequence函數初始化一個層級的線性堆棧。這允許我們在以後使用Dense模塊添加更多的層。

1classifier = Sequential()

添加輸入層(第一隱藏層)

我們使用add方法向ANN添加不同的層。第一個參數是要添加到該層的節點數。對於應該添加多少個節點沒有經驗法則,但是一個常見的策略是選擇節點的數量是輸入層節點的和輸出層節點的數量的平均值。

比如說你有五個自變量和一個輸出。然後把它們加起來除以2,也就是3。您還可以決定試驗一種稱爲參數調優的技術。第二個參數kernel_initializer將用於初始化權重。在這種情況下,它將使用均勻分佈來確保權重是接近於零的小數字。下一個參數是激活函數。我們用整流器函數,簡稱relu。我們主要使用這個函數在ANN中隱藏層。最後一個參數是input_dim,它是輸入層中的節點數。它表示自變量的數量。

1classifier.add(
2        Dense(3, kernel_initializer = ‘uniform’,
3              activation = ‘relu’, input_dim=5))

添加第二個隱藏層

添加第二個隱藏層類似於添加第一個隱藏層。

1classifier.add(
2      Dense(3, kernel_initializer = ‘uniform’,
3            activation = ‘relu’))

我們不需要指定input_dim參數,因爲我們已經在第一個隱藏層中指定了它。在第一個隱藏層中,我們指定了這個,以便讓層知道需要多少輸入節點。在第二個隱藏層中,ANN已經知道需要多少輸入節點,所以我們不需要重複。

添加輸出層

1classifier.add(
2     Dense(1, kernel_initializer = ‘uniform’,
3           activation = ‘sigmoid’))

我們改變第一個參數,因爲在輸出節點中我們需要一個節點。這是因爲我們只關心一項索賠是否具有欺騙性。我們改變激活函數因爲我們想要得到索賠是欺詐的概率。我們通過使用Sigmoid激活函數來做到這一點。如果您要處理的分類問題有兩個以上的類(例如,分類貓、狗和猴子),我們需要改變兩件事。我們將第一個參數改爲3,激活函數改爲softmax。Softmax是一個應用於兩個以上類別的自變量的sigmoid函數。

編譯ANN

1classifier.compile(optimizer= ‘adam’,
2                  loss = ‘binary_crossentropy’,
3                  metrics = [‘accuracy’])

編譯基本上是將隨機梯度下降法應用於整個神經網絡。第一個參數是你想要用來在神經網絡中得到最優權重集的算法。這裏使用的算法是一個隨機梯度算法。這有很多變體。一個非常有效的方法是adam。第二個參數是隨機梯度算法中的損失函數。由於我們的分類是二進制的,我們使用binary_crossentropy 損失函數。否則我們就會使用categorical_crossentopy。

訓練集上擬合ANN

1classifier.fit(X_train, y_train, batch_size = 10, epochs = 100)

X_train表示我們用來訓練ANN的自變量,y_train表示我們預測的列。Epochs表示通過ANN傳遞完整數據集的次數。Batch_size是權重將被更新的觀察值的數量。

使用訓練集進行預測

1y_pred = classifier.predict(X_test)

這將向我們顯示索賠欺詐的可能性。然後,我們爲將索賠歸類爲欺詐設定閾值爲50%。這意味着任何概率爲0.5或以上的索賠都將被歸類爲欺詐。

1y_pred = (y_pred > 0.5)

通過這種方式,保險公司可以首先追蹤那些沒有可疑的索賠,然後花更多時間評估那些被標記爲欺詐的索賠。

覈查混淆矩陣

1from sklearn.metrics import confusion_matrix
2cm = confusion_matrix(y_test, y_pred)

混淆矩陣的解釋如下。在2000個觀測中,1550 + 175觀測被正確預測,230 + 45觀測被錯誤預測。你可以用正確預測的次數除以總預測次數來計算準確率。在這種情況下(1550+175)/ 2000,也就是86%

做一個預測

假設保險公司只給你一次索賠。他們想知道索賠是否具有欺騙性。你會怎麼做才能知道呢?

1new_pred = classifier.predict(sc.transform(np.array([[a,b,c,d]])))

其中a b c d代表你的特徵。

1new_pred = (new_prediction > 0.5)

由於我們的分類器需要numpy數組,所以我們必須將單個觀察值轉換爲numpy數組,並使用變量標準化進行縮放。

評價ANN

在對模型進行一到兩次訓練之後,您會注意到您會得到不同的準確度。所以你不確定哪個是正確的。這就引入了偏差方差權衡。從本質上講,我們正在嘗試訓練一個模型,它將是準確的,並且在訓練幾次後,它的準確性不會有太多的差異。爲了解決這個問題,我們使用K-fold交叉驗證,K = 10。這將把訓練集分成10份。然後我們將在9個flods上訓練我們的模型,並在剩下的flod上測試它。因爲我們有10個flods,我們將通過10個組合迭代來做這個。

每次迭代都會給我們提供它的準確性。然後我們會找到所有準確度的平均值並將其作爲模型的準確度。我們還計算了方差,以確保它是最小的。

Keras有一個scikit學習包裝器(KerasClassifier),它允許我們在Keras代碼中包含K-fold交叉驗證。

1from keras.wrappers.scikit_learn import KerasClassifier

接下來,我們從scikit_learn導入k-fold交叉驗證函數。

1from sklearn.model_selection import cross_val_score

KerasClassifier希望它的一個參數是一個函數,因此我們需要構建這個函數。這個函數的目的是構建我們的ANN的架構。

1def make_classifier():
2    classifier = Sequential()
3    classiifier.add(Dense(3, kernel_initializer = ‘uniform’, activation = ‘relu’, input_dim=5))
4    classiifier.add(Dense(3, kernel_initializer = ‘uniform’, activation = ‘relu’))
5    classifier.add(Dense(1, kernel_initializer = ‘uniform’, activation = ‘sigmoid’))
6    classifier.compile(optimizer= ‘adam’,loss = ‘binary_crossentropy’,metrics = [‘accuracy’])
7    return classifier

這個函數將構建分類器並返回它以供下一步使用。我們在這裏做的唯一一件事就是將前面的ANN體系結構包裝在一個函數中並返回分類器。

然後,我們使用K-fold交叉驗證創建一個新的分類器,並將參數build_fn作爲前面創建的函數傳遞。接下來,我們傳遞batch的大小和epoch的數量,就像我們在前面的分類器中所做的一樣。

1classiifier = KerasClassifier(build_fn = make_classifier,
2                            batch_size=10, nb_epoch=100)

要應用k-fold交叉驗證函數,我們可以使用scikit-learn的cross_val_score函數。估計器就是我們用make_classifier構建的分類器,n_jobs=-1將利用所有可用的cpu。cv是摺疊數,10是一個典型的選擇。cross_val_score將返回計算中使用的十個測試fold的十個準確度。

1accuracies = cross_val_score(estimator = classifier,
2                             X = X_train,
3                             y = y_train,
4                             cv = 10,
5                             n_jobs = -1)

爲了得到相對準確度,我們得到了準確度的均值。

1mean = accuracies.mean()

所得方差如下:

1variance = accuracies.var()

目標是在準確度之間有一個小的差異。

克服過擬合

機器學習中的過度擬合是指當模型在訓練集中學習細節和噪聲,以致在測試集中表現不佳時發生的情況。當我們在測試集和訓練集的準確度之間存在巨大差異時,或者當你在應用k-fold交叉驗證時觀察到高方差時,就可以觀察到過擬合。在人工神經網絡中,我們使用了一種叫做“dropout regularization”的技術來解決這個問題。dropout regularization通過在訓練的每次迭代中隨機禁用一些神經元,以防止它們彼此過於依賴。

 1from keras.layers import Dropout
 2
 3classifier = Sequential()
 4classiifier.add(Dense(3, kernel_initializer = ‘uniform’, activation = ‘relu’, input_dim=5))
 5
 6# Notice the dropouts
 7classifier.add(Dropout(rate = 0.1))
 8classiifier.add(Dense(6, kernel_initializer = ‘uniform’, activation = ‘relu’))
 9classifier.add(Dropout(rate = 0.1))
10
11classifier.add(Dense(1, kernel_initializer = ‘uniform’, activation = ‘sigmoid’))
12classifier.compile(optimizer= ‘adam’,loss = ‘binary_crossentropy’,metrics = [‘accuracy’])

在這種情況下,我們在第一隱藏層和第二隱藏層之後應用drop。使用0.1的比率意味着10%的神經元將在每次迭代中被禁用。建議從0.1開始。然而,你不應該超過0.4,因爲你現在開始變得欠擬合

參數調整

一旦您獲得了您的準確度,您就可以調整參數以獲得更高的準確度。網格搜索使我們能夠測試不同的參數,以獲得最佳的參數。

第一步是從sklearn導入GridSearchCV模塊。

1from sklearn.model_selection import GridSearchCV

我們還需要修改make_classifier函數,如下所示。我們創建了一個名爲optimizer的新變量,它允許我們在params變量中添加多個優化器。

1def make_classifier(optimizer):
2    classifier = Sequential()
3    classiifier.add(Dense(6, kernel_initializer = ‘uniform’, activation = ‘relu’, input_dim=11))
4    classiifier.add(Dense(6, kernel_initializer = ‘uniform’, activation = ‘relu’))
5    classifier.add(Dense(1, kernel_initializer = ‘uniform’, activation = ‘sigmoid’))
6    classifier.compile(optimizer= optimizer,loss = ‘binary_crossentropy’,metrics = [‘accuracy’])
7    return classifier

我們仍然會使用KerasClassifier,但是我們不會傳遞批處理大小和epoch的數量,因爲這些是我們想要調優的參數。

1classifier = KerasClassifier(build_fn = make_classifier)

下一步是創建一個字典,其中包含我們想要調優的參數——在本例中是批處理大小、epoch的數量和優化器函數。我們仍然使用adam作爲優化器,並添加了一個名爲rmsprop的新優化器。Keras文檔在處理循環神經網絡時推薦使用rmsprop。然而,我們可以嘗試爲這個ANN看看它是否給我們一個更好的結果。

1params = {
2    'batch_size':[20,35],
3    'nb_epoch':[150,500],
4    'Optimizer':['adam','rmsprop']
5}

然後我們使用網格搜索來測試這些參數。網格搜索函數需要我們的估計器,我們剛剛定義的參數,評分指標和k-fold的數量。

1grid_search = GridSearchCV(estimator=classifier,
2                           param_grid=params,
3                           scoring=’accuracy’,
4                           cv=10)

和前面的對象一樣,我們需要擬合我們的訓練集。

1grid_search = grid_search.fit(X_train,y_train)

我們可以使用best_params從網格搜索對象中獲得最佳的參數選擇。同樣,我們使用best_score_來獲得最好的分數。

1best_param = grid_search.best_params_
2best_accuracy = grid_search.best_score_

需要注意的是,在尋找最佳參數時,這個過程需要一段時間。

總結

人工神經網絡只是一種深層神經網絡。還有其他一些網絡,如遞歸神經網絡(RNN)、卷積神經網絡(CNN)和玻爾茲曼機。RNNs可以預測股票的價格在未來是否會上漲或下跌。CNNs用於計算機視覺——在一組圖像中識別貓和狗,或在大腦圖像中識別癌細胞的存在。玻爾茲曼機用於設計推薦系統。也許我們可以在未來介紹其中一個神經網絡。

Cheers.

作者:Derrick Mwiti 原文鏈接: https://heartbeat.fritz.ai/introduction-to-deep-learning-with-keras-c7c3d14e1527

您有什麼想法或者見解,請留言。

數據人網是數據人學習,交流和分享的平臺,誠邀您創造和分享數據知識,共建和共享數據智庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章