我正在尝试使用“一天中的小时”作为参数来拟合线性模型。我正在努力解决的问题是,我找到了两种可能的解决方案来解决这个问题:
一天中每个小时的虚拟编码
我不太了解这两种方法的用例,因此我不确定哪一种会带来更好的结果。
我使用的数据来自这个Kaggle 挑战。目标是预测纽约市出租车费用。给定的属性是上车和下车坐标、上车日期时间、乘客人数和票价金额。我提取了一天中的时间以考虑可能的拥堵,并试图将其实施到我的模型中。我还应该提到我很缺乏经验。
我正在尝试使用“一天中的小时”作为参数来拟合线性模型。我正在努力解决的问题是,我找到了两种可能的解决方案来解决这个问题:
一天中每个小时的虚拟编码
我不太了解这两种方法的用例,因此我不确定哪一种会带来更好的结果。
我使用的数据来自这个Kaggle 挑战。目标是预测纽约市出租车费用。给定的属性是上车和下车坐标、上车日期时间、乘客人数和票价金额。我提取了一天中的时间以考虑可能的拥堵,并试图将其实施到我的模型中。我还应该提到我很缺乏经验。
虚拟编码会破坏几个小时之间的任何邻近度度量(和排序)。例如,下午 1 点到晚上 9 点之间的距离将与下午 1 点到凌晨 1 点之间的距离相同。下午 1 点左右就更难说了。
在我看来,即使让它们保持原样,例如 0-23 中的数字,也将是比虚拟编码更好的方法。但是,这种方式也有一个问题:00:01 和 23:59 看起来很遥远,但实际上并非如此。为了解决这个问题,使用了您列出的第二种方法,即循环变量。循环变量将小时映射到一个圆圈(如 24 小时机械时钟),以便 ML 算法可以看到各个小时的邻居。
+1 对枪手的回答。虚拟编码确实会忽略时间点之间的距离 - 相隔 1 小时的两个时间点之间的响应将比相隔 3 小时的两个时间点之间的响应更相似,并且虚拟编码完全丢弃了这条信息。
虚拟编码符合阶梯式时间依赖性:响应平坦一小时,然后突然跳跃(除了数据告诉我们的内容外,跳跃不受约束——这是缺乏邻近建模的结果)。这两个方面在生态上都非常值得怀疑:
这是一个额外的方面。如果您将一天分成 24 小时,那么除了截距之外,您还需要拟合 23 个参数。这是很多,您将需要大量数据才能可靠地适应它,而不会违反偏差-方差权衡。
另一种方法是使用具有谐波的傅里叶类型模型。例如,假设您的观察时间戳对应于一天中的某个时间(所以当从到,我们只需从)。然后您可以将时间影响转换为正弦和余弦:
一个简单的模型会上升到:
这已经以仅拟合 6 个参数为代价为您提供了很大的灵活性,因此您的模型将更加稳定。此外,您不会在一小时内得到持续的响应,也不会在新的一小时开始时获得突然的步骤。以下是一些适合的时间课程的随机示例:
当然,无论您做出什么选择,您都应该考虑包含您知道的任何其他信息(例如,如果所有剧院和电影院在同一时间开始或结束演出,那么用假人标记,因为那么你会得到一个急剧的变化,至少在相关地区)。此外,工作日和周末之间的时间响应肯定会有所不同,周五和其他工作日之间也可能会有所不同,因此包括您的时间模型和星期几之间的交互。或查看模型多重季节性来解决这个问题。
我的地块的 R 代码:
par(mai=c(.8,.1,.1,.1))
plot(c(0,24),c(0,1),yaxt="n",xlab="Hour",ylab="")
lines(c(0,rep(1:23,each=2),24),rep(runif(24),each=2))
tau <- seq(0,24,by=.001)
mm <- cbind(1,sin(2*pi*1*tau/24),sin(2*pi*2*tau/24),sin(2*pi*3*tau/24),cos(2*pi*1*tau/24),cos(2*pi*2*tau/24),cos(2*pi*3*tau/24))
par(mai=c(.8,.1,.1,.1),mfrow=c(3,2))
for ( ii in 1:6 ) plot(tau,(mm%*%runif(7,-1,1))[,1],yaxt="n",xlab="Hour",ylab="",type="l")
对于时间序列回归,只需添加每小时虚拟变量
, 在大多数情况下是很自然的事情,即拟合模型
通过一些任意周期函数(sin/cos/etc)转换数据是不合适的。例如,假设您适合模型