如何为子弹形曲线上的点拟合一条平滑曲线?
拟合子弹形曲线的平滑方法
数据集
result_df <- structure(list(rp = c(0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2), MV = c(0.3396, 0.3076, 0.2788, 0.2532, 0.2308, 0.2116, 0.1956, 0.1828, 0.1732, 0.1668, 0.1636, 0.1636, 0.1668, 0.1732, 0.1828, 0.1956, 0.2116, 0.2308, 0.2532, 0.2788)), class = "data.frame", row.names = c(NA, -20L))
该数据呈现**子弹形(对称U型)**分布,以下是两种有效的平滑拟合方案:
方案1:使用loess局部加权回归
loess会自动适配非线性对称曲线,无需手动指定复杂多项式,拟合效果自然平滑:
library(ggplot2) ggplot(result_df, aes(x = sqrt(MV), y = rp)) + geom_point(color = "steelblue", size = 2) + stat_smooth(method = "loess", formula = y ~ x, se = FALSE, color = "darkred", linewidth = 1) + labs(title = "平滑拟合子弹形曲线", x = "s.d.", y = "rp") + theme_bw()
方案2:利用对称性拟合二次多项式
观察数据可知,sqrt(MV)随rp先递减后递增,呈现严格二次关系,用二次多项式即可完美拟合,避免高次多项式的过拟合问题:
# 拟合二次模型 model <- lm(sqrt(MV) ~ poly(rp, 2), data = result_df) # 生成高密度预测数据 pred_df <- data.frame(rp = seq(min(result_df$rp), max(result_df$rp), length.out = 100)) pred_df$sqrt_MV <- predict(model, newdata = pred_df) # 绘图 ggplot(result_df, aes(x = sqrt(MV), y = rp)) + geom_point(color = "steelblue", size = 2) + geom_line(data = pred_df, aes(x = sqrt_MV, y = rp), color = "darkred", linewidth = 1) + labs(title = "二次多项式拟合子弹形曲线", x = "s.d.", y = "rp") + theme_bw()
原方法问题说明
你之前使用12次多项式拟合过于复杂,不仅会导致曲线出现不必要的波动,还容易引发过拟合,反而无法准确捕捉数据的对称趋势。
内容的提问来源于stack exchange,提问作者Amirul Islam
相关产品推荐
相关产品推荐

