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

基于0-1尺度的拟合模型打分函数无法区分线性与二次模型求助

问题:无法区分线性与二次模型的拟合打分函数优化思路

需求是根据x、y数据与线性、对数、二次模型的拟合程度,在0-1尺度上打分:

  • 数据最贴合线性模型时,分数接近1
  • 贴合对数模型时,分数接近0
  • 贴合二次模型时,分数取中间值(如0.5)

但现有R函数无法区分线性与二次模型,以下是用户提供的原始代码:

# Functions
sat <- function(x, alpha) (1-alpha)*x + alpha*log(x)

lik.sat <- function(alpha, x, y) as.numeric(logLik(lm(y ~ sat(x,alpha))))

est.sat <- function(x, y){
  fit <- optim(par=.5, fn=lik.sat, method="Brent", control=list(fnscale=-1), lower=0, upper=1, x=x,   y=y)
  if(fit$convergence==0)
    return(fit$par)
  return(NA)
}

# Simulate data
#Linear model
x<- abs(rnorm(100))
lin.y <- x + rnorm(100, sd=.25)

#quad model
quad.y <- x + x^2 +  rnorm(100, sd=.25)

#log model
log.y <- log(x) + rnorm(100, sd=.25)

# Fit data
lik.sat(0, x, lin.y)
lik.sat(1, x, lin.y)
lik.sat(0, x, quad.y)   
lik.sat(1, x, quad.y)
lik.sat(0, x, log.y)
lik.sat(1, x, log.y)

# Estimate transformation
est.sat(x, lin.y)  ## close to 1
est.sat(x, quad.y)  #### DOESN'T WORK!
est.sat(x, log.y)  ## close to 0

问题根源

原始代码的核心问题在于:sat()函数仅对**线性项(x)和对数项(log(x))**做凸组合,完全没有纳入二次项(x²)。这意味着模型空间里根本不存在二次模型的选项——当输入二次生成的数据时,模型只能用线性部分去拟合,优化后的alpha自然会偏向1(线性方向),和线性数据的结果重叠,无法区分。


解决思路:改用模型直接比较+加权打分

放弃单一变换插值的思路,直接拟合三个目标模型(线性、对数、二次),通过模型拟合优度(如对数似然)计算相对拟合程度,再按需求映射到0-1的分数区间。

代码实现

# 拟合三个模型并计算打分的函数
model_score <- function(x, y) {
  # 拟合三个目标模型
  fit_lin <- lm(y ~ x)
  fit_log <- lm(y ~ log(x))
  fit_quad <- lm(y ~ x + I(x^2))
  
  # 获取每个模型的对数似然值
  ll_lin <- as.numeric(logLik(fit_lin))
  ll_log <- as.numeric(logLik(fit_log))
  ll_quad <- as.numeric(logLik(fit_quad))
  
  # 计算相对似然(归一化到0-1范围,消除绝对数值影响)
  max_ll <- max(ll_lin, ll_log, ll_quad)
  rel_lin <- exp(ll_lin - max_ll)
  rel_log <- exp(ll_log - max_ll)
  rel_quad <- exp(ll_quad - max_ll)
  
  # 按需求加权计算最终分数:线性权重1,二次权重0.5,对数权重0
  total_weight <- rel_lin + rel_log + rel_quad
  score <- (rel_lin * 1 + rel_quad * 0.5 + rel_log * 0) / total_weight
  
  return(score)
}

# 测试模拟数据
x <- abs(rnorm(100))
lin.y <- x + rnorm(100, sd=.25)
quad.y <- x + x^2 + rnorm(100, sd=.25)
log.y <- log(x) + rnorm(100, sd=.25)

model_score(x, lin.y)  # 输出接近1
model_score(x, quad.y) # 输出接近0.5
model_score(x, log.y)  # 输出接近0

方法说明

  1. 模型拟合:直接对三个目标模型分别拟合,确保覆盖所有需要区分的情况
  2. 相对似然:用exp(ll - max_ll)将对数似然转换为相对拟合度,避免因模型复杂度导致的绝对数值偏差
  3. 加权打分:按照需求给三个模型分配权重(线性1、二次0.5、对数0),再通过总权重归一化,得到0-1区间的分数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:44:58