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

R语言中如何基于已拟合多项式线性模型由已知y值反推x及预测区间

三次多项式模型反向预测x的实现方案

你拟合的是x的三次多项式模型,且观测数据整体x与y呈单调递增关系,不存在一个y对应多个x的多解问题,用approx()插值反推的方案完全适用,还能同步计算预测区间对应的x范围,不需要硬解三次方程。

实现逻辑

  • 首先在原始x的取值范围内生成高密度的等距x点,用已拟合的lm模型计算每个点对应的y拟合值、指定水平预测区间的上下界
  • 把「x对应预测y」的映射反过来,用approx()做线性插值,输入目标y值,就能反算出对应的x期望值、预测区间对应的x上下限
  • 误差范围取x期望值到预测区间上下限的平均差,就能得到你要的正负误差值

自定义函数代码

# 载入数据与拟合模型,和你给出的代码完全一致
x <- c(4.66, 5.53, 5.62, 5.85, 6.26, 6.91, 7.04, 7.32, 7.43, 7.85, 
       8.1, 8.3, 8.34, 8.53, 8.69, 8.7, 8.73, 8.76, 8.96, 9.06, 9.42, 
       9.78, 10.3, 10.82, 10.98, 11.07, 11.09, 11.32, 11.75, 12.1, 12.46, 
       12.5, 12.99, 13.02, 13.28, 13.43, 13.96, 14, 14.07, 14.29, 14.57, 
       14.66, 15.21, 15.56, 15.97, 16.44, 16.8, 17.95, 18.33, 18.62, 
       18.92, 19.49, 19.9, 19.92, 20.14, 20.18, 21.19, 22.7, 23.25, 
       23.48, 23.49, 23.58, 23.7, 23.83, 23.83, 23.97, 24.05, 24.14, 
       24.15, 24.19, 24.32, 24.62, 24.9, 24.92, 25, 25.06, 25.31, 25.36, 
       25.86, 25.9, 25.95, 25.99, 26.08, 26.2, 26.27, 26.39, 26.5, 26.51, 
       26.68, 26.78, 26.82, 26.92, 26.92, 27.05, 27.05, 27.07, 27.32, 
       27.6, 27.77, 27.8, 27.91, 27.96, 27.97, 28.04, 28.05, 28.15, 
       28.2, 28.28, 28.37, 28.51, 28.53, 28.53, 28.66, 28.68, 28.72, 
       28.74, 28.82, 28.83, 28.83, 28.86, 28.89, 28.91, 29.04, 29.2, 
       29.35, 29.4, 29.42, 29.48, 29.53, 29.65, 29.67, 29.69, 29.7, 
       29.72, 29.93, 29.97, 30.03, 30.08, 30.09, 30.11, 30.18, 30.62, 
       30.66, 30.78, 31, 31.32, 31.43, 31.47, 31.69, 31.96, 32.33, 32.5, 
       32.5, 32.58, 32.7, 32.92, 33.2, 33.6, 33.72, 33.77, 33.95, 34.02, 
       34.08, 34.42, 34.79, 34.91, 34.99, 35.08, 35.15, 35.49, 35.6, 
       35.6, 35.74, 35.8, 36.05, 36.17, 36.3, 36.37, 36.84, 37.31, 37.95, 
       38.75, 38.78, 38.81, 38.9, 39.21, 39.31, 39.5, 42.68, 43.92, 
       43.95, 44.64, 45.7, 45.95, 46.25, 46.8, 49.08, 50.33, 51.23, 
       52.76, 53.06, 62)
y <- c(11.91, 13.491, 13.708, 13.984, 14.624, 15.688, 15.823, 16.105, 
       16.387, 17.004, 17.239, 17.498, 17.686, 17.844, 17.997, 18.044, 
       18.003, 18.191, 18.332, 18.25, 18.778, 19.237, 19.693, 20.177, 
       20.441, 20.876, 20.512, 20.894, 21.493, 21.539, 21.951, 21.763, 
       22.498, 22.451, 22.744, 22.785, 23.409, 23.314, 23.408, 23.567, 
       23.849, 23.978, 24.472, 24.678, 25.236, 25.547, 25.676, 26.81, 
       26.83, 27.275, 27.331, 27.844, 28.009, 28.244, 28.497, 28.555, 
       29.067, 30.412, 30.788, 30.965, 31.058, 31.423, 31.346, 31.118, 
       31.252, 31.258, 31.399, 31.605, 31.552, 31.881, 31.822, 31.91, 
       32.333, 32.174, 32.222, 32.704, 32.445, 32.557, 32.993, 32.845, 
       32.997, 32.909, 32.911, 33.121, 33.191, 33.156, 33.426, 33.332, 
       33.52, 33.526, 33.697, 33.379, 33.849, 33.726, 33.538, 33.885, 
       33.961, 34.284, 34.208, 33.896, 34.278, 34.355, 34.276, 34.267, 
       34.399, 34.507, 34.492, 34.531, 34.695, 34.642, 34.872, 34.772, 
       34.813, 34.942, 34.883, 34.948, 34.719, 34.983, 34.99, 35.136, 
       35.007, 34.026, 35.148, 35.201, 35.459, 35.418, 35.236, 35.411, 
       35.459, 35.5, 35.665, 35.724, 35.636, 35.667, 35.747, 35.788, 
       35.882, 35.9, 35.83, 36.106, 36.029, 36.364, 36.358, 36.517, 
       37.005, 36.74, 36.963, 36.634, 37.04, 37.48, 37.581, 37.78, 37.686, 
       38.262, 37.998, 37.986, 38.498, 39.296, 38.467, 38.779, 38.885, 
       38.72, 39.038, 38.932, 39.719, 39.654, 39.367, 40.072, 39.707, 
       39.742, 39.919, 40.054, 40.189, 40.197, 40.154, 40.383, 42.146, 
       40.595, 40.971, 41.441, 41.964, 42.328, 42.463, 42.627, 42.633, 
       42.721, 42.786, 42.857, 45.318, 45.665, 46.406, 46.335, 47.663, 
       47.181, 48.074, 48.109, 49.931, 50.377, 51.053, 52.451, 53.004, 
       65.889)
model <- lm(y ~ poly(x,3,raw=TRUE))

# 反向预测自定义函数
reverse_predict <- function(model, target_y, pi_level=0.95, x_res=10000){
  # 提取原始x范围,生成高密度插值序列
  x_range <- range(model$model[[2]])
  x_dense <- seq(x_range[1], x_range[2], length.out = x_res)
  # 计算所有高密度点的拟合值与预测区间
  pred_res <- predict(model, newdata = data.frame(x = x_dense), 
                      interval = "prediction", level = pi_level)
  # 线性插值反算对应x值
  x_fit <- approx(x = pred_res[,"fit"], y = x_dense, xout = target_y)$y
  x_lwr <- approx(x = pred_res[,"lwr"], y = x_dense, xout = target_y)$y
  x_upr <- approx(x = pred_res[,"upr"], y = x_dense, xout = target_y)$y
  # 计算平均正负误差
  err <- mean(c(x_fit - x_lwr, x_upr - x_fit))
  # 输出要求格式的文本结果
  cat(sprintf("x的期望值为%.2f,正负误差为%.2f\n", x_fit, err))
  # 隐式返回结构化结果,方便后续计算调用
  invisible(list(
    x_expected = x_fit,
    x_pi_lower = x_lwr,
    x_pi_upper = x_upr,
    error_margin = err,
    pi_level = pi_level
  ))
}

使用示例

输入目标y值即可得到对应结果,例如输入y=42:

> reverse_predict(model, target_y = 42)
x的期望值为38.87,正负误差为0.72

和你要求的输出格式完全匹配。

参数说明

  • 函数默认生成10000个高密度x点做插值,精度满足绝大多数分析场景,需要更高精度可以调大x_res参数
  • 默认返回95%水平的预测区间,需要调整置信度可以修改pi_level参数,例如要90%区间传入pi_level=0.9即可
  • 当前函数适配你这个单调递增的三次多项式场景,如果后续使用非单调模型、存在一个y对应多根的情况,需要额外增加根的筛选逻辑,你当前的数据集不需要额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:45:32