使用 LSTM 进行多元二元序列预测

2024-01-18

我正在研究序列预测问题,并且在这方面没有太多经验,因此下面的一些问题可能很幼稚。

FYI:我创建了一个关注 CRF 的后续问题here https://stackoverflow.com/questions/53987682/multivariate-binary-sequence-prediction-with-crf

我有以下问题:

我想预测多个非独立变量的二元序列。

Inputs:

我有一个包含以下变量的数据集:

  1. 时间戳
  2. A组和B组
  3. 与特定时间戳的每个组相对应的二进制信号

此外,假设以下情况:

  1. 我们可以从时间戳(例如一天中的小时)中提取其他属性,这些属性可以用作外部预测器
  2. 我们认为 A 组和 B 组不是独立的,因此联合建模他们的行为可能是最佳选择

binary_signal_group_A and binary_signal_group_B是我想使用(1)它们过去的行为和(2)从每个时间戳提取的附加信息来预测的 2 个非独立变量。

到目前为止我所做的:

# required libraries
import re
import numpy as np
import pandas as pd
from keras import Sequential
from keras.layers import LSTM

data_length = 18  # how long our data series will be
shift_length = 3  # how long of a sequence do we want

df = (pd.DataFrame  # create a sample dataframe
    .from_records(np.random.randint(2, size=[data_length, 3]))
    .rename(columns={0:'a', 1:'b', 2:'extra'}))
# NOTE: the 'extra' variable refers to a generic predictor such as for example 'is_weekend' indicator, it doesn't really matter what it is

# shift so that our sequences are in rows (assuming data is sorted already)
colrange = df.columns
shift_range = [_ for _ in range(-shift_length, shift_length+1) if _ != 0]
for c in colrange:
    for s in shift_range:
        if not (c == 'extra' and s > 0):
            charge = 'next' if s > 0 else 'last'  # 'next' variables is what we want to predict
            formatted_s = '{0:02d}'.format(abs(s))
            new_var = '{var}_{charge}_{n}'.format(var=c, charge=charge, n=formatted_s)
            df[new_var] = df[c].shift(s)

# drop unnecessary variables and trim missings generated by the shift operation
df.dropna(axis=0, inplace=True)
df.drop(colrange, axis=1, inplace=True)
df = df.astype(int)
df.head()  # check it out

#   a_last_03  a_last_02      ...        extra_last_02  extra_last_01
# 3          0          1      ...                    0              1
# 4          1          0      ...                    0              0
# 5          0          1      ...                    1              0
# 6          0          0      ...                    0              1
# 7          0          0      ...                    1              0
# [5 rows x 15 columns]

# separate predictors and response
response_df_dict = {}
for g in ['a','b']:
    response_df_dict[g] = df[[c for c in df.columns if 'next' in c and g in c]]

# reformat for LSTM
# the response for every row is a matrix with depth of 2 (the number of groups) and width = shift_length
# the predictors are of the same dimensions except the depth is not 2 but the number of predictors that we have

response_array_list = []
col_prefix = set([re.sub('_\d+$','',c) for c in df.columns if 'next' not in c])
for c in col_prefix:
    current_array = df[[z for z in df.columns if z.startswith(c)]].values
    response_array_list.append(current_array)

# reshape into samples (1), time stamps (2) and channels/variables (0)
response_array = np.array([response_df_dict['a'].values,response_df_dict['b'].values])
response_array = np.reshape(response_array, (response_array.shape[1], response_array.shape[2], response_array.shape[0]))
predictor_array = np.array(response_array_list)
predictor_array = np.reshape(predictor_array, (predictor_array.shape[1], predictor_array.shape[2], predictor_array.shape[0]))

# feed into the model
model = Sequential()
model.add(LSTM(8, input_shape=(predictor_array.shape[1],predictor_array.shape[2]), return_sequences=True))  # the number of neurons here can be anything
model.add(LSTM(2, return_sequences=True))  # should I use an activation function here? the number of neurons here must be equal to the # of groups we are predicting
model.summary()

# _________________________________________________________________
# Layer (type)                 Output Shape              Param #   
# =================================================================
# lstm_62 (LSTM)               (None, 3, 8)              384       
# _________________________________________________________________
# lstm_63 (LSTM)               (None, 3, 2)              88        
# =================================================================
# Total params: 472
# Trainable params: 472
# Non-trainable params: 0

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])  # is it valid to use crossentropy and accuracy as metric?
model.fit(predictor_array, response_array, epochs=10, batch_size=1)
model_preds = model.predict_classes(predictor_array)  # not gonna worry about train/test split here
model_preds.shape  # should return (12, 3, 2) or (# of records, # of timestamps, # of groups which are a and b)

# (12, 3)

model_preds
# array([[1, 0, 0],
#        [0, 0, 0],
#        [1, 0, 0],
#        [0, 0, 0],
#        [1, 0, 0],
#        [0, 0, 0],
#        [0, 0, 0],
#        [0, 0, 0],
#        [0, 0, 0],
#        [0, 0, 0],
#        [1, 0, 0],
#        [0, 0, 0]])

问题:

这里的主要问题是:我如何让它工作,以便模型能够预测两组的下一个 N 序列?

另外,我想问以下问题:

  1. A 组和 B 组预计是互相关的,但是,尝试通过单个模型输出 A 和 B 序列是否有效,或者我应该拟合 2 个单独的模型,一个预测 A,另一个预测 B,但都使用历史 A 和 B 数据作为输入?
  2. 虽然模型中的最后一层是形状为 (None, 3, 2) 的 LSTM,但预测输出的形状为 (12, 3),而我原本期望它是 (12, 2) ——我在做什么吗这里错了,如果是这样,我该如何解决这个问题?
  3. 就输出 LSTM 层而言,这里使用激活函数(例如 sigmoid)是个好主意吗?为什么/为什么不呢?
  4. 使用分类类型损失(二元交叉熵)和指标(准确性)来优化序列是否有效?
  5. LSTM 模型是这里的最佳选择吗?有人认为 CRF 或某种 HMM 类型的模型在这里效果更好吗?

非常感谢!


我将按顺序回答所有问题

我如何让它工作,以便模型能够预测下一个 N 两组的序列?

我建议对您的模型进行两处修改。
The first最后一层使用 sigmoid 激活。

Why?? Consider binary cross entropy loss function (I borrowed the equation from here https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html)
eq
Where L is calculated loss, p is network prediction and y is target values.

The Loss is defined for eq . If p is outside of this open interval range then the loss is undefined. The default activation of lstm layer in keras is tanh https://keras.io/layers/recurrent/ and it's output range is (-1, 1). This implies that the output of the model is not suitable for binary cross-entropy loss. If you try to train the model you might end up getting nan for loss.

The second修改(是第一次修改的一部分)或者在最后一层之前添加 sigmoid 激活。为此,您有三个选择。

  1. 在输出和最后一个 lstm 层之间添加带有 sigmoid 激活的密集层。
  2. 或者将lstm层的激活改为sigmoid。
  3. 或者在输出层之后添加具有 sigmoid 激活的激活层。

尽管所有情况都有效,但我建议使用带有 sigmoid 激活的密集层,因为它几乎总是效果更好。 现在建议更改的模型将是

model = Sequential()
model.add(LSTM(8, input_shape=(predictor_array.shape[1],predictor_array.shape[2]), return_sequences=True))  
model.add(LSTM(2, return_sequences=True)) 
model.add(TimeDistributed(Dense(2, activation="sigmoid")))
model.summary()

...尝试通过单个输出同时输出 A 和 B 序列是否有效 型号还是我应该安装 2 个单独的型号...?

理想情况下,这两种情况都可以。但最新的研究如this one https://pdfs.semanticscholar.org/813d/4b843f64439c9ff9df63158c8ba8179276da.pdf表明前一种情况(对两个组使用单一模型)往往表现更好。该方法通常被称为多任务学习 https://en.wikipedia.org/wiki/Multi-task_learning。背后的想法多任务学习非常广泛,为了简单起见,它可以被认为是通过强制模型学习多个任务常见的隐藏表示来添加归纳偏差。

...当我预期时,预测输出的形状为 (12, 3) 它是 (12, 2) -- 我在这里做错了什么吗......?

你得到这个是因为你正在使用预测类 https://faroit.github.io/keras-docs/1.0.0/models/sequential/方法。与预测方法不同,predict_classes 方法返回通道轴的最大索引(在您的情况下是第三个索引)。正如我上面所解释的,如果您对最后一层使用 sigmoid 激活并用 Predict 替换 Predict_classes,您将得到您所期望的结果。

就输出 LSTM 层而言,这是一个好主意吗? 在这里使用激活函数,例如 sigmoid?为什么/为什么不呢?

我希望我已经在上面解释了这一点。答案是肯定的。

使用分类类型损失(二元交叉熵)是否有效 和优化序列的指标(准确性)?

由于您的目标是二进制信号(分布是伯努利分布 https://en.wikipedia.org/wiki/Bernoulli_distribution),是的,使用二进制损失和准确性指标是有效的。这个答案给出了 https://stackoverflow.com/a/53933195/5825953有关为什么二元交叉熵对于此类目标变量有效的更多详细信息。

LSTM 模型是这里的最佳选择吗?有人认为 CRF 或者某些 HMM 类型的模型在这里会更好?

这取决于可用数据和您选择的网络的复杂性。 CRF 和 HMM 网络很简单,如果可用数据较小,效果会更好。但如果可用数据集很大,LSTM 几乎总是优于 CRF 和 HMM。我的建议是,如果你有大量数据,请使用 LSTM。但如果您的数据较少或正在寻找简单的模型,您可以使用 CRF 或 HMM。

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

使用 LSTM 进行多元二元序列预测 的相关文章

随机推荐

  • 何时通过服务引用使用 WCF ChannelFactory [重复]

    这个问题在这里已经有答案了 我正在浏览 WCF 教程 发现这些教程指出我需要提供一个 mex 端点 以允许隐式向客户端添加服务引用 我想这允许 VS 在使用生成的 WSDL 文件时创建代理类 然而 我试图熟悉的代码库不使用隐式服务引用 相反
  • 将数据从表单提交到 django 视图

    当我打开 html 文件时 它会按预期显示 当我在文本框中输入数据并提交时 它会将我重定向到localhost myapp output 但为什么我在文本框中输入的数据没有提交 例如localhost myapp output data I
  • EclipseLink、EntityManager 需要两个持久性单元

    我有一个 jar 库 A 或 eclipse 中的项目 它有自己的持久性单元 META INF persistence xml 和一些实体类 以及使用该库的另一个项目 B 在项目 B 中还有持久化单元和实体类 在项目 B 中 我需要使用项目
  • 嵌入、对象和视频标签之间的区别?

    据我所知 我知道embed tag用于嵌入来自 youtube 等网站的视频 object tag适用于 Flash 视频和video tags受到HTML5 但我很好奇这些标签的深入细节 以及作为一名开发人员 应该在哪里使用哪个标签 em
  • SSRS - 后续页面内容区域中标题和 tablix 之间的空格/边距

    好吧 我知道这个问题很难消化 所以我希望这张附图能让我的问题更有意义 基本上我想在第一页之后在标题和 tablix 之间保留一些空间 我对标题使用底部边框 用户不希望看到表格和标题粘在一起 尝试放置空文本框 隐藏 但实际上不起作用 因为我无
  • django 错误无法导入名称“RemovedInDjango30Warning”

    伙计们 我对 Django 相当陌生 我刚刚开始从事一个个人项目 并决定滥用 pycharm 我认为它与错误有关 或不相关 当我跑步时python manage py runserver我收到下面发布的错误 我做了一些谷歌搜索 看起来它是由
  • C++中的vtable是什么[重复]

    这个问题在这里已经有答案了 可能的重复 为什么我需要虚拟表 https stackoverflow com questions 3004501 why do i need virtual table C 中的 vtable 是什么 到目前为
  • 纯虚函数调用

    我正在使用 boost python 来制作用 C 编写的 python 模块 我有一些带有纯虚函数的基类 我已将其导出如下 class Base virtual int getPosition 0 boost python class B
  • 如何在 elm 中按索引获取列表项?

    我有一个清单 现在我想要第 n 项 在哈斯克尔我会使用 但我找不到它的榆树变体 Elm 添加了数组0 12 1 http elm lang org blog announce 0 12 1 elm 并且在 0 19 中对实现进行了大规模修改
  • 如何在 Microsoft Access 中通过 VBA 设置 INSERT SQL 查询的参数值?

    我是 Access 新手 之前使用过 C SQL Server 和 Net 我有一个项目正在进行 我必须完成一些部分 该场景可以描述为 带有子表单的 Access 表单 一个Access查询 即上述子表单的数据源 有两个参数 显示为 Par
  • 使用 SyndicateFeed 读取 SyndicateItem 中的非标准元素

    在 net 3 5 中 有一个 SyndicateFeed 可以加载 RSS 提要并允许您在其上运行 LINQ 以下是我正在加载的 RSS 示例
  • 谷歌云端点返回 java long 作为 JSON 中的字符串

    我正在使用 google app engine 最新版本 1 9 30 我定义我的云端点如下 Api name app version v1 transformers EndpointDateTransformer class public
  • 如何在 IE 10/11 中可靠地将 XML 转换为字符串?

    当使用 jQuery 解析 XML 并将其转换回字符串时 IE 10 和 IE 11 未正确保留命名空间 除了编写我自己的 stringify 代码之外 还有其他可接受的方法可以在 IE 10 11 中执行此操作吗 这是我正在使用的代码 我
  • 直线和球体之间的交点

    我试图找到球体和直线之间的交点 但老实说 我不知道该怎么做 有人能帮我解决这个问题吗 将直线表示为函数t x t x0 1 t t x1 y t y0 1 t t y1 z t z0 1 t t z1 When t 0 它将在一个终点 x0
  • 多行文本框根据文本量自动调整其高度

    我有一个文本框 可以返回长度从 5 个字符到 1000 个字符的各种字符串 它具有以下属性 多行 真 自动换行 true 我需要设置文本框的哪些其他属性才能实现以下操作 盒子的宽度应该是固定的 根据返回的文本量自动调整框的高度 例如 如果文
  • 具有绝对/固定子项的父容器的自动高度

    我试图为包含 2 个子元素的 div 设置自动高度 分别固定和绝对定位 我希望我的父容器具有自动高度 但我知道这很难 因为子元素及其位置从页面结构中取出 我尝试为我的父 div 设置一个有效的高度 但是由于我的布局是响应式的 当它缩小到移动
  • 如何确定一个枚举值是否是另一个枚举值的后继?

    我正在尝试编写一个函数来告诉我是否Enum是另一个人的继承者 这是我的第一次尝试 isSuccessorOf x y x succ y 看起来很合理 我们来尝试一下 gt isSuccessorOf 3 2 True gt isSucces
  • 如何在 androidTest 范围内使用 kapt

    有没有办法将 kapt 用于 androidtest 范围 目前我正在从 com neenbedankt gradle plugins android apt 迁移到 kapt 效果很好 但我不确定如何在 androidTest 范围内执行
  • 如何在 .NET CF 2.0 下调整位图大小

    我有一个位图 我想以编程方式将其放大到原始大小的约 1 5 倍或 2 倍 在 NET CF 2 0 下有没有一种简单的方法可以做到这一点 一种 正常 方式是创建一个新的Bitmap所需大小 创建一个Graphics然后将旧图像绘制到其上Gr
  • 使用 LSTM 进行多元二元序列预测

    我正在研究序列预测问题 并且在这方面没有太多经验 因此下面的一些问题可能很幼稚 FYI 我创建了一个关注 CRF 的后续问题here https stackoverflow com questions 53987682 multivaria