乐趣区

关于数据挖掘:PYTHON用LSTM长短期记忆神经网络的参数优化方法预测时间序列洗发水销售数据

原文链接:http://tecdat.cn/?p=24431 

配置神经网络很艰难,因为没有对于如何去做的好的实践。

您必须系统地从动静和主观后果的角度摸索不同的参数配置,以尝试理解给定预测建模问题的状况。

在本教程中,您将理解如何摸索如何针对工夫序列预测问题配置 LSTM 网络参数。

实现本教程后,您将理解:

  • 如何调整和解释训练期间数的后果。
  • 如何调整和解释训练批次大小的后果。
  • 如何调整和解释神经元数量的后果。

如何应用 Keras 调整 LSTM 超参数以进行工夫序列预测
 

教程概述

本教程分为 6 个局部;他们是:

  1. 洗发水销售数据集
  2. 试验测试
  3. 调整期间数
  4. 调整批次大小
  5. 调整神经元的数量
  6. 后果总结

环境

本教程假如您已装置 Python SciPy 环境。您能够在此示例中应用 Python 2 或 3。

本教程假如您曾经装置了 Keras v2.0 或更高版本以及 TensorFlow。

本教程还假如您已装置 scikit-learn、Pandas、NumPy 和 Matplotlib。

洗发水销售数据集

该数据集形容了 3 年期间每月洗发水的销售量。

单位是销售计数,有 36 个察看值。

上面的示例加载并创立已加载数据集的图。

# 加载并绘制数据集


# 加载数据集

def paser(x):

return dattme.strptme('190'+x, '%Y-%m')

seres = read\_csv('sale.csv', header=0, pare\_dats=\[0\])

# 总结前几行

print(seres.head())

# 绘制线图

seres.plot()

运行示例将数据集加载为 Pandas 序列并输入前 5 行。

而后创立该序列的线图,显示出显著的减少趋势。

洗发水销售数据集的线图

接下来,咱们将看看试验中应用的 LSTM 配置和测试工具。

试验测试

本节介绍本教程中应用的测试工具。

数据拆分

咱们将把洗发水销售数据集分成两局部:训练集和测试集。

前两年的数据将用于训练数据集,残余的一年数据将用于测试集。

将应用训练数据集开发模型并对测试数据集进行预测。

测试数据集上的持久性预测实现了每月洗发水销量 136.761 的误差。这在测试集上提供了可承受的较低性能界线。

模型评估

应用滚动预测场景。

测试数据集的每个工夫步将一次走一个。模型将用于对工夫步长进行预测,而后将采纳测试集中的理论预期值,并将其提供给模型用于下一个工夫步长的预测。

这模仿了一个真实世界的场景,其中每个月都会有新的洗发水销售察看后果,并用于下个月的预测。

这将通过训练和测试数据集的构造进行模仿。咱们将以一次性办法进行所有预测。

将收集对测试数据集的所有预测,并计算误差以总结模型的技能。将应用均方根误差 (RMSE),因为它会惩办大误差并产生与预测数据(即每月洗发水销售量)雷同单位的分数。

数据筹备

在咱们将 LSTM 模型拟合到数据集之前,咱们必须转换数据。

在拟合模型和进行预测之前,对数据集执行以下三个数据转换。

  1. 转换工夫序列数据,使其安稳。具体来说,滞后 =1 差分以打消数据中的减少趋势。
  2. 将工夫序列转换为监督学习问题。具体来说,将数据组织成输出和输入模式,其中前一个工夫步的察看被用作预测以后工夫步的察看的输出
  3. 将观测值转换为特定的量纲。具体来说,将数据从新缩放到 -1 和 1 之间的值以满足 LSTM 模型的默认双曲正切激活函数。

在计算和误差之前,这些变换在预测中被返回到原始比例。

试验运行

每个试验计划将被运行 10 次。

这样做的起因是,LSTM 网络的随机初始条件在每次训练一个给定的配置时,会导致十分不同的后果。

一个诊断办法将被用来钻研模型配置。这就是将创立模型技能随工夫变动的线图(训练迭代称为 epochs),并对其进行钻研,以深刻理解一个给定的配置是如何执行的,以及如何调整它以取得更好的性能。

在每个历时完结时,模型将在训练和测试数据集上进行评估,并保留 RMSE 分数。

每个场景完结时的训练和测试 RMSE 分数将被打印进去,以显示进度。

训练和测试的 RMSE 分数系列在运行完结后被绘制成线图。训练得分用蓝色示意,测试得分用橙色示意。

让咱们深刻理解一下后果。
 

调整期间

咱们将查看调整的第一个 LSTM 参数是训练期间的数量。

该模型将应用一个批次 4 和单个神经元。咱们将摸索针对不同训练期间数训练此配置的成果。

500 期间 epoch 的诊断

代码正文得相当好,应该很容易了解。

# 可能在服务器上保留图像

matplotlib.use('Agg')




# 用于加载数据集的日期工夫解析函数

def paser(x):

return dateime.strptme('190'+x, '%Y-%m')



# 将一个序列设定为一个监督学习问题



colmns.appnd(df)
df = concat(colns, axis=1)



# 创立一个差分序列

diffene(dtaset, ieral=1):




# 将训练和测试数据扩大到 \[-1, 1\]。scae(train, test):

scler = salr.fit(train)

# 转换训练集

train = trin.rhape(tain.hpe\[0\], tran.shpe\[1\])


# 变换测试


tst_caed = scler.trnfom(test)




# 预测值的逆向缩放

inve_scle(saer, X, yhat):




# 在数据集上评估模型,以转换后的单位返回 RMSE

evaluate(mdel, rw\_data, scald\_dataet, caler)
# 离开

X, y = scald_daaset\[:,0:-1\], saleddaaset\[:,-1)

# 重塑

reshaed = X.reshpe(len(X), 1, 1)

# 预测数据集

predict(rshped, bth_ize=tchsize)

# 在预测中反转数据变换


for i in rage(len(outut)):

yat = output\[i,0\]

# 反转比例

yhat = inrtscle(saer, X\[i\], yhat)

# 反转差分

yhat = yhat + raaa\[i\]。# 存储预测

pdiis.ppd(yhat)

# 报告性能

rmse = srt(mensuederror pricions) )





# 对训练数据进行 LSTM 网络拟合

fitlstm(tran, tet, raw, caler bath\_sie, n\_eoch, erns):


# 筹备模型

model = Sequential()

moel.ad(LSTM(neons, bh_phpe, stateful)


# 拟合模型


for i in range(nb_epoch):

fit(X, y, epocs=1, bathsze, verose=0, shufle=False)


# 在训练数据上评估模型


mse.apend(evalaion(mdel, rawtain, trai, scler, 0, bcize))


# 在测试数据上评估模型

rmse.append(evalh_size))



# 运行诊断性试验
run():

# 载入数据集

read_csv('sale.csv'

# 将数据转化为安稳的


diffe(raues, 1)

# 将数据转化为有监督的学习

supd = timespevied(diues, 1)

suplues = supd.vales

# 将数据分成训练集和测试集

train, test = supues\[0:-12\], suplues\[-12:\]。# 扭转数据的尺度

scar, traaled, tescaled = scale(tain, tst)

# 拟合和评估模型

traed = trainld\[2:, :\]

# 配置

reas = 10

nbch = 4

nphs = 500

nnens = 1

# 运行诊断性测试

for i in range(ret):

fit(train, tes, rawues, scler, nbth, necs, neons)

留神 :思考到算法或评估程序的随机性,或数值精度的差别。思考屡次运行该示例并比拟均匀后果。

运行试验会在 10 次试验运行完结时输入训练和测试集的 RMSE。

还创立了每个训练期间之后训练集和测试集上的一系列 RMSE 分数的线图。

500 个期间的诊断后果

后果分明地表明,简直所有试验运行的 RMSE 在训练期间都有降落趋势。

它表明模型正在学习问题并且具备肯定的预测能力。事实上,所有最终测试分数都低于在这个问题上实现 136.761 的 RMSE 的简略持久性模型(奢侈预测)的误差。

结果表明,更多的训练期间将产生更纯熟的模型。

让咱们尝试将 epoch 数从 500 加倍到 1000。

1000 个期间的诊断

在本节中,咱们应用雷同的试验设置并拟合模型超过 1000 个训练期间。

具体来说,在 _run()_ 函数中将 _n_epochs_ 参数设置为 _1000_。

nepohs = 1000

留神 :思考到算法或评估程序的随机性,或数值精度的差别。思考屡次运行该示例并比拟均匀后果。

运行该示例会输入最初一个 epoch 中训练集和测试集的 RMSE。

还创立了每个期间的测试和训练 RMSE 分数的线图。

1000 个期间的诊断后果

咱们能够看到,模型误差的降落趋势的确在持续,而且仿佛在放缓。

训练和测试用例的线条变得更加程度,但仍广泛出现降落趋势,只管变化率较低。一些测试谬误的例子显示了大概 600 个期间可能呈现的拐点,并且可能显示出回升趋势。

咱们对测试集上继续改良的均匀性能感兴趣,而且这种状况可能会继续上来。

让咱们尝试将 epoch 数从 1000 增加一倍到 2000。

2000 期间 Epoch 的诊断

在本节中,咱们应用雷同的试验设置并拟合模型超过 2000 个训练期间。

具体来说,在_run()_ 函数中将 _npoch_参数设置为 2000。

nepoch = 2000

留神 :思考到算法或评估程序的随机性,或数值精度的差别。思考屡次运行该示例并比拟均匀后果。

运行该示例会输入最初一个 epoch 中训练集和测试集的 RMSE。

还创立了每个期间的测试和训练 RMSE 分数的线图。

2000 期间 epoch 的诊断后果

正如人们可能曾经猜到的那样,在训练和测试数据集上的额定 1000 个 epoch 中,误差的降落趋势仍在持续。

值得注意的是,大概一半的案例在运行完结之前始终在缩小误差,而其余的则显示出减少趋势的迹象。

增长的趋势是适度拟合的标记。这是当模型适度拟合训练数据集时,其代价是测试数据集上的性能降落。它的例子是在训练数据集上的继续改良,以及在测试数据集上的拐点和最差技能之后的改良。在测试数据集上,只有不到一半的运行显示了这种类型的模式的开始。

尽管如此,测试数据集上的最终历时后果还是十分好。咱们能够通过更长的训练看到进一步的收益。

让咱们尝试将历时数翻倍,从 2000 到 4000。
 

4000 个期间的诊断

在本节中,咱们应用雷同的试验设置并拟合模型超过 4000 个训练期间。

具体来说,在_run()_ 函数中将 _n_epochs_参数设置为 4000。

nepocs = 4000

留神 :思考到算法或评估程序的随机性,或数值精度的差别。思考屡次运行该示例并比拟均匀后果。

运行该示例会输入最初一个 epoch 中训练集和测试集的 RMSE。

还创立了每个期间的测试和训练 RMSE 分数的线图。

4000 epoch 的诊断后果

即便超过 4000 个 epoch,也有进步性能的总体趋势。存在一种重大过拟合的状况,即测试误差急剧回升。

同样,大多数运行以“良好”(比持久性更好)的最终测试谬误完结。

后果总结

下面的诊断运行有助于摸索模型的动静行为,但不足主观和可比拟的均匀性能。

咱们能够通过反复雷同的试验并计算和比拟每个配置的汇总统计来解决这个问题。在这种状况下,实现了 30 次运行,工夫值为 500、1000、2000、4000 和 6000。

这个想法是应用大量运行的汇总统计来比拟配置,并确切地查看哪些配置的均匀性能可能更好。

上面列出了残缺的代码示例。

# 运行一个反复试验

epernt(rpeas, sris, ochs):

# 将数据转化为安稳的


dif_vues = diferne(ravaues, 1)

# 将数据转换为有监督的学习

to\_spersed(dif\_vles, 1)

# 将数据分成训练集和测试集

train, test = spervsed\[0:-2\], suervues\[-12:\]。# 扭转数据的尺度
scale(train, test)

# 运行试验


for r in range(reeats):

# 拟合模型

size = 4

trtried = traled\[2:, :\]

ltmol = lstm(tamd, bachsie, eohs, 1)

# 预测整个训练数据集,以建设预测的状态

trainmd\[:, 0\].resape(lentran_tmmed), 1, 1)
predict(tain\_rsaped, ah\_size=ath_ize)

# 预测测试数据集

te_sapd = tstscaled\[:,0:-1)

predict(testped, btze=btc_sze)



for i in range(len(outut)):
yhat = output\[i,0\]
X = te_saled\[i, 0:-1\]。# 反转比例

yhat = invere(aler, X, yhat)

# 反转差分

yht = invsefece(raw_aues, yat, len+1-i)

# 报告性能

sqrt(men\_sqred\_eror(a_vals\[-12:\], pedins) )


# 扭转训练历时

echs = \[500, 1000, 2000, 4000, 6000\]。for e in eochs:
 exiet(rpats, sries, e)

# 总结后果
boxlot()

运行代码首先输入 5 个配置中每一个的汇总统计信息。值得注意的是,这包含来自每个后果群体的 RMSE 分数的平均值和标准差。

平均值给出了配置的均匀预期性能的概念,而标准差给出了方差的概念。最小和最大 RMSE 分数还给出了可能冀望的最佳和最坏状况示例的范畴。

仅查看均匀 RMSE 分数,结果表明配置为 1000 的 epoch 可能更好。后果还表明,可能须要对 1000 至 2000 之间的值进行进一步剖析。

散布也显示在箱线图上。这有助于理解散布如何间接比拟。

红线显示中位数,方框显示第 25 个和第 75 个百分位数,或中位数 50% 的数据。这种比拟还表明,将 epochs 设置为 1000 的抉择优于测试的代替计划。它还表明,能够在 2000 或 4000 次迭代时获得最佳性能,但代价是均匀性能更差。

总结 Epoch 后果的箱线图

接下来,咱们将看看批次大小的影响。

调整批次大小

批次大小管制更新网络权重的频率。

重要的是,在 Keras 中,批量大小必须是测试和训练数据集大小的一个因素。

在上一节探讨训练 epoch 数的局部中,批大小固定为 4,它分为测试数据集(大小为 12)和测试数据集(大小为 20)。

在本节中,咱们将探讨扭转批大小的影响。咱们将训练 epoch 的数量放弃在 1000。

诊断 1000 个期间和批次大小为 4

作为揭示,上一节在第二次试验中评估了批量大小为 4,历时数为 1000 的试验。

1000 个期间的诊断后果

诊断 1000 个期间和批次大小为 2

在本节中,咱们着眼于将批大小从 4 减半至 2。

这个改变是 对_run()_ 函数中的 _n_batch_参数进行的;例如:

n_batch = 2

运行该示例显示了与批大小为 4 雷同的总体性能趋势,可能在最初一个期间具备更高的 RMSE。

运行可能会显示出更早稳固 RMES 的行为,而不是仿佛持续降落趋势。

上面列出了每次运行最终的 RSME 分数。

 

还创立了每个期间的测试和训练 RMSE 分数的线图。

1000 个期间和批次大小为 2 的诊断后果

让咱们再次尝试应用批量大小。

诊断 1000 个期间和批次大小为 1

这是在每个训练模式之后更新网络。能够与批量学习造成比照,其中权重仅在每个 epoch 完结时更新。

咱们能够 在_run()_ 函数中更改 _n_batch_参数;例如:

n_batch = 1

同样,运行该示例会输入每次运行的最初一期的 RMSE 分数。

还创立了一个每个历时的测试和训练 RMSE 分数的线图。

该图表明,随着工夫的推移,测试 RMSE 有更多的变动,兴许训练 RMSE 比大批量的测试 RMSE 稳固得更快。测试 RMSE 的变异性减少是意料之中的,因为每次更新对网络所做的扭转都会带来很少的反馈。

该图还表明,如果配置被赋予更多的训练历时,兴许 RMSE 的降落趋势会继续下去。
 

1000 个期间和批次大小为 1 的诊断后果

后果总结

与训练期间一样,咱们能够主观地比拟网络在给定不同批次大小的状况下的性能。

每个配置运行 30 次,并依据最终后果计算汇总统计信息。

# 运行一个反复的试验


# 将数据转换为安稳的

raw_vues = sres.values

df_vaues = difence(rvalues, 1)

# 将数据转换为监督学习


suesr_lus = surior.values

# 将数据分成训练集和测试集

# 变换数据的尺度

tra_cled,testscld = scale(tain, tet)

# 运行试验



# 拟合模型

tran\_timed = tan\_saled\[2:, :\]

lstmmdl = lstm(tainrmd, ach_e, 1000, 1)

# 预测整个训练数据集以建设预测状态


preit(trairehae,bach\_ie=bat\_size)# 预测测试数据集

preict(tst\_rehapeatc\_ze=bathsize)X = tes_cd\[i, 0:-1\]

# 反转缩放

yht = ivetcale(aler, X, yhat)

# 反转差分

yat = invese_dfence(awvalus, yat, le(tetsald)+1-i)


# 报告体现

rmse = sqrt(mean_urerror)


# 加载数据集


# 试验

# 扭转训练批次

批次 = \[1, 2, 4\]

boxplot()

仅从均匀性能来看,结果表明批量大小为 1 时 RMSE 较低。正如上一节所述,这可能会随着更多的训练期间而失去进一步改善。

还创立了数据的箱线图,以帮忙以图形形式比拟散布。该图将中值性能显示为一条红线,其中批次大小为 4 显示最大的差别和最低的中值 RMSE。

调整神经网络是均匀性能和该性能的可变性的衡量,现实后果具备低平均误差和低可变性,这意味着它通常是好的和可反复的。

总结批次大小后果的箱线图

调整神经元的数量

在本节中,咱们将钻研扭转网络中神经元数量的影响。

神经元的数量影响网络的学习能力。一般来说,更多的神经元可能以更长的训练工夫为代价从问题中学习更多的构造。更多的学习能力也会产生潜在的适度拟合训练数据的问题。

咱们将应用 4 和 1000 个训练期间的批量大小。

1000 个期间和 1 个神经元的诊断

咱们将从 1 个神经元开始。

揭示一下,这是从 epochs 试验中测试的第二个配置。

1000 个期间的诊断后果

1000 个期间和 2 个神经元的诊断

咱们能够将神经元的数量从 1 减少到 2。这无望进步网络的学习能力。

咱们能够通过更改_run()_ 函数中的_n_neurons_ 变量 来做到这一点。

n_neurons = 2

运行此配置会输入每次运行的最初一个期间的 RMSE 分数。

结果表明,总体体现不错,但不是很好。

还创立了每个期间的测试和训练 RMSE 分数的线图。

这更能阐明问题。它显示了测试 RMSE 的疾速降落,大概在 500-750 个期间中,一个拐点显示了测试 RMSE 的回升,简直所有的运行都是如此。同时,训练数据集显示继续降落到最初一期。

这些都是训练数据集过拟合的迹象。

 
 

1000 个期间和 2 个神经元的诊断后果

让咱们看看这种趋势是否会随着更多的神经元而持续。

1000 个期间和 3 个神经元的诊断

本节着眼于将神经元数量减少到 3 的雷同配置。

n_neurons = 3

运行此配置会输入每次运行的最初一个期间的 RMSE 分数。

后果与上一节相似;咱们看不到 2 或 3 个神经元的最终 epoch 测试分数之间的个别差别。3 个神经元的最终训练分数仿佛的确较低,这可能表明适度拟合减速。

训练数据集中的拐点仿佛比 2 个神经元试验产生得更早,可能在 300-400 期。

这些神经元数量的减少可能受害于减缓学习速度的额定变动。例如应用正则化办法,如 dropout,缩小批量大小,缩小训练期间的数量。

还创立了每个期间的测试和训练 RMSE 分数的线图。

1000 个期间和 3 个神经元的诊断后果

后果总结

同样,咱们能够主观地比拟减少神经元数量同时放弃所有其余网络配置的影响。

在本节中,咱们将每个试验反复 30 次,并将均匀测试 RMSE 性能与 1 到 5 的神经元数量进行比拟。

# 运行一个反复的试验


# 将数据转换为安稳的

ra_lus = sees.values

difvles = difece(rwvlus, 1)

# 将数据转换为监督学习


sups_ales = supvor.values

# 将数据分成训练集和测试集


# 变换数据的尺度

trainsld,tet_scld = scale(tain, est)

# 运行试验

err_scres = list()


# 拟合模型


trntied = tr_aed\[2:, :\]

lsmel = lstm(tritid, bahze, 1000, eons)

# 预测整个训练数据集以建设预测状态

trrehap = ti\_rimed\[:, 0\].rehae(len(train\_trimmed), 1, 1)

prdict(trahpe,bahe=achze)# 预测测试数据集

tet_sape = tetsaled\[:,0:-1\]
tetrehae = tesespe.reshape(len(tst_ehape), 1, 1)

prect(tes\_rhpe,bath\_ize=btchsze)X = ts_cld\[i, 0:-1\]

# 反转缩放

yhat = ivertle(scaer, X, yhat)

# 反转差分

yht = inversefrce(rw\_values, hat, len(tet\_saed)+1-i)

# 报告体现

rmse = sqrt(men\_sureero(aw\_vue\[-12:\], preiions))



# 加载数据集


# 试验




# 扭转神经元

神经元 = \[1, 2, 3, 4, 5\]


boxplot()

运行试验会输入每个配置的摘要统计信息。

仅从均匀性能来看,结果表明具备 1 个神经元的网络配置在 1000 个 epoch 中具备最佳性能,批量大小为 4。

盒须图显示了中值测试集性能的显著趋势,其中神经元的减少导致测试 RMSE 的相应减少。

总结神经元后果的盒须图

所有后果的总结

在本教程中,咱们在洗发水销售数据集上实现了相当多的 LSTM 试验。

一般来说,仿佛有状态的 LSTM 配置了 1 个神经元,批量大小为 4,并且训练了 1000 个 epochs 可能是一个很好的配置。

后果还表明,兴许这种批量大小为 1 并且适宜更多 epoch 的配置可能值得进一步摸索。

调整神经网络是一项艰巨的实证工作,事实证明 LSTM 也不例外。

本教程展现了配置行为随工夫的诊断钻研以及测试 RMSE 的主观钻研的益处。

扩大

本节列出了对本教程中执行的试验进行扩大的一些想法。

如果您摸索其中任何一个,请在评论中报告您的后果;我很想看看你想出了什么。

  • dropout。应用正则化办法(例如循环 LSTM 连贯上的 dropout)减慢学习速度。
  • 。通过在每层增加更多层和不同数量的神经元来摸索额定的分层学习能力。
  • 正则化 。摸索如何使用权重正则化(例如 L1 和 L2)来减缓网络在某些配置上的学习和适度拟合。
  • 优化算法 。例如经典梯度降落,以查看减速或减慢学习的特定配置是否会带来益处。
  • 损失函数
  • 特点和工夫步长 。摸索应用滞后察看作为输出特色和特色的输出工夫步长,看看它们作为输出的存在是否能够进步模型的学习和 / 或预测能力。
  • 更大的批量 。摸索大于 4 的批量大小,可能须要进一步解决训练和测试数据集的大小。

概括

在本教程中,您理解了如何系统地钻研 LSTM 网络的配置以进行工夫序列预测。

具体来说,你学到了:

  • 如何设计用于评估模型配置的零碎测试工具。
  • 如何随着工夫的推移应用模型诊断以及主观预测误差来解释模型行为。
  • 如何摸索和解释训练期间数、批量大小和神经元数量的影响。

您对调整 LSTM 或本教程有任何疑难吗?
在上面的评论中提出您的问题,咱们会尽力答复。


 

最受欢迎的见解

1. 用于 NLP 的 Python:应用 Keras 的多标签文本 LSTM 神经网络分类

2.Python 中利用长短期记忆模型 LSTM 进行工夫序列预测剖析 – 预测电力耗费数据

3.python 在 Keras 中应用 LSTM 解决序列问题

4.Python 中用 PyTorch 机器学习分类预测银行客户散失模型

5.R 语言多元 Copula GARCH 模型工夫序列预测

6. 在 r 语言中应用 GAM(狭义相加模型)进行电力负荷工夫序列剖析

7.R 语言中 ARMA,ARIMA(Box-Jenkins),SARIMA 和 ARIMAX 模型用于预测工夫序列数

8.R 语言预计时变 VAR 模型工夫序列的实证钻研剖析案例

9. 用狭义加性模型 GAM 进行工夫序列剖析

退出移动版