如何在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
相关产品推荐
相关产品推荐

