互联网上有不少很棒的机器学习教程。可是,它们大多数都专一于机器学习的特定部分,例如,探索数据,创建模型,训练和评估。其中不多有人介绍构建机器学习模型的完整步骤。算法
最受欢迎的文章之一律述了进行机器学习的步骤,这是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:本文属于翻译,原文