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

如何在R分段回归中约束拟合线起始点为(10,0)?

固定断点分段回归强制过指定起始点的解决方案

问题说明

需要对给定的债券数据集拟合分段线性回归,已固定断点为15、20、30,但要求拟合线必须起始于点(maturity=10, yield_change=0)。尝试变量变换时出现两个报错:

  • 执行segmented(model,seg.Z=~maturity,...)时,报错“object maturity not recognised”
  • 执行segmented(model,seg.Z=~I(maturity-10),psi = list(I(maturity-10) = c(15,20,30)),...)时,出现语法错误

错误原因分析

  1. “object maturity not recognised”:通常是segmented函数未正确从原模型的环境中识别变量,或数据传递路径出现问题。
  2. 语法错误:psi参数的列表中不能直接使用I(maturity-10)作为元素名,R的语法不允许表达式作为列表元素名称。

解决方案

方法1:手动构造分段变量+约束回归(推荐,无需依赖segmented包)

既然已固定断点,直接手动构造分段变量,并通过去掉模型截距+自变量中心化的方式强制拟合线过(10,0),步骤如下:

  1. 中心化自变量到10,构造各断点对应的分段变量;
  2. 拟合无截距的线性模型,确保maturity=10时预测值为0;
  3. 生成包含指定起始点的预测数据并绘图。

完整代码

bond_data <- data.frame(
  yield_change = c(-1.2,-0.9,-1.8,-1.4,-1.8,-2.1,-2.3,-2.1,-2.5,-2.2,-2.4,-2.5,-2.4,-2.4,
                   -3.0,-2.6,-5.1,-4.8,-4.9,-5.0,-5.0,-6.2,-6.1,-6.3,-5.0,-5.0),
  maturity =c(10.2795,10.8603,11.7753,12.3562,12.5205,13.3589,13.8630,14.2822,14.3589,15.3589,
              15.8630,16.778,17.3616,17.8658,18.3616,21.8685,22.5288,23.8685,24.3644,25.3671,
              26.8712,27.8712,28.8712,29.8740,44.3781,49.3836)
)

# 构造满足约束的变量:中心化到maturity=10,生成分段变量
bond_data$mat_centered <- bond_data$maturity - 10  # mat_centered=0对应maturity=10
bond_data$seg15 <- pmax(bond_data$maturity - 15, 0)
bond_data$seg20 <- pmax(bond_data$maturity - 20, 0)
bond_data$seg30 <- pmax(bond_data$maturity - 30, 0)

# 拟合无截距模型:强制maturity=10时yield_change=0
constrained_model <- lm(yield_change ~ 0 + mat_centered + seg15 + seg20 + seg30, data = bond_data)

# 生成包含指定起始点的预测数据
xp <- c(10, 15, 20, 30, max(bond_data$maturity))
new_data <- data.frame(maturity = xp)
new_data$mat_centered <- new_data$maturity - 10
new_data$seg15 <- pmax(new_data$maturity - 15, 0)
new_data$seg20 <- pmax(new_data$maturity - 20, 0)
new_data$seg30 <- pmax(new_data$maturity - 30, 0)

# 预测并绘图
yp <- predict(constrained_model, new_data)
plot(bond_data$maturity, bond_data$yield_change, pch=16, col="blue", ylim = c(-8,0), 
     xlab="Maturity", ylab="Yield Change")
lines(new_data$maturity, yp, col="red", lwd=2)
points(10, 0, pch=18, col="red", cex=1.5)  # 标记指定起始点

方法2:修正segmented包调用(保留segmented工作流)

如果必须使用segmented包,需先在数据框中生成变换后的变量,避免语法错误,同时确保预测包含指定起始点:

完整代码

bond_data <- data.frame(
  yield_change = c(-1.2,-0.9,-1.8,-1.4,-1.8,-2.1,-2.3,-2.1,-2.5,-2.2,-2.4,-2.5,-2.4,-2.4,
                   -3.0,-2.6,-5.1,-4.8,-4.9,-5.0,-5.0,-6.2,-6.1,-6.3,-5.0,-5.0),
  maturity =c(10.2795,10.8603,11.7753,12.3562,12.5205,13.3589,13.8630,14.2822,14.3589,15.3589,
              15.8630,16.778,17.3616,17.8658,18.3616,21.8685,22.5288,23.8685,24.3644,25.3671,
              26.8712,27.8712,28.8712,29.8740,44.3781,49.3836)
)

# 先生成变换后的变量,避免语法错误
bond_data$mat_10 <- bond_data$maturity - 10

# 拟合分段模型:断点对应mat_10的值为5(15-10)、10(20-10)、20(30-10)
model <- lm(yield_change ~ mat_10, data = bond_data)
segmented.model <- segmented(model, seg.Z=~mat_10, 
                             psi = list(mat_10 = c(5,10,20)), 
                             fixed.psi = c(5,10,20), 
                             control = seg.control(it.max = 0))

# 生成包含起始点的预测数据:mat_10=0对应maturity=10
xp_mat10 <- c(0, segmented.model$psi[,"Est."], max(bond_data$mat_10))
new_data <- data.frame(mat_10 = xp_mat10)
yp <- predict(segmented.model, new_data)

# 转换回maturity坐标并绘图
xp_maturity <- xp_mat10 + 10
plot(bond_data$maturity, bond_data$yield_change, pch=16, col="blue", ylim = c(-8,0))
lines(xp_maturity, yp, col="red", lwd=2)
points(10, 0, pch=18, col="red", cex=1.5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:25:53