我希望使用具有多个断点的非线性函数分段执行回归。我已经完成了分段线性回归,但是当涉及到指定任何类型的非线性函数时,我们如何在 R 中设置?
具体来说,我对线性、指数和使用两个断点的指数这 3 个函数感兴趣。请指教
卡提克
使用
nls()
(非线性最小二乘法)可以解决您的问题吗? 我使用了与此类似的公式,为每个“部分”添加了真/假陈述:
reg = nls( y ~ (Z < 0.33) * a + (Z < 0.33) * Z * b +
(Z >= 0.33 & Z < 0.67) * Z ^ a2 +
(Z >= 0.67) * a3 + (Z >= 0.67) * Z * a4,
start = list(a = 0, b = 50, a2 = 100, a3 = 150, a4 = 80),
data = yourdata)
在上面的程式化示例中,断点位于 Z = 0.33 和 Z = 0.67。 如果您可以更具体,或者分别提供三个回归的代码,我可以使我的答案更具体。
我的建议是加载“splines”包,然后运行
help(bs)
中的示例。您可以使用线性回归机制获得分段三次(但在结处连续)拟合。哈雷尔在他的“rms”包中运用了这一策略,取得了极好的效果。加载“rms”并查看 help(rcs)
。该页面上的示例使用了他的逻辑回归实现,但 rcs()
术语也适用于 ols()
和 cph()
。
分段线性曲线可以使用以下方程定义:
y = a + bx + c(x-k1)(x>=k1)
,其中 k1 是结值。
您可以继续为更多结添加附加项(即
+ d(x-k2)(x>=k2)
)。
使用
nls()
进行回归并找到方程系数:
# Create some arbitrary piecewise data with random noise:
set.seed(1);
df = data.frame(x = seq(0,250,.5) * runif(n=501)) %>%
mutate(y = 1 + 2*x - .5*(x-50)*(x>=50) + rnorm(n=501,mean=0,sd=3))
# use nls to solve, providing reasonable starting values for each unknown:
fit = nls(formula = as.formula("y ~ a + b*x + c*(x-k1)*(x>=k1)"),
start = c(a=0, b=5, c=-.25, k1=70), data = df)
summary(fit)
Formula: y ~ a + b * x + c * (x - k1) * (x >= k1)
Parameters:
Estimate Std. Error t value Pr(>|t|)
a 0.64397 0.32985 1.952 0.0515 .
b 2.01371 0.01317 152.912 <2e-16 ***
c -0.51108 0.01380 -37.038 <2e-16 ***
k1 48.90703 1.00800 48.519 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.948 on 497 degrees of freedom
Number of iterations to convergence: 5
Achieved convergence tolerance: 3.605e-08
# Visualize the solution:
df$pred = predict(fit)
ggplot(df, aes(x=x,y=y)) +
geom_abline() +
geom_point() +
geom_line(aes(y=pred, color="piecewise")) +
scale_color_manual(values = "orange")
您可以用指数函数代替线性函数,并以相同的方式求解,根据需要添加额外的结。