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

使用nls函数进行正系数约束回归时遇错误的求助

问题原因与解决方案

错误原因分析

  1. 第一个错误:nls不支持lm风格的.自动展开自变量。它需要显式定义每个待拟合的参数与变量的关系,否则无法识别需要估计的参数,导致起始值匹配失败。
  2. 第二个错误:你的数据中x1-x5完全共线(均为seq(10)),导致模型矩阵奇异,触发QR分解的维度错误;同时用nls拟合线性约束回归并非最优选择,更适合用专门的非负最小二乘工具。

解决方案

方法一:用nnls包做非负最小二乘(推荐,高效直接)

对于线性回归且要求系数非负的场景,nnls包是专门的解决方案,比nls更高效稳定:

library(nnls)
library(magrittr)

# 构造非共线数据(避免完全共线导致的错误)
X <- data.frame(
    x1 = seq(10),
    x2 = seq(10) + rnorm(10),
    x3 = seq(10) + rnorm(10),
    x4 = seq(10) + rnorm(10),
    x5 = seq(10) + rnorm(10),
    y = seq(10) + rnorm(10)
)

# 转换为模型矩阵和响应向量
X_mat <- X %>% dplyr::select(-y) %>% as.matrix()
y_vec <- X$y

# 拟合非负最小二乘
fit_nnls <- nnls(X_mat, y_vec)

# 查看结果
fit_nnls$x          # 非负系数
sum((y_vec - X_mat %*% fit_nnls$x)^2)  # 残差平方和

方法二:修正nls的用法(适合非线性场景,线性场景不推荐)

如果一定要用nls,需要显式定义参数并避免数据共线:

library(magrittr)

# 构造非共线数据
X <- data.frame(
    x1 = seq(10),
    x2 = seq(10) + rnorm(10),
    x3 = seq(10) + rnorm(10),
    x4 = seq(10) + rnorm(10),
    x5 = seq(10) + rnorm(10),
    y = seq(10) + rnorm(10)
)

# 生成带显式参数的公式(如a1*x1 + a2*x2...)
var_names <- X %>% dplyr::select(-y) %>% names
param_names <- paste0("a", seq_along(var_names))
formula_str <- paste("y ~", paste(paste(param_names, var_names, sep="*"), collapse=" + "), "-1")
f <- as.formula(formula_str)

# 设置起始值、上下界(需与参数名一一对应)
start <- setNames(rep(0, length(var_names)), param_names)
lower <- start
upper <- setNames(rep(Inf, length(var_names)), param_names)

# 拟合nls
fit_nls <- nls(formula = f, data = X,
               start = start,
               lower = lower,
               upper = upper,
               algorithm = "port"
)

# 查看结果
summary(fit_nls)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:45:35