互聯網上有不少很棒的機器學習教程。可是,它們大多數都專一於機器學習的特定部分,例如,探索數據,創建模型,訓練和評估。其中不多有人介紹構建機器學習模型的完整步驟。算法
最受歡迎的文章之一律述了進行機器學習的步驟,這是Google雲端平臺推出的郭玉峯的《機器學習的7個步驟》。api
提出瞭如下七個步驟:瀏覽器
在本文中,咱們將實踐上述步驟,並從頭開始構建機器學習模型。網絡
在開始討論細節以前,對於任何機器學習項目,咱們要作的第一件事是爲咱們的機器學習模型定義問題。session
對於本教程,咱們將使用Kaggle的Titanic Dataset。這是一個很是著名的數據集,一般是學生學習機器學習的第一步。架構
假設咱們被要求建立一個能夠預測泰坦尼克號生存時間的系統。app
爲了運行本教程,您須要安裝dom
TensorFlow 2, TensorBoard 2, numpy, pandas, matplotlib, seaborn
它們均可以直接經過PyPI安裝,我強烈建議建立一個新的虛擬環境。最好避免使用base(root),由於它可能會破壞系統。機器學習
有關建立Python虛擬環境的教程,您能夠看一下:svg
定義好問題後,就該進行機器學習的第一步,那就是收集數據。這一步是最重要的,由於您收集的數據的質量和數量將直接決定您的預測模型的質量。
在本教程中,數據未來自Kaggle。讓咱們導入一些庫並加載數據以開始使用:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline
讓咱們將train.csv和test.csv文件加載到pandas DataFrame中。
df_train_raw = pd.read_csv('data/titanic/train.csv') df_test_raw = pd.read_csv('data/titanic/test.csv') df_train_raw.head()
preview of Titanic data
Data Dictionary from Kaggle
讓咱們從一些探索性數據分析(EDA)開始。咱們將從檢查缺失值開始。
咱們可使用seaborn來建立一個簡單的熱圖,以查看缺乏的值:
sns.heatmap(df_train_raw.isnull(), yticklabels=False, cbar=False, cmap='viridis')
output of seaborn heatmap plot for missing values
年齡,機艙和出發缺乏值。年齡缺失的比例可能很小,不足以用某種形式的估算合理地替代。查看「機艙」列,該數據彷佛缺乏太多值,沒法作有用的事情。咱們可能會在之後放下機艙,或將其更改成其餘功能,例如「機艙已知:1或0」。出發的比例很小,在本教程中,咱們保留它。
讓咱們繼續可視化更多數據:
sns.countplot(x='Survived', data=df_train_raw, palette='RdBu_r')
plot of Survived
sns.countplot(x='Survived', hue='Sex', data=df_train_raw, palette='RdBu_r')
sns.countplot(x='Survived', hue='Pclass', data=df_train_raw, palette='rainbow')
sns.distplot(df_train_raw['Age'].dropna(), kde=True, color='darkred', bins=30)
sns.countplot(x='SibSp',data=df_train_raw)
df_train_raw['Fare'].hist(color='green', bins=40, figsize=(8,4))
咱們想用某種形式的估算來代替失蹤的時代。一種方法是填寫全部乘客的平均年齡。可是,咱們能夠對此有所瞭解,並按旅客等級檢查平均年齡。例如:
sns.boxplot(x='Pclass', y='Age', data=df_train_raw, palette='winter')
咱們能夠看到,較高階層的較富裕乘客每每年齡較大,這是有道理的。咱們將使用這些平均年齡值根據年齡的Pclass進行估算。
def impute_age(cols): Age = cols[0] Pclass = cols[1] if pd.isnull(Age): if Pclass == 1: return 37 elif Pclass == 2: return 29 else: return 24 else: return Age
如今,咱們應用該功能並檢查其是否有效:
# Make a copy for test only train_copy = df_train_raw.copy() train_copy['Age'] = train_copy[['Age','Pclass']] .apply(impute_age, axis=1) # check that heat map again sns.heatmap(train_copy.isnull(), yticklabels=False, cbar=False, cmap='viridis')
很是好! impute_age()有效。讓咱們繼續進行轉換,並刪除「機艙」列。
咱們須要將分類功能轉換爲一鍵編碼。不然,咱們的機器學習算法將沒法直接將這些功能做爲輸入。
讓咱們使用info()檢查列數據類型:
df_train_raw.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 712 entries, 0 to 711 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 712 non-null int64 1 Survived 712 non-null int64 2 Pclass 712 non-null int64 3 Name 712 non-null object 4 Sex 712 non-null object 5 Age 566 non-null float64 6 SibSp 712 non-null int64 7 Parch 712 non-null int64 8 Ticket 712 non-null object 9 Fare 712 non-null float64 10 Cabin 168 non-null object 11 Embarked 710 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 66.9+ KB
有5列具備對象數據類型的列。其中,不須要名稱,機票和機艙。另外,根據上面看到的數據字典,咱們注意到Pclass是分類數據。讓咱們作一個函數preprocessing()來保留這些有用的數字功能,並將Pclass,Sex和Embarked轉換爲一鍵編碼。
讓咱們應用該功能並建立訓練和測試數據集以構建咱們的機器學習模型。
x_train = preprocessing(df_train_raw) y_train = df_train_raw['Survived'].values x_test = preprocessing(df_test_raw) y_test = df_test_raw['Survived'].values print("x_train.shape =", x_train.shape ) print("x_test.shape =", x_test.shape )
經過在上面運行,您應該得到以下訓練和測試數據集的形狀:
x_train.shape = (712, 13) x_test.shape = (179, 13)
讓咱們看看x_train.head()的數據:
咱們的數據已準備好用於模型。
在TensorFlow 2.0中有三種方法來實現神經網絡架構:
爲簡單起見,讓咱們使用最簡單的方法:帶有Sequential()的Sequential API。讓咱們繼續前進,構建一個具備3個密集層的神經網絡。每一層中的全部參數均已進行硬編碼,以下所示:
import tensorflow as tf from tensorflow.keras import models, layers tf.keras.backend.clear_session() model = models.Sequential() model.add(layers.Dense(10, activation='relu', input_shape=(13,))) model.add(layers.Dense(20, activation='relu' )) model.add(layers.Dense(1, activation='sigmoid')) model.summary()
下面是model.summary() 的輸出:
首先,讓咱們使用model.compile()配置模型:
對於訓練,有三種方法能夠訓練Keras模型:
在本教程中,讓咱們繼續最簡單的方式model.fit()。
# Convert DataFrame into np array x_train = np.asarray(x_train) y_train = np.asarray(y_train) # Get around with KMP duplicate issue import os os.environ['KMP_DUPLICATE_LIB_OK']='True' # Use binary cross entropy loss function for binary classification model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy']) history = model.fit(x_train,y_train, batch_size= 64, epochs= 30, validation_split=0.2 )
若是一切運行順利,咱們應該獲得以下輸出。
Train on 569 samples, validate on 143 samples Epoch 1/30 569/569 [==============================] - 1s 2ms/sample - loss: 0.5568 - accuracy: 0.7206 - val_loss: 0.6139 - val_accuracy: 0.6713 Epoch 2/30 569/569 [==============================] - 0s 91us/sample - loss: 0.5639 - accuracy: 0.7047 - val_loss: 0.6212 - val_accuracy: 0.6643 Epoch 3/30 569/569 [==============================] - 0s 112us/sample - loss: 0.5705 - accuracy: 0.6907 - val_loss: 0.6379 - val_accuracy: 0.6573 Epoch 4/30 569/569 [==============================] - 0s 109us/sample - loss: 0.5538 - accuracy: 0.7065 - val_loss: 0.6212 - val_accuracy: 0.6713 ...... ...... Epoch 30/30 569/569 [==============================] - 0s 102us/sample - loss: 0.5597 - accuracy: 0.7065 - val_loss: 0.6056 - val_accuracy: 0.7203
訓練結束後,就可使用「模型評估」來查看模型是否良好。模型評估一般涉及:
df_test
發揮做用的地方。讓咱們建立一個函數plot_metric()來繪製指標。
%matplotlib inline %config InlineBackend.figure_format = 'svg' def plot_metric(history, metric): train_metrics = history.history[metric] val_metrics = history.history['val_'+metric] epochs = range(1, len(train_metrics) + 1) plt.plot(epochs, train_metrics, 'bo--') plt.plot(epochs, val_metrics, 'ro-') plt.title('Training and validation '+ metric) plt.xlabel("Epochs") plt.ylabel(metric) plt.legend(["train_"+metric, 'val_'+metric]) plt.show()
經過運行plot_metric(history,'loss')繪製損失進度。
經過運行plot_metric(history,'accuracy')繪製準確性進度。
針對測試數據集測試咱們的模型:
# Convert DataFrame into np array x_test = np.asarray(x_test) y_test = np.asarray(y_test) model.evaluate(x = x_test,y = y_test)
並且咱們應該獲得具備損失和準確性的輸出,以下所示:
179/1 [====] - 0s 43us/sample - loss: 0.5910 - accuracy: 0.6760 [0.5850795357586951, 0.67597765]
太酷了,咱們已經對第一個機器學習模型進行了評估。如今該看看咱們是否能夠經過任何方式進一步改進它。咱們能夠經過旋轉超參數來作到這一點。當咱們進行第一次訓練時,咱們隱式假設了一些參數,如今是時候回過頭來測試這些假設並嘗試其餘值了。
對於本教程,咱們只關注模型中如下三個超參數的實驗:
首先,首先加載TensorBoard notebook擴展程序:
# Load the TensorBoard notebook extension %load_ext tensorboard
而後,添加一條語句以清除上一次運行中的全部日誌。若是您不清除儀表盤,則會弄亂儀表盤。
# Clear any logs from previous runs !rm -rf ./logs/
導入TensorBoard HParams插件:
from tensorboard.plugins.hparams import api as hp
列出要嘗試的值,並將實驗配置記錄到TensorBoard。
5
、10
和20
10
、20
和40
adam
和sgd
用於優化程序
咱們的模型很是簡單:3個密集層。儘管再也不對超參數進行硬編碼,但代碼看起來很熟悉。相反,超參數在hyparams字典中提供,並在整個訓練功能中使用:
對於每次運行,請記錄具備超參數和最終精度的hparams摘要:
def run(run_dir, hparams): with tf.summary.create_file_writer(run_dir).as_default(): hp.hparams(hparams) # record the values used in this trial accuracy = train_test_model(hparams) tf.summary.scalar(METRIC_ACCURACY, accuracy, step=1)
如今,咱們能夠嘗試進行多個實驗,並使用不一樣的一套超級血壓計來訓練每一個實驗。爲簡單起見,讓咱們使用網格搜索來嘗試離散參數的全部組合以及實值參數的上限和下限。
session_num = 0 for num_units_one in HP_NUM_UNITS_ONE.domain.values: for num_units_two in HP_NUM_UNITS_TWO.domain.values: for optimizer in HP_OPTIMIZER.domain.values: hparams = { HP_NUM_UNITS_ONE: num_units_one, HP_NUM_UNITS_TWO: num_units_two, HP_OPTIMIZER: optimizer, } run_name = "run-%d" % session_num print('>> Starting trial: %s' % run_name) print({h.name: hparams[h] for h in hparams}) run('logs/hparam_tuning/' + run_name, hparams) session_num += 1
若是一切運行順利,咱們應該獲得以下輸出:
運行完成後,打開終端並cd進入項目目錄。而後,如今能夠經過在終端中運行如下命令來打開HParams儀表板:
admin@Mac:~/Code/WorkSpace/machine-learning/tf2 ⇒ tensorboard --logdir logs/hparam_tuning Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all TensorBoard 2.0.0 at http://localhost:6006/ (Press CTRL+C to quit)
在瀏覽器中打開儀表板,而後直接轉到HPARAMS-> PARALLEL COORDINATES VIEW
經過查看「平行座標」視圖,而後在精度軸上單擊並拖動,能夠選擇精度最高的運行。
當這些運行經過不一樣的超參數時,咱們能夠得出如下結論:
在這些實驗中表現最好。
如今,就準確度而言,咱們已經有了最好的機器學習模型。最後一步是使用此模型進行預測或推斷。這是全部這些工做的重點,在那裏機器學習的價值得以實現。咱們最終可使用咱們的模型來預測乘客是否存活。
使用模型進行預測:
model.predict(x_test[0:10]) array([[0.56895125], [0.37735564], [0.5005745 ], [0.60003537], [0.5371451 ], [0.36402294], [0.49169463], [0.49049523], [0.4984674 ], [0.1470165 ]], dtype=float32)
使用該模型爲輸入樣本生成類別預測。
model.predict_classes(x_test[0:10]) array([[1], [0], [1], [1], [1], [0], [0], [0], [0], [0]], dtype=int32)
最後,咱們能夠將整個模型保存到單個HDF5文件中:
model.save('data/keras_model.h5')
並加載經過save()保存的模型:
model = models.load_model('data/keras_model.h5') # Predict class model.predict_classes(x_test[0:10])
本文是一個快速教程,主要向全部人展現如何將Google的機器學習的7個步驟付諸實踐。我試圖避免使用許多機器學習概念,並儘可能簡化本教程。
在實際的應用程序中,它們還有不少要考慮的地方。例如,選擇評估指標,特徵縮放,選擇有意義的特徵,拆分數據集,處理過分擬合和欠擬合等。此外,本教程僅適用於結構化數據,而實際數據並不老是結構化數據,全部諸如圖像,音頻或文本之類的東西都是非結構化數據。
PS:本文屬於翻譯,原文