You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R的lm()函数中实现分时段分段线性回归?

实现在单个lm()中拟合分段线性回归(共享误差项)

问题回顾

你需要拟合的模型是:
$$Y=(1-\sigma)(\alpha_i + \beta_i x)+ \sigma(\alpha_j+\beta_j x)+\varepsilon$$
本质是每个时间段有独立的截距$\alpha_i$和斜率$\beta_i$,且所有观测共享同一个误差项$\varepsilon$。之前分时段循环拟合的方式会得到多个独立模型(误差项不共享),而仅用交互项的写法又缺少独立截距,这两种方式都不符合需求。

解决方法

核心是给数据添加时段分组变量,然后在lm()中同时纳入时段主效应(对应截距)和时段与自变量的交互效应(对应斜率),就能在单个模型中实现需求。

步骤1:给数据标记时段

先给你的原始数据df新增一个period列,用来标记每条观测属于哪个时间段:

start_dates <- as.Date(c("2003-01-01", "2008-01-01", "2016-01-01","2020-03-01"))
end_dates <- as.Date(c("2007-12-01", "2015-12-01", "2020-02-01", "2023-03-01"))

# 用cut函数给每个日期分配对应的时段标签
df$period <- cut(
  df$date,
  breaks = c(start_dates, max(end_dates) + 1),  # 最后一个区间包含到最大结束日期
  labels = paste0("period", 1:4),
  include.lowest = TRUE  # 确保第一个日期被包含在period1中
)

步骤2:拟合目标模型

有两种写法可以实现需求,根据你对系数输出形式的偏好选择:

写法1:无截距模型(直接输出每个时段的α和β)

如果你想直接看到每个时段的截距和斜率值,用无截距的公式:

# 无截距,每个时段输出独立的截距和斜率
final_model <- lm(short ~ 0 + period + inf:period, data = df)
summary(final_model)

系数解释:

  • periodperiod1 = 时段1的截距$\alpha_1$
  • periodperiod2 = 时段2的截距$\alpha_2$
  • inf:periodperiod1 = 时段1的斜率$\beta_1$
  • inf:periodperiod2 = 时段2的斜率$\beta_2$
    以此类推,直接得到每个时段的$\alpha_i$和$\beta_i$。

写法2:带参考组的交互模型

如果你习惯以第一个时段为参考组,看其他时段与参考组的差异,可以用period * inf(等价于period + inf + period:inf):

# 带参考组的交互模型
final_model_ref <- lm(short ~ period * inf, data = df)
summary(final_model_ref)

系数解释:

  • (Intercept) = 参考组(period1)的截距$\alpha_1$
  • periodperiod2 = period2与period1的截距差($\alpha_2 - \alpha_1$)
  • inf = 参考组(period1)的斜率$\beta_1$
  • periodperiod2:inf = period2与period1的斜率差($\beta_2 - \beta_1$)
    要得到其他时段的实际$\alpha_i$和$\beta_i$,只需把参考组的系数加上对应的差值即可。

模型验证

这两种写法的模型都完全符合你要的形式:每个时间段有独立的$\alpha_i$和$\beta_i$,所有观测共享同一个误差项$\varepsilon$,解决了分时段拟合的误差项不统一问题,也补上了单独交互项缺少截距的缺陷。


内容的提问来源于stack exchange,提问作者emithemex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:00:38