机器学习入门简介

2022-12-30 0 385

机器自学是一类自然科学方式,从更正式宣布和抽象化的微观上,能像Mitchell(1997)那般表述:

假如两个电脑程式在T类各项任务中的操控性(用P来衡量)随著实战经验E的减少而提升,则该流程能从实战经验E中自学有关T类任务和谢鲁瓦操控性P的自然科学知识。

上面从统计数据预备,数学模型评估结果和校正等两个各方面,粗略如是说机器自学的愿景。

1. 统计数据预备

样品统计数据是如前所述英镑/美元指数的真实世界金融创新排程建立的。具体来说,从远距引入统计数据,接着将统计数据再次取样为当月统计数据, 并储存在Series第一类中。

import numpy as np import pandas as pd import matplotlib.pyplot as plt np.random.seed(100) plt.rcParams[savefig.dpi] = 300 plt.rcParams[font.family] = serif url = http://hilpisch.com/aiif_eikon_eod_data.csv raw = pd.read_csv(url, index_col=0, parse_dates=True)[EUR=] # raw.head() # 以月为周期性对统计数据再次取样 l = raw.resample(1M).last() l.plot(figsize=(10, 6), title=EUR/USD monthly);

机器学习入门简介

图1 英镑/美元指数的时间字符串(以月为基层单位)

为的是使样品多于单个特点,上面建立两个制备特点向量,在图象中展开单纯的建模。总之,而此制备特点(常量)对英镑 / 美元指数(条码统计数据,常量)没任何人说明力。在接下去的文本中,它会把条码统计数据是已连续且脉动的内在抽象化出。

# 将条码统计数据切换为ndarray第一类。 l = l.values # 从统计数据原素中乘以平均数 l -= l.mean() # 建立两个制备特点做为ndarray第一类 f = np.linspace(-2, 2, len(l)) plt.figure(figsize=(10, 6)) plt.plot(f, l, ro) plt.title(Sample Data Set) plt.xlabel(features) plt.ylabel(labels);

机器学习入门简介

图2 样品统计数据集

2. 准确性(误差)统计

MSE是预测问题常用的误差度量。如前所述MSE,以条码统计数据做为相关基准,并以算法在统计数据集(或部分统计数据集)上的预测值来判断其是否成功。我们分别考虑两种算法: OLS回归和神经网络。 具体来说是OLS回归,这个应用非常单纯,如上面的 Python 代码所示。如图3所示,回归结果是包含五阶单项式的回归。

def MSE(l, p): return np.mean((l – p) ** 2) # OLS 回归数学模型的拟合,包括五阶单项式 reg = np.polyfit(f, l, deg=5) # 通过 OLS 回归数学模型的预测给出了最优参数 p = np.polyval(reg, f) # 给定预测值的MSE值 mse = MSE(l, p) print(fMSE = {mse:.5f}) # Out: # MSE = 0.00342 plt.figure(figsize=(10, 6)) plt.plot(f, l, ro, label=sample data) plt.plot(f, p, –, label=regression) plt.legend();

机器学习入门简介

图3 样品统计数据与五阶单项式回归线

OLS回归一般采用解析解,因此没迭代自学发生,然而能通过逐步将更多统计数据赋给算法来模拟自学过程。上面的代码实现了OLS回归和预测,开始时多于两个样品, 接着逐渐减少样品的数量,最终达到统计数据集的完整长度。回归步骤是如前所述较小的子集实现的,而预测步骤是如前所述每一类情况下的全部特点统计数据实现的。一般来说,随著训练统计数据集的减少,MSE会明显下降。

for i in range(10, len(f) + 1, 20): # 如前所述统计数据子集的回归步骤。 reg = np.polyfit(f[:i], l[:i], deg=3) # 如前所述完整统计数据集的预测步骤 p = np.polyval(reg, f) # 产生的MSE值 mse = MSE(l, p) print(f{i:3d} | MSE={mse}) # Out: # 10 | MSE=248628.10681594367 # 30 | MSE=731.9382249304159 # 50 | MSE=12.236088505004368 # 70 | MSE=0.741059061974328 # 90 | MSE=0.0057430617304093335 # 110 | MSE=0.006492800939555583

神经网络在样品统计数据上的应用同样非常单纯,图4显示了神经网络是如何逼近样品统计数据的。

import pandas as pd import tensorflow as tf tf.random.set_seed(100) from Keras.layers import Dense from keras.models import Sequential model = Sequential() # 此神经网络是两个多于单个隐藏层的浅层网络 model.add(Dense(256, activation=relu, input_dim=1)) model.add(Dense(1, activation=linear)) model.compile(loss=mse, optimizer=rmsprop) # 训练数学模型 h = model.fit(f, l, epochs=1500, verbose=False) # Keras每个自学步骤的MSE值 res = pd.DataFrame(h.history) res.iloc[100:].plot(figsize=(10, 6)) plt.ylabel(MSE) plt.xlabel(epochs);

机器学习入门简介

图4 MSE值与训练轮数的关系

上面是数学模型的预测效果

# 在预测步骤中展平ndarray第一类 p = model.predict(f).flatten() # DNN 预测结果的MSE值 mse = MSE(l, p) print(fMSE = {mse:.5f}) # Out: # MSE = 0.0011754115847228454 plt.figure(figsize=(10, 6)) plt.plot(f, l, ro, label=sample data) plt.plot(f, p, –, label=DNN approximation) plt.legend();

机器学习入门简介

图5 样品统计数据和DNN近似

3. 数学模型的容量

通俗地讲,数学模型的容量是指它拟合各种函数的能力,它基本上决定了数学模型或算法能自学什么类型的函数或关系。对于仅如前所述单项式的OLS回归,最高阶单项式的次数表述了数学模型的容量。如将该阶数参数设置为deg=3,则 OLS 回归数学模型能自学常数型、线性型、二次型或三次型的函数关系。参数deg越大,OLS回归数学模型的容量越大。上面从deg=1开始,以2为增量增大阶数,MSE值随著阶数参数的增大而单调递减。图6显示了所有考虑阶数的回归线。

reg = {} for d in range(1, 12, 2): reg[d] = np.polyfit(f, l, deg=d) p = np.polyval(reg[d], f) mse = MSE(l, p) print(f{d:2d} | MSE={mse}) plt.figure(figsize=(10, 6)) plt.plot(f, l, ro, label=sample data) for d in reg: p = np.polyval(reg[d], f) plt.plot(f, p, –, label=fdeg={d}) plt.legend();

机器学习入门简介

图6 不同最高阶数的回归线

神经网络的容量取决于许多超参数,一般而言包括:

隐藏层的数量每个隐藏层的隐藏单元数量。

这两个超参数共同表述了神经网络中可训练参数(权重)的数量。前面的神经网络数学模型的可训练参数相对较少,只要再减少两个相同大小的层,就能显著减少可训练参数的数量。尽管可能需要减少训练轮数,但是容量较大的神经网络的MSE值会显著降低,并且拟合在视觉上也会更好,如图7所示。

def create_dnn_model(hl=1, hu=256): 建立Keras DNN数学模型的函数 参数 ========== hl: int 隐藏层数量 hu: int 每个隐藏层的单元数量 model = Sequential() for _ in range(hl): model.add(Dense(hu, activation=relu, input_dim=1)) model.add(Dense(1, activation=linear)) model.compile(loss=mse, optimizer=rmsprop) return model # 具有3个隐藏层,每层256个单元的DNN model = create_dnn_model(3) model.fit(f, l, epochs=2500, verbose=False) p = model.predict(f).flatten() mse = MSE(l, p) print(fMSE = {mse:.5f}) # Out: # MSE = 0.00028 plt.figure(figsize=(10, 6)) plt.plot(f, l, r, label=sample data) plt.plot(f, p, –, label=DNN approximation) plt.legend();

机器学习入门简介

图7 样品统计数据和DNN近似(更大容量)

4. 数学模型评估结果

一般来说,当在同一统计数据集上对数学模型或算法展开训练和评估结果时,数学模型或算法的容量会直接影响其操控性。然而,更复杂的是,应使用经过训练的数学模型或算法对其从未见过的统计数据展开泛化。例如,根据股票价格的历史预测(估计)未来股票价格,或者根据现有债务人的统计数据将潜在债务人分为“有信用”或“无信用”。

通常,给定的统计数据集会被分为多个子集,每个子集有不同的用途

训练统计数据集:这是用于算法训练的子集。校正统计数据集:这是用于在训练期间校正算法操控性的子集,该统计数据集与训练统计数据集不同。测试统计数据集:这是训练完成后仅在其上测试训练算法的子集。

通过对校正统计数据集应用两个(当前)经过训练的算法获得的结果,可能会反映在训练本身上(比如,对数学模型超参数展开调整会影响训练结果)。另外,在测试统计数据集上测试训练算法的结果不应反映在训练本身上或超参数中。

上面的代码任意选择25%的样品统计数据展开测试,在训练(自学)完成之前,数学模型或算法不会“看到”这些统计数据。同样,另外25%的样品统计数据被保留以用于校正,该统计数据用于在训练步骤和许多自学迭代期间监控操控性。剩余的50%用于训练(自学)本身。给定样品统计数据集,打乱顺序随机填充所有样品统计数据子集是有意义的。

# 测试统计数据集样品的数量 te = int(0.25 * len(f)) # 校正统计数据集样品的数量 va = int(0.25 * len(f)) np.random.seed(100) # 完整统计数据集的随机索引 ind = np.arange(len(f)) np.random.shuffle(ind) # 为统计数据子集生成的排序索引 ind_te = np.sort(ind[:te]) ind_va = np.sort(ind[te:te + va]) ind_tr = np.sort(ind[te + va:]) # 生成统计数据子集的特点 f_te = f[ind_te] f_va = f[ind_va] f_tr = f[ind_tr] # 生成统计数据子集的条码 l_te = l[ind_te] l_va = l[ind_va] l_tr = l[ind_tr]

如前所述训练统计数据子集和校正统计数据子集,上面的代码实现了不同deg参数值的回归,并计算了两个统计数据子集上的预测的MSE值。虽然训练统计数据集上的MSE值单调减小,但校正统计数据集上的MSE值往往在某一参数值达到最小值后又再次增大。这个现象就是所谓的过拟合。图8显示了不同deg值的回归拟合情况,并比较了训练统计数据集和校正统计数据集的拟合情况。

reg = {} mse = {} for d in range(1, 22, 4): reg[d] = np.polyfit(f_tr, l_tr, deg=d) p = np.polyval(reg[d], f_tr) # 训练统计数据集的MSE值 mse_tr = MSE(l_tr, p) p = np.polyval(reg[d], f_va) # 校正统计数据集的MSE值 mse_va = MSE(l_va, p) mse[d] = (mse_tr, mse_va) print(f{d:2d} | MSE_tr={mse_tr:7.5f} | MSE_va={mse_va:7.5f}) # Out: # 1 | MSE_tr=0.00574 | MSE_va=0.00492 # 5 | MSE_tr=0.00375 | MSE_va=0.00273 # 9 | MSE_tr=0.00132 | MSE_va=0.00243 # 13 | MSE_tr=0.00094 | MSE_va=0.00183 # 17 | MSE_tr=0.00060 | MSE_va=0.00153 # 21 | MSE_tr=0.00046 | MSE_va=0.00837 fig, ax = plt.subplots(2, 1, figsize=(10, 8), sharex=True) ax[0].plot(f_tr, l_tr, ro, label=training data) ax[1].plot(f_va, l_va, go, label=validation data) for d in reg: p = np.polyval(reg[d], f_tr) ax[0].plot(f_tr, p, –, label=fdeg={d} (tr)) p = np.polyval(reg[d], f_va) plt.plot(f_va, p, –, label=fdeg={d} (va)) ax[0].legend() ax[1].legend();

机器学习入门简介

图8 包括回归拟合的训练统计数据集和校正统计数据集

通过Keras和神经网络数学模型,能针对每个自学步骤监控校正统计数据集的操控性。当没观察到进一步的改进时(比如,在训练统计数据集上的操控性各方面),也能使用回调函数提前停止数学模型训练。上面的代码使用了这样的回调函数。图9显示了神经网络对训练统计数据 集和校正统计数据集的预测。

from keras.callbacks import EarlyStopping model = create_dnn_model(2, 256) callbacks = [EarlyStopping(monitor=loss, # 根据训练统计数据集的MSE值停止自学 patience=100, # 在一定的训练轮数后没改善就停止自学 restore_best_weights=True) # 当自学停止时保存最好的权重 ] h = model.fit(f_tr, l_tr, epochs=3000, verbose=False, validation_data=(f_va, l_va), # 指定校正统计数据子集 callbacks=callbacks) # 将回调函数传给fit()方式 fig, ax = plt.subplots(2, 1, sharex=True, figsize=(10, 8)) ax[0].plot(f_tr, l_tr, ro, label=training data) p = model.predict(f_tr) ax[0].plot(f_tr, p, –, label=fDNN (tr)) ax[0].legend() ax[1].plot(f_va, l_va, go, label=validation data) p = model.predict(f_va) ax[1].plot(f_va, p, –, label=fDNN (va)) ax[1].legend();

机器学习入门简介

图9 包括 DNN 预测的训练统计数据集和校正统计数据集

Keras允许对数学模型每一轮训练的两个统计数据集上MSE值的变化展开分析。从图10中能看出,MSE值随著训练轮数的减少而减小,但只是平均减小,而不是单调减小。

机器学习入门简介

图10 DNN数学模型在训练统计数据集和校正统计数据集上的MSE值

在OLS回归的情况下,可能会为阶数参数选择两个高但不太高的值,比如deg=9。神经网络数学模型的参数化会在训练结束时自动给出最佳数学模型配置。图11比较了两个数学模型之间的预测以及与测试统计数据集的预测。鉴于样品统计数据的性质,神经网络的测试统计数据集操控性更好一点儿并不令人惊讶。

p_ols = np.polyval(reg[5], f_te) p_dnn = model.predict(f_te).flatten() mse_ols = MSE(l_te, p_ols) print(fMSE of OLS: {mse_ols}) # Out: # MSE of OLS: 0.0038960346771028365 mse_dnn = MSE(l_te, p_dnn) print(fMSE of DNN: {mse_dnn}) # Out: # MSE of DNN: 0.0006873497338876613 plt.figure(figsize=(10, 6)) plt.plot(f_te, l_te, ro, label=test data) plt.plot(f_te, p_ols, –, label=OLS prediction) plt.plot(f_te, p_dnn, -., label=DNN prediction); plt.legend();

机器学习入门简介

图11 OLS 回归和DNN数学模型的测试统计数据集和预测

5. 偏差和方差

一般来说,机器自学中的两个主要问题是过拟合,特别是当机器自学算法应用于金融创新统计数据时。当校正统计数据集和测试统计数据集的操控性比训练统计数据集的操控性差时,就是数学模型过度拟合了其训练统计数据,使用OLS回归的示例能在视觉上和数字上说明这个问题。 上面的代码使用较小的子集展开训练和校正,并实现了线性回归和高阶回归。如图12所示,线性回归拟合在训练统计数据集上有较高的偏差,预测统计数据和条码统计数据之间的绝对差异相对较大。高阶拟合显示出了较高的方差,它精确地命中所有训练统计数据点,但为实现完美拟合,拟合本身变化会很大。

# 较少特点的统计数据子集 f_tr = f[:20:2] l_tr = l[:20:2] # 较少条码的统计数据子集 f_va = f[1:20:2] l_va = l[1:20:2] plt.figure(figsize=(10, 6)) # 高偏差 OLS 回归(线性) reg_b = np.polyfit(f_tr, l_tr, deg=1) # 高方差 OLS 回归(高阶) reg_v = np.polyfit(f_tr, l_tr, deg=9, full=True)[0] # 用于绘图的放大的特点统计数据集 f_ = np.linspace(f_tr.min(), f_va.max(), 75) plt.plot(f_tr, l_tr, ro, label=training data) plt.plot(f_va, l_va, go, label=validation data) plt.plot(f_, np.polyval(reg_b, f_), –, label=high bias) plt.plot(f_, np.polyval(reg_v, f_), –, label=high variance) plt.ylim(-0.2) plt.legend(loc=2);

机器学习入门简介

图12 高偏差和高方差的OLS回归拟合

如图12显示,在本例中,高偏差拟合比高方差拟合在训练统计数据集上的表现更差。但高方差拟合在很大程度上是过拟合,在校正统计数据集上表现得更差。这能通过比较所有情况下的谢鲁瓦操控性来说明。以下的代码不仅计算MSE 值,还计算 值。

from sklearn.metrics import r2_score def evaluate(reg, f, l): p = np.polyval(reg, f) # 平均差异绝对值做为数学模型偏差 bias = np.abs(l – p).mean() # 数学模型预测的方差做为数学模型方差 var = p.var() msg = fMSE={MSE(l, p):.4f} | R2={r2_score(l, p):9.4f} | msg += fbias={bias:.4f} | var={var:.4f} print(msg) # 高偏差数学模型在训练统计数据集上的操控性 evaluate(reg_b, f_tr, l_tr) # Out: # MSE=0.0026 | R2= 0.3484 | bias=0.0423 | var=0.0014 # 高偏差数学模型在校正统计数据集上的操控性 evaluate(reg_b, f_va, l_va) # Out: # MSE=0.0032 | R2= 0.4498 | bias=0.0460 | var=0.0014 # 高方差数学模型在训练统计数据集上的操控性 evaluate(reg_v, f_tr, l_tr) # Out: # MSE=0.0000 | R2= 1.0000 | bias=0.0000 | var=0.0040 # 高方差数学模型在校正统计数据集上的操控性 evaluate(reg_v, f_va, l_va) # Out: # MSE=0.8753 | R2=-149.2835 | bias=0.3565 | var=0.7540

结果表明,在训练统计数据集和校正统计数据集上,高偏差数学模型的操控性大致相当。相比之下,高方差数学模型在训练统计数据集上的操控性很好,在校正统计数据集上的操控性则相当差。

6. 交叉校正

避免过拟合的标准方式是交叉校正,在此过程中对多个训练统计数据集和校正统计数据集展开测试。scikit-learn包提供了以标准化方式实现交叉校正的功能,函数cross_val_score能用于任何人scikit-learn数学模型第一类。 上面的代码使用scikit-learn的多项式 OLS 回归数学模型在完整的样品统计数据集上实现 OLS回归方式,对最高多项式展开不同阶数的五折交叉验证。平均而言,回归中最高阶数越高,交叉校正得分就越差。当使用样品统计数据集中前20% 的统计数据(图3中左侧的统计数据)或最后20%的统计数据(图3中右侧的统计数据)展开校正时,观察到的结果尤为糟糕。但是,在 样品统计数据集中间20%的统计数据处,能观察到最佳校正分数。

from sklearn.model_selection import cross_val_score from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.pipeline import make_pipeline # 建立多项式回归数学模型类。 def PolynomialRegression(degree=None, **kwargs): return make_pipeline(PolynomialFeatures(degree), LinearRegression(**kwargs)) np.set_printoptions(suppress=True, formatter={float: lambda x: f{x:12.2f}}) # 调整 numpy 的默认打印设置 print(\nCross-validation scores) print(74 * =) for deg in range(0, 10, 1): model = PolynomialRegression(deg) # 实施五折交叉校正 cvs = cross_val_score(model, f.reshape(-1, 1), l, cv=5) print(fdeg={deg} | + str(cvs.round(2))) # Out: # Cross-validation scores # ========================================================================== # deg=0 | [ -6.07 -7.34 -0.09 -6.32 -8.69] # deg=1 | [ -0.28 -1.40 0.16 -1.66 -4.62] # deg=2 | [ -3.48 -2.45 0.19 -1.57 -12.94] # deg=3 | [ -0.00 -1.24 0.32 -0.48 -43.62] # deg=4 | [ -222.81 -2.88 0.37 -0.32 -496.61] # deg=5 | [ -143.67 -5.85 0.49 0.12 -1241.04] # deg=6 | [ -4038.96 -14.71 0.49 -0.33 -317.32] # deg=7 | [ -9937.83 -13.98 0.64 0.22 -18725.61] # deg=8 | [ -3514.36 -11.22 -0.15 -6.29 -298744.18] # deg=9 | [ -7454.15 -0.91 0.15 -0.41 -13580.75]

Keras提供了包装类来使用带有scikit-learn接口的Keras数学模型第一类,比如cross_val_ score函数。上面的例子使用KerasRegressor类来包装神经网络数学模型,并对其应用交叉校正。与OLS回归交叉校正分数相比,测试的两个网络的交叉校正分数始终更高。在这个例子中,神经网络容量并没发挥太大作用。

np.random.seed(100) tf.random.set_seed(100) from keras.wrappers.scikit_learn import KerasRegressor # from scikeras.wrappers import KerasRegressor # 低容量神经网络的包装类 model = KerasRegressor(build_fn=create_dnn_model, verbose=False, epochs=1000, hl=1, hu=36) # 低容量神经网络的交叉校正 cross_val_score(model, f, l, cv=5) # Out: # array([ -0.02, -0.01, -0.00, -0.00, # -0.08]) # 高容量神经网络的包装类 model = KerasRegressor(build_fn=create_dnn_model, verbose=False, epochs=1000, hl=3, hu=256) # 高容量神经网络的交叉校正 cross_val_score(model, f, l, cv=5) # array([ -0.05, -0.01, -0.00, -0.00, # -0.04])

一般而言,过拟合,即数学模型在训练统计数据集上比在校正统计数据集和测试统计数据集上表现得更好,在机器自学中是要避免的,尤其是在金融创新中。适当的评估结果流程和分析(比如交叉校正)有助于防止过拟合并能找到足够的数学模型容量。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务