Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测

2023-05-16

近日,Artur Suilin 等人发布了 Kaggle 网站流量时序预测竞赛第一名的详细解决方案。他们不仅公开了所有的实现代码,同时还详细解释了实现的模型与经验。机器之心简要介绍了他们所实现的模型与经验,更详细的代码请查看 GitHub 项目。


GitHub 项目地址:https://github.com/Arturus/kaggle-web-traffic


下面我们将简要介绍 Artur Suilin 如何修正 GRU 以完成网站流量时序预测竞赛。


预测有两个主要的信息源:

  1. 局部特征。我们看到一个趋势时,希望它会继续(自回归模型)朝这个趋势发展;看到流量峰值时,知道它将逐渐衰减(滑动平均模型);看到假期交通流量增加,就知道以后的假期也会出现流量增加(季节模型)。
  2. 全局特征。如果我们查看自相关(autocorrelation)函数图,就会注意到年与年之间强大的自相关和季节间的自相关。


我决定使用 RNN seq2seq 模型进行预测,原因如下:

  1. RNN 可以作为 ARIMA 模型的自然扩展,但是比 ARIMA 更灵活,更具表达性。
  2. RNN 是非参数的,大大简化了学习。想象一下对 145K 时序使用不同的 ARIMA 参数。
  3. 任何外源性的特征(数值或类别、时间依赖或序列依赖)都可以轻松注入该模型。
  4. seq2seq 天然适合该任务:我们根据先前值(包括先前预测)的联合概率(joint probability)预测下一个值。使用先前预测可保持模型稳定,因为误差会在每一步累积,如果某一步出现极端预测,则有可能毁了所有后续步的预测质量。
  5. 现在的深度学习出现了太多的炒作。

特征工程

RNN 足够强大来发现和学习自身特征。模型的特征列表如下:

  • pageviews:原始值经过 log1p() 的转换得到几乎正态的时序内值分布,而不是偏态分布。
  • agent, country, site:这些特征从网页 url 中提取,然后经过 One-Hot 编码。
  • day of week:捕捉每周的季节效应。
  • year-to-year autocorrelation, quarter-to-quarter autocorrelation:捕捉各年、各季度的季节效应。
  • page popularity:高流量和低流量页面具有不同的流量变化模式,该特征(pageviews 的中间值)帮助捕捉流量规模。pageviews 特征丢失了规模信息,因为每个 pageviews 序列被独立归一化至零均值和单位方差。
  • lagged pageviews:之后将具体介绍。

特征预处理

所有特征(包括 One-Hot 编码的特征)被归一化至零均值和单位方差。每个 pageviews 序列被独立归一化。


时间依赖特征(自相关性、国家等)被「拉伸」至时序长度,即每天重复使用 tf.tile() 命令。


模型在来自初始时序的随机固定长度样本上进行训练。例如,如果初始时序长度是 600 天,我们使用 200 天的样本进行训练,那么我们可以在前 400 天中随意选择开始采样的样本。


该采样工作是一种有效的数据增强机制:训练代码在每一步随机选择每次时序的开始点,生成无限量的几乎不重复的数据。


模型的核心技术

模型主要由两部分组成,即编码器和解码器。

编码器为 cuDNN GRU,cuDNN 要比 TensorFlow 的 RNNCells 快大约 5 到 10 倍,但代价就是使用起来不太方便,且文档也不够完善。


解码器为 TF GRUBlockCell,该 API 封装在 tf.while_loop() 中。循环体内的代码从上一步获得预测,并加入到当前时间步的输入特征中。


处理长时间序列


LSTM/GRU 对于相对较短的序列(100-300 项以内)来说是非常好的解决方案。但对于较长的序列来说,LSTM/GRU 仍然有效,只不过会逐渐遗忘较早时间步所包含的信息。Kaggle 竞赛的时间序列长达 700 多天,所以我们需要找一些方法来「加强」GRU 的记忆力。


我们第一个方法先是考虑使用一些注意力机制。注意力机制可以将过去较长距离的有用信息保留到当前 RNN 单元中。对于我们的问题,最简单高效的注意力方法是使用固定权重的滑动窗口注意力机制。它在较长距离的过去时间步上有两个重要的点(考虑长期的季节性),即 1 年前和 1 个季度前。

我们可以采用 current_day - 365 和 current_day - 90 这两个时间点的编码器输出,并将它们馈送到全连接层以降低维度,并将结果加入到解码器的输入特征中。这个解决方案虽然简单却大大降低了预测误差。


随后我们将重要的点与它们的近邻求均值,并借此减少噪声和补偿不均匀的间隔(闰年和不同长度的月份):attn_365 = 0.25 * day_364 + 0.5 * day_365 + 0.25 * day_366。


但随后我们意识到 0.25、0.5、0.25 是一个一维卷积核(length=3),我们可以自动学习更大的卷积核以检测过去重要的点。


最后,我们构建了一个非常大的注意力机制,它会查看每一个时间序列的「指纹」(指纹由较小的卷积网络产生),并决定应该注意哪些点和为较大卷积核生成权重。这个应用于解码器输出的较大卷积核会为每一个预测的日期生成一个注意力特征。虽然最后没有使用这种方法,但这个注意力机制仍然保留在代码中,读者可以在模型代码中找到它。


注意,我们并没有使用经典的注意力方案(Bahdanau 或 Luong 注意力机制),因为经典的注意力机制应该在每个预测步上使用所有的历史数据点从头开始计算,因此这种方法对于较长时间序列(约两年的天数)来说太耗时间了。所以我们的方案将会对所有数据点进行一次卷积,对所有预测时间步使用相同的注意力权重(这也是缺点),这样的方案计算起来要快很多。


因为我们对注意力机制的复杂度感到不太满意,因此我们试图完全移除注意力机制,并将一年前、半年前、一季度前重要的数据点作为编码器和解码器的附加特征。这样的结果是非常令人惊讶的,甚至在预测质量方面都要比带注意力机制的模型略胜一筹。因此我们最好的公开分数都是仅使用滞后(lagged)数据点实现的,它们都没有使用注意力机制。

滞后数据点另一个重要的优势是,模型可以使用更短的编码器而不需要担心损失过去的信息,因为这些信息现在明确地包含在特征中。在采用这种方法后,即使我们编码器的长度是 60 到 90 天,结果也是完全可以接受的,而以前需要 300-400 天的长度才能获得相同的性能。此外,更短的编码器就等于更快速的训练和更少的信息损失。


损失和正则化


SMAPE(竞赛用的目标损失函数)因其在零值周围不稳定的行为而无法直接使用(当真值为零的时候,损失函数是阶跃函数;预测值也为零的时候,则损失函数不确定)。


我使用经平滑处理的可微 SMAPE 变体,它在所有实数上都表现良好:

        
  
  
  1. epsilon = 0.1

  2. summ = tf.maximum(tf.abs(true) + tf.abs(predicted) + epsilon, 0.5 + epsilon)

  3. smape = tf.abs(predicted - true) / summ * 2.0


另一个选择是在 log1p(data) 上的 MAE 损失函数,它很平滑,且训练目标与 SMAPE 非常接近。


最终预测取最接近的整数,负面预测取零。


我尝试使用论文《Regularizing RNNs by Stabilizing Activations》中经正则化的 RNN 激活值,因为 cuDNN GRU 的内部权重无法直接正则化(也可能是我没有找到正确的方法)。稳性损失(Stability loss)不起作用,激活损失可以为较小损失权重(1e-06..1e-05)带来少许改进。


训练和验证


我使用 COCOB 优化器(详见论文《Training Deep Networks without Learning Rates Through Coin Betting》)结合梯度截断进行训练。COCOB 尝试预测每个训练步的最优学习率,因此我完全不必调整学习率。它的收敛速度也比传统的基于动量的优化器快得多,尤其是在第一个 epoch 上,可以让我及早停止不成功的实验。


有两种方式可以将时序分割为训练和验证数据集:

  1. Walk-forward 分割。这实际上不是分割:我们在完整数据集上训练和验证,但使用不同的时间跨度。验证用的时间跨度比训练用时间跨度前移一个预测间隔。
  2. Side-by-side 分割。这是主流机器学习传统的分割模型。数据集被分割成两个独立的部分,一个用于训练,另一个用于验证。

两种方式我都试了,但对于这个任务来说 Walk-forward 更好,因为它与竞赛目标直接相关:使用历史值预测未来值。但是该分割破坏了时序结尾的数据点,使得训练准确预测未来的模型变得困难。


具体来说:比如,我们有 300 天的历史数据,想预测接下来 100 天的数据。如果我们选择 walk-forward 分割,我们必须使用前 100 天的数据用于真实训练,后面 100 天的数据用于训练模式的预测(运行解码器、计算损失),再后面 100 天的数据用于验证,最后 100 天用于对未来值真正进行预测。因此,我们实际上可以使用 1/3 的数据点来训练,最后一个训练数据点和第一个预测数据点之间隔了 200 天。间隔太大了,因为一旦我们离开某个训练数据,预测质量将出现指数级下降(不确定性增加)。使用 100 天差距训练的模型预测质量相对较好。


Side-by-side 分割所需要的计算力更少,因为它在端点时并不会消耗数据点。但是对于我们的数据,模型在验证集上的性能与在训练集上的性能是强相关的,并且与将来的实际模型性能几乎不具有相关性。换而言之,并行分割对于我们的问题基本上是没有什么作用的,它只是复制了在训练数据集上观察到的模型损失。


我仅使用验证集(带有前向分步分割)进行模型调优,预测未来数值的最终模型只是在盲目的模式中进行训练,没有使用任何验证集。


降低模型方差


优于强噪音数据的输入,模型不可避免地具有高方差。坦白讲,我很惊讶 RNN 居然从噪音数据中学习到了东西。


在不同 seed 上训练的相同模型具有不同的表现,有时模型甚至在「不幸」的 seed 上变得发散。训练期间,表现也会逐步地发生很大波动。依靠纯粹的运气很难赢得比赛,因此我决定采取行动降低方差。

  1. 我不知道哪个训练步骤最适合预测未来(但前数据的验证结果与未来数据的结果只有弱相关关系),所以我不能使用提前停止。但是我知道近似区域,其中模型(可能)进行了充分训练,但(可能)没有开始过拟合。我决定把这个最佳区域设置为 10500 到 11500 次迭代区间内,并且从这个区域的每第 10000 个步骤保存 10 个检查点。
  2. 相似地,我决定在不同的 seed 上训练 3 个模型,并从每个模型中保存检查点。因此我一共有 30 个检查点。
  3. 降低方差、提升模型性能的一个众所周知的方法是 ASGD(SGD 平均)。它很简单,并在 TensorFlow 中得到很好的支持。我们必须在训练期间保持网络权重的移动平均值,并在推断中使用这些平均权重,而不是原来的权重。

三个模型的结合表现不错(在每个检查点上使用平均模型权重的 30 个检查点的平均预测)。我在排行榜上(针对未来数据)获得了相较于历史数据上的验证大致相同的 SMAPE 误差。


理论上讲,你也可以把前两种方法用作集成学习,但我主要用其降低方差。


超参数调节


很多模型参数(层的数量、深度,激活函数,dropout 系数等)能够(并且应该)被调节从而获得更优的模型表现。手动调节乏味且费时,所以我决定自动化该过程,并使用 SMAC3 搜索超参数。下面是 SMAC3 的一些优势:

  • 支持条件参数(例如,为每层联合调节层数和 dropout;如果 n_layers > 1,第二层上的 dropout 将被调节)
  • 明确处理模型方差。SMAC 在不同种子上训练每个模型的若干个实例,如果实例在相同种子上训练还要对比模型。如果它在所有相同种子上优于另一个模型,则该模型获胜。

与我的期望相反,超参数搜索并没有建立定义明确的全局最小。所有的最佳模型大致具有相同的性能,但参数不同。可能 RNN 模型对于这个任务来说太具有表现力了,并且最好的模型得分更多依赖于模型架构上的数据信噪比。不管怎样,最好的参数设置依然可以在 hparams.py 文件中找到。


原文链接:https://github.com/Arturus/kaggle-web-traffic/blob/master/how_it_works.md

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 的相关文章

  • 游戏大厅类软件 Demo系列(二)

    游戏大厅类软件 DSkinLite界面库Demo系列 xff08 二 xff09 游戏大厅类软件是UIEASY开发团队制作的又一个软件demo xff0c 此次发布只是一个雏形 xff0c 我们还将继续完善此Demo xff0c 使其各项功
  • 窗口控件透明效果的实现--DSkinLite界面库使用技巧

    DSkinLite 界面库使用技巧 二 窗口控件透明效果 界面设计中 xff0c 很多效果需要借助透明效果来实现 不幸的是 xff0c Windows 标准控件基本不支持透明效果 因此我们需要自己来实现透明效果 一般来说所谓控件透明 xff
  • DSkinControl( For MFC) 控件- dsCtrlComboBox

    原文地址 xff1a http www uieasy cn blog p 61 513 传统的combobox 在使用方面有很多限制 xff0c 很难满足我们combobox类型控件的需求 主要表现中combobox内置的listbox难以
  • 图像典型特征描述子Haar

    以下文章摘录自 xff1a 机器学习观止 核心原理与实践 京东 xff1a https item jd com 13166960 html 当当 xff1a http product dangdang com 29218274 html 由
  • oracle触发器执行用户和v$session的查询

    oracle触发器 xff0c 由针对表的动作触发 xff0c 其执行用户为当前表的所有者 xff0c 所以在触发器中涉及的权限问题 xff0c 应该和触发器所基于的表的所有者有关 对于v session的查询 xff1a 要明确的是 xf
  • springboot打包docker镜像部署

    springboot打包docker镜像部署 环境准备 机器 vultr一台 centos7 资源下载 jdk8 maven git yum install git docker yum install docker io 环境搭建 jdk
  • 深度学习基础——简单了解meta learning(来自李宏毅课程笔记)

    知乎同名账号同步发布 目录 一 初步了解二 和ML的差异三 应用了解 一 初步了解 我们以分类问题为例 xff0c 以前 xff0c 学习的目的是学习一个二元分类器 f f f xff1b 现在 xff0c 学习的
  • docker删除镜像及容器

    问题 清理服务器相关无用docker镜像及容器 删除镜像image 要删除 Docker 中的镜像 xff0c 可以使用 docker rmi 命令 请注意 xff0c 删除镜像前请确保不再需要它 xff0c 并且已经停止了使用该镜像的所有
  • 云技术:弹性计算ECS

    云计算 xff08 Cloud Computing xff09 被业界看作继大型计算机 个人计算机 互联网之后的第四次IT产业革命 xff0c 正日益成为未来互联网与移动技术相结合的一种新兴计算模式 云计算提供了IT基础设施和平台服务的新模
  • 如何在 docker 容器中安装 ROS

    本文记录在 docker ubuntu 18 04 环境下安装 ROS xff08 机器人操作系统 xff09 的过程 目录 文章目录 目录安装 ROS参考文献 安装 ROS 安装步骤如下 xff1a span class token co
  • DOCKER个人遇见小问题

    1 在写dockerfile的时候使用了echo的方式向文件里面写入 基本格式是 echo 34 想要写入的操作 34 gt gt gt 路径 dockerfile 1 因为是要向文件里面进行一个写操作同时希望建立容器的时候执行这个操作 所
  • Tips and Tricks for Visual Question Answering: Learnings from the 2017 Challenge阅读笔记

    本文提出了一种基于深度神经网络的VQA模型 xff0c 并报告了一套广泛的实验来确定每个设计选择的贡献和替代设计的性能 它提供了关于VQA模型各个组件重要性的指示器 xff0c 一 Summary of findings 1 使用一个sig
  • Ubuntu系统用VNCViewer连不上远程的解决办法

    有时Ubuntu重启电脑重新联网之后 xff0c 用VNCViewer远程时提示timeout 解决办法 点击Ubuntu电脑系统的设置按钮 xff0c 进入共享选项卡 检查远程登录是不是已经开启 xff0c 屏幕共享是不是活动状态 屏幕共
  • OAuth2.0的四种授权方式

    前言 OAuth 简单理解就是一种授权机制 xff0c 它是在客户端和资源所有者之间的授权层 xff0c 用来分离两种不同的角色 在资源所有者同意并向客户端颁发令牌后 xff0c 客户端携带令牌可以访问资源所有者的资源 OAuth2 0 是
  • PowerBuilder---合并相同单元格

    在用数据窗口显示数据时 xff0c 经常会出现某一列的连续多行内容是相同的 xff0c 在有中国特色的软件使用者看来这是一个很大的问题 一定要合并才能显得规范 如下图 xff1a PowerBuilder 合并相同单元格 qibin jin
  • 各行业的英语术语(绝对精华 1)

    不看不知道 各行业的英语术语 xff08 绝对精华 xff09 化妆品中英文对照 makeup xff08 粉底 xff09 mask xff08 面膜 xff09 mascara xff08 睫毛膏 xff09 milk xff08 乳
  • SD-WAN与SDN:揭开差异 如何选择虚拟化网络

    随着物联网 工业互联网等新兴业务场景的不断涌现 xff0c 网络正面临着开放 融合 智能化 个性化等需求 在SDN进入稳定爬升期 xff0c 还未完全落地之时 xff0c 以SD WAN xff08 软件定义的广域网 xff09 为代表的新
  • H5实例 移动端页面练习

    文章目录 标签知识点 标签知识点 name 61 viewport xff1b 屏幕设定maximum scale 61 1 0 minimum scale 61 1 0 initial scale 61 1 0 xff1b 最大最小缩放比
  • SSH修改远程端口后无法登录的解决办法

    参考 xff1a https www cnblogs com opswa p 16076001 html SSH是一种网络协议 xff0c 用于计算机之间的加密登录 如果一个用户从本地计算机 xff0c 使用SSH协议登录另一台远程计算机
  • 串口调试助手如何使用

    需要设置好对应的串口端口 xff0c 波特率 校验位 数据位 停止位 xff0c 然后打开串口 这是一个绿色版的 xff0c 比深蓝串口调试助手好用的多

随机推荐

  • 来来来!我告诉你 AUTOSAR架构深度解析从入门到放弃

    如何快速学习AUTOSAR 关于AUTOSAR的背景和架构信息 xff0c 这里就不详细展开了 大家可以参看 xff1a AUTOSAR的分层架构 一文了解 今天我们重点讲讲如何快速学习AUTOSAR架构的方法 如何获取规范文档 xff1f
  • 智能指针make_unique 与make_shared 的知识介绍

    关于make unique的构造及使用例程 xff0c MSDN的讲解非常详细 xff08 https msdn microsoft com zh cn library dn439780 aspx xff09 使用过程中 xff0c 主要有
  • Adaptive AutoSAR 标准介绍

    关于自适应AutoSAR 平台 自适应autosar 平台实现了adaptive applications的运营环境 它提供了两种接口 xff0c 一种是service 一种是API 平台功能分成两部分 xff1a service部分和ad
  • MPU和MCU的区别

    MCU指的是微控制 器 集合了FLASH RAM和一些外围器件 MCU一般使用片内FLASH来存储和执行程序代码 MPU指的是微处理 器 FLASH和RAM则需要设计者自行搭建 xff0c 当然MCU也可以外扩 MPU的电路设计相对MCU较
  • powerbuilder9 窗口高级配置

    一 无标题栏 办法 xff1a 把窗口类型配置成response或者popup xff0c 窗口属性中的titlebar属性就变成可以选择 xff0c 把titlebar属性的勾点掉 xff0c 就可以配置成无标题栏 xff0c main类
  • Adaptive AUTOSAR——Cryptography (VRTE3.0 R21-11)

    Cryptography模块是用于自适应汽车软件架构的密码学模块 xff0c 主要用于实现各种安全功能 xff0c 包括加密 解密 签名和验证 等操作 它的主要作用包括 xff1a 安全通信 xff1a 使用各种算法对数据进行加密和解密 x
  • 一文读懂AUTOSAR SecOC通讯

    为什么用SecOC 在车载网络中 xff0c CAN总线作为常用的通讯总线之一 xff0c 其大部分数据是以明文方式广播发送且无认证接收 这种方案具有低成本 高性能的优势 xff0c 但是随着汽车网联化 xff0c 智能化的业务需要 xff
  • 汽车操作系统的趋势

    操作系统 OS 需要管理基于计算机的系统的所有硬件和软件 xff0c 并且是汽车行业的关键软件平台 本文侧重于提供教程信息和汽车操作系统策略的一些观点 每个操作系统在功能 程序大小 复杂性 开发工作和硬件要求以及生命周期维护 支持工作和成本
  • 4.5.2 DDS

    1 标准及发展简介 DDS 的全称为 Data Distribution Service xff08 数据分发服务 xff0c 是由 OMG 联盟在 2004 年发布的中间件协议和应用程序接口标准 采用发布 订阅模型 xff0c 提供丰富的
  • SOA协议DDS和Some/IP对比

    SOME IP 和 DDS 均已被纳入AUTOSAR AP的平台标准中 SOME IP 和 DDS是在不同的应用场景和不同的需求下诞生的技术 xff0c 所以它们之间注定有很大的区别 SOME IP SOME IP的全称为 xff1a Sc
  • linux内核提高系统实时性,Linux操作系统实时性分析及改进策略

    摘要 xff1a 实时操作系统要求具有速度快和可预测性的特点 xff0c 必须保证实时任务在要求的时间内完成 本文在分析Linux操作系统的中断方式和进程调度等影响实时性的因素后 xff0c 对Linux的实时性策略进行改进 xff0c 提
  • switch ... case语句的用法

    当情况大于或等于4种的时候就用switch case语句 switch xff08 表达式 xff09 case 常量1 xff1a 语句体1 xff1b case 常量2 xff1a 语句体2 xff1b case 常量3 xff1a 语
  • 什么是eNodeB?eNodeB有什么主要功能?eNodeB与2G、3G的基站有什么区别?

    答 xff1a eNodeB xff08 简称为eNB xff09 是LTE网络中的无线基站 xff0c 也是LTE无线接入网的唯一网元 xff0c 负责空中接口相关的所有功能 xff1a xff08 1 xff09 无线链路维护功能 xf
  • 最优传输-ML实战

    在正文开始之前 xff0c 我们先举一个例子 xff1a Equations A 1
  • 最优传输-Sinkhorn算法(第九篇)

    最优传输系列是基于Computational Optimal Transport开源书的读书笔记 Sinkhorn算法 在上一篇里 xff0c 我们介绍了加入熵正则化的最优传输问题 熵正则化通过限制最优传输问题解的复杂度 xff0c 可以以
  • oracle表对表的多行更新

    oracle并没有update from 这个写法 所以在从一个表将数据更新到另外一个表时 xff0c 无法使用update from写法 xff0c 尤其是需要多行更新时 xff0c 最好使用merge into merge into允许
  • 一图理解M0不同优先级中断及Pendsv切换

  • 纽约客封面故事:欢迎来到「黑暗工厂」,这里是由机器统治的世界

    来源 The New Yorker 作者 Sheelah Kolhatkar 编译 编辑部 大急流城 xff0c Steelcase 的 人肉机器人 1977 年 xff0c 在密歇根州大急流城 xff0c 当 David Stinson
  • 先读懂CapsNet架构然后用TensorFlow实现:全面解析Hinton的提出的Capsule

    上周 Geoffrey Hinton 等人公开了那篇备受关注的 NIPS 论文 xff0c 而后很多研究者与开发者都阅读了该论文并作出了一定的代码实现 机器之心在本文中将详细解释该论文提出的结构与过程 xff0c 并借助 GitHub 上热
  • Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测

    近日 xff0c Artur Suilin 等人发布了 Kaggle 网站流量时序预测竞赛第一名的详细解决方案 他们不仅公开了所有的实现代码 xff0c 同时还详细解释了实现的模型与经验 机器之心简要介绍了他们所实现的模型与经验 xff0c