前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >再见One-Hot!时间序列特征循环编码火了!

再见One-Hot!时间序列特征循环编码火了!

作者头像
数据STUDIO
发布2024-07-24 09:42:42
1230
发布2024-07-24 09:42:42
举报
文章被收录于专栏:数据STUDIO
在进行时间序列机器学习模型的训练时,通常需要利用如下时间特征:小时、星期、月份以及周或年。将时间戳列转换为这些特征非常简单。确保将时间列转换为日期时间对象后,你可以使用.dt.Time方法来提取大量的时间序列特征。
代码语言:javascript
复制
df['Hour']=df['Datetime'].dt.hour
df['Month']=df['Datetime'].dt.month
df['Dayofweek']=df['Datetime'].dt.dayofweek

举个例子,使用一个包含每小时电力消耗数据的数据集作为参考。能源消耗数据集通常属于时间序列数据,其最终目的是利用过去的数据来预测未来的消耗量,因此这是一个很好的应用案例。尽管温度、湿度和风速等外部特征也会对能源消耗产生影响,但在这里我会着重关注时间序列特征的提取和转换。

现在你已经从 0 个可用功能变成了 3 个。

在使用 ML 时,我们需要对特征进行适当的处理,不能直接将其原样传入模型。原因在于大多数模型会将时间序列特征错误地理解为数字特征。举例来说,在能源消耗方面,某些高峰时段通常会导致较高的能源消耗,而其他特定时段则有较低的能耗。换句话说,可以将每个小时视作一个类别。

通过放大数据集的特定部分,可以证明这一点。数据显示了明显的消费模式,例如在下午 5-6 点的使用量往往达到最高峰,而在上午 5-7 点的使用量则最低。

显然,时间/年份/月份和星期等特征之间存在着复杂的相互作用,因此我们需要将更多的信息纳入我们的模型中。

为了做到这一点,我们需要使用其他格式来编码分类特征,以确保模型能够正确理解这些特征。最常见的方法是使用独热编码。

One-Hot(独热编码)的实现非常简单直接。它的基本原理是,对于一天(或月、日等)中的任何给定小时,我们会询问“它是否是第n小时/日/月”?然后用一个二进制的0或1来回答。对每一种类别都是这样操作。因此,对于原始特征中的day_of_week,将会得到7个编码特征(代表一周中的7天):

  • is_day_1
  • is_day_2
  • is_day_3
  • is_day_4
  • is_day_5
  • is_day_6
  • is_day_7

在 Python 中,最简单的方法是使用 pd.get_dummies

代码语言:javascript
复制
columns_to_encode = ['Hour', 'Month', 'Dayofweek']
df = pd.get_dummies(df, columns=columns_to_encode)

这将产生新的特征集

我们的特征非常丰富。我们已经将列数从原先的3列(小时、月、星期)增加到了40多列。随着需要编码的时间序列特征不断增加,这可能会变得越来越复杂。要跟踪所有这些特征可能会变得相当困难,特别是当您希望在数据库中存储或可视化这些特征时,您可能会希望避免产生过于混乱的图表。

循环编码

时间序列数据具有周期性循环的特点。例如,一天被划分为24个小时,当时针指向24:00(凌晨 12 点),新的一天就开始了,之后是1点、2点...按顺序循环。尽管从数值上看,1点与24点(0点)相距最远,但实际上1点与23点一样接近0点,因为它们都处于同一个24小时周期内。

因此,除了用数值直接表示时间,我们还可以将时间戳转换为正弦和余弦值。这种方法实质上是将时间映射到单位圆上,根据时间在圆周上的位置,赋予对应的正弦和余弦坐标值。它能很好地体现一天、一周或一年等周期性时间的特征。

与简单的类别编码(one-hot encoding)不同,这种方法将时间转化为数值特征,相邻时间点的特征值也相对接近,而相距较远的时间点的特征值则相去甚远。这样可以保留时间序列的关联性,而类别编码会丢失这种信息。

我们可以将单位圆的0度(3点钟方向)作为起始点,对应0:00(午夜)。然后按逆时针方向,将圆周等分为4个象限,分别对应上午6点、中午12点、下午6点和午夜12点。任意一个时间戳都可以映射到对应的象限中,从而获得其唯一的正弦和余弦坐标值,这两个值就代表了该时间戳的数值特征。通过这种方式,我们可以用这对正弦余弦值来周期性地表示一天24小时的时间序列。

为什么选择正弦余弦编码

时间序列数据有循环周期性的特点,比如一天24小时就是一个循环。我们希望编码后的特征值能够体现这种循环关系,即相邻的时间点特征值相近,而时间间隔越大,特征值差异就越大。正弦余弦函数本身具有周期性,非常适合表示这种循环模式。

具体是如何编码的

以每天24小时为例,我们将时间映射到单位圆上。圆周代表一天,设圆心为原点(0,0),半径为1。我们可将0点(午夜)设为起点,对应圆周上(1,0)的位置,并按逆时针方向进行。那么:

  • 6点钟对应(0,1)
  • 中午12点对应(-1,0)
  • 18点钟对应(0,-1)

对于任意一个时间t,我们就可以根据它在圆周上的位置,计算出其对应的(cos(t), sin(t))坐标值。这对坐标值就是该时间点的正弦余弦特征编码。

为什么这样编码好
  • 保持周期性:相邻时间的编码值接近,间隔大则编码差异大
  • 无边界:0点与24点编码相同,避免了"边界"问题
  • 更多信息:与one-hot编码相比,正余弦值更加连续,信息更丰富
其他周期也可类似编码

对于其他周期性时间序列,如一周七天、一年十二个月等,也可类似地将其映射到单位圆并编码为正余弦值对。甚至可将多个不同的周期合并编码。

基本单位圆

可以将相同的方法应用于其他周期,比如星期或年。在Python中实现这一点,首先需要将日期时间(在我这个例子中是每小时的时间戳)转换为数值变量。通过将此列转换为pd.Timestamp.timestamp对象,我们可以将每个时间戳转换为Unix时间(从1970年1月1日以来已过去的秒数)。

此时,可以将此数值列转换为正弦和余弦特征。

代码语言:javascript
复制
# 将日期时间转换为数字秒时间戳对象 
# (tells you the date/time in seconds)
timestamp_s = df['Datetime'].map(pd.Timestamp.timestamp)

# 获取每个时间段的秒数
day = 24*60*60
week = day*7
year = day*(365.2425)

# 使用正弦和余弦进行变换
# Time of day
df['Day_sin'] = np.sin(timestamp_s * (2 * np.pi / day))
df['Day_cos'] = np.cos(timestamp_s * (2 * np.pi / day))

# Time of week
df['Week_sin'] = np.sin(timestamp_s * (2 * np.pi / week))
df['Week_cos'] = np.cos(timestamp_s * (2 * np.pi / week))

# Time of year
df['Year_sin'] = np.sin(timestamp_s * (2 * np.pi / year))
df['Year_cos'] = np.cos(timestamp_s * (2 * np.pi / year))

大致而言,我们首先需要将时间戳从秒转换为弧度,即乘以2 * np.pi,因为一个完整的圆/周期有 2 * pi 的弧度。然后,我们将结果除以周期,这样就能以秒(日、周或年)为单位得到周期持续时间。接下来,通过乘以弧度数,我们将每个时间戳映射到一个唯一的角度,表示其在周期中的位置。

例如,如果周期为天,一天开始时的时间戳将被映射为 0 弧度,一天中间的时间戳将被映射为 np.pi 弧度,一天结束时的时间戳将被映射为 2 * np.pi 弧度。

最后,我们计算结果的 和 值,得到单位圆上实际的 x 和 y 坐标值。这些值将始终介于 -1 和 1 之间。

通过这种方法,每个原始时间序列特征(如每天的小时、每周的天、每年的月)现在只映射到 2 个新特征(原始特征的正弦和余弦),而不是 24、7、12 等。

缺点

在使用正弦余弦编码时间序列特征的方法时,需要格外谨慎并注意以下几点:

编码方式的选择有赖于数据分布
  • 如果数据在某些特定时间点/月份等存在显著的峰值,使用one-hot编码可能更合适,因为它能够明确区分这些异常值。
  • 但如果数据在较大的时间范围内(如中午12点至下午2点)呈现周期性波动,正弦余弦编码可能更加高效,能够较好捕捉数据的连续性和周期规律。
编码方式与模型算法相关
  • 正弦余弦编码特别适用于深度学习/神经网络等模型,因为这些模型擅长学习数值型特征之间的非线性关系。
  • 但对于基于决策树的模型如随机森林,由于其每次只根据一个特征进行分裂,可能无法很好利用正弦余弦编码所带来的优势。因为一个原始的时间特征被拆分为两个正弦余弦值,决策树会分别对待这两个数值。
具体问题具体分析
  • 并非完全禁止在树模型中使用正弦余弦编码。在一些特殊情况下,它仍可能对模型有益。需根据具体数据集和问题进行交叉验证和测试集评估。 在选择编码方案前,务必对比one-hot与正弦余弦编码在你的数据上的表现,以确定更优方案。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据STUDIO 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 循环编码
    • 为什么选择正弦余弦编码
      • 具体是如何编码的
        • 为什么这样编码好
          • 其他周期也可类似编码
          • 缺点
            • 编码方式的选择有赖于数据分布
              • 编码方式与模型算法相关
                • 具体问题具体分析
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档