如何在R中拟合仅含一个拐点的loess模型?若无法实现该如何近似?
带单拐点约束的Loess模型拟合方案
标准loess模型没法直接加「仅一个拐点」的约束——因为它是局部加权多项式回归,拟合过程是自适应局部调整的,天生可能产生多个拐点。下面是几个靠谱的近似方案:
1. 分段线性回归(严格单拐点)
直接拟合两段线性模型,拐点位置可以手动指定或者让模型自动估计,用segmented包就能实现:
library(segmented) library(ggplot2) library(dplyr) # 先拟合基础线性模型 lm_fit <- lm(val ~ testage, data = df, weights = n) # 拟合分段模型,psi参数给拐点的初始猜测(比如25) seg_fit <- segmented(lm_fit, seg.Z = ~testage, psi = list(testage = 25)) # 生成预测数据 pred_df <- data.frame(testage = seq(0, 70, 1)) pred_df$val <- predict(seg_fit, newdata = pred_df) # 绘图展示 df %>% ggplot(aes(x=testage, y=val, weight=n)) + geom_point() + scale_x_continuous(name = 'Age', limits = c(0,70)) + scale_y_continuous(limits = c(-6,0.8), name = expression(paste("Avg. ",theta))) + geom_line(data = pred_df, color="blue", size=1) + geom_hline(yintercept=0) + geom_vline(xintercept=0)
这个方法能严格保证只有一个拐点,拐点的位置会由模型根据数据优化出来。
2. 约束样条回归(平滑且限拐点)
用mgcv包的GAM模型,通过控制样条自由度来限制拐点数量。比如设置自由度k=3的立方样条,最多只会有1个拐点:
library(mgcv) # 拟合约束GAM模型 gam_fit <- gam(val ~ s(testage, k=3), data = df, weights = n, method = "REML") # 生成预测值 pred_df$gam_val <- predict(gam_fit, newdata = pred_df) # 绘图 df %>% ggplot(aes(x=testage, y=val, weight=n)) + geom_point() + scale_x_continuous(name = 'Age', limits = c(0,70)) + scale_y_continuous(limits = c(-6,0.8), name = expression(paste("Avg. ",theta))) + geom_line(data = pred_df, aes(y=gam_val), color="red", size=1) + geom_hline(yintercept=0) + geom_vline(xintercept=0)
这种方案比分段线性更平滑,同时能控制拐点数量,适合需要曲线光滑度的场景。
3. 分段非线性模型(适配趋势)
如果你的数据是先升后降(或反之)的趋势,可以拟合分段二次模型,确保只有一个拐点:
# 拟合分段二次模型,start参数给初始值 nls_fit <- nls(val ~ a + b*testage + d*pmax(testage - c, 0)^2, data = df, weights = n, start = list(a=-6, b=0.3, c=25, d=-0.01)) # 生成预测值 pred_df$nls_val <- predict(nls_fit, newdata = pred_df) # 绘图 df %>% ggplot(aes(x=testage, y=val, weight=n)) + geom_point() + scale_x_continuous(name = 'Age', limits = c(0,70)) + scale_y_continuous(limits = c(-6,0.8), name = expression(paste("Avg. ",theta))) + geom_line(data = pred_df, aes(y=nls_val), color="green", size=1) + geom_hline(yintercept=0) + geom_vline(xintercept=0)
这里的拐点c是模型的估计参数,曲线在拐点前后的趋势可以灵活调整,适配数据的实际形态。
总结
如果必须严格保证只有一个拐点,分段线性/非线性回归是最直接的选择;如果想要平滑曲线同时限制拐点,约束样条GAM更合适——这两种方案都比单纯调大loess的span更精准地满足你的需求。
内容的提问来源于stack exchange,提问作者SunWuKung
相关产品推荐
相关产品推荐

