拟合y ~ a*x^b*z^c时相关系数不一致原因及最优拟合方法
问题解答
两个相关系数数值不同的原因
- 核心原因:皮尔逊相关系数仅对变量的线性变换保持不变,对数变换、指数变换都属于非线性单调变换,会改变变量间的线性关联强度。CORR_1衡量的是对数尺度下
log(y)和预测值的线性相关性,CORR_2衡量的是原始尺度下y和预测值的线性相关性,二者本来就不相等。 - 样本不一致:你在处理对数变换时,将
x=0对应的无效log(x)设为了NA,拟合模型和计算CORR_1时会自动剔除这条样本,但计算CORR_2时没有剔除x=0的样本,这条样本的预测值为0、真实值为0.82,属于明显的离群点,会进一步拉低CORR_2的数值。 - 损失函数适配尺度不同:对数变换后的线性回归最小化的是对数尺度的残差平方和,参数是针对对数尺度最优的,转回原始尺度后不会是原始尺度下的最优解,也会导致原始尺度的线性相关性下降。
该形式模型的最优拟合方法
不存在通用的最优方法,需要结合你的误差结构选择:
情况1:误差为乘性结构
如果你的数据生成形式为 y = a*x^b*z^c * ε,其中ε是独立同分布的对数正态误差(即观测误差随y的大小成比例变化),此时对数变换后做线性回归是无偏最优的,代码和你现有写法基本一致,只需要注意计算相关系数时统一剔除x=0的样本即可:
# 统一剔除x=0的样本 df_clean <- df[df$x > 0, ] # 对数变换拟合 log_y <- log(df_clean$y) log_x <- log(df_clean$x) log_z <- log(df_clean$z) lm_model <- lm(log_y ~ log_x + log_z) # 对数尺度相关 cor_log <- cor(log_y, predict(lm_model)) # 转回原尺度计算相关 coeff <- list(a = exp(coef(lm_model)[1]), b = coef(lm_model)[2], c = coef(lm_model)[3]) y_pred <- coeff$a * df_clean$x^coeff$b * df_clean$z^coeff$c cor_raw <- cor(df_clean$y, y_pred)
情况2:误差为加性结构
如果你的数据生成形式为 y = a*x^b*z^c + ε,其中ε是独立同分布的正态误差(即观测误差和y的大小无关),此时应该用非线性最小二乘直接在原始尺度拟合,最小化原始尺度的残差平方和,代码示例如下:
# 剔除x=0的样本避免幂运算异常 df_clean <- df[df$x > 0, ] # 先用对数变换结果作为初始值,提升收敛稳定性 init_log <- lm(log(y) ~ log(x) + log(z), data = df_clean) init_val <- list(a = exp(coef(init_log)[1]), b = coef(init_log)[2], c = coef(init_log)[3]) # 非线性最小二乘拟合 nls_model <- nls(y ~ a * x^b * z^c, data = df_clean, start = init_val) # 提取参数与预测值 coeff_nls <- coef(nls_model) y_pred_nls <- predict(nls_model) # 原始尺度相关 cor_raw_nls <- cor(df_clean$y, y_pred_nls)
该方法得到的原始尺度相关会比对数变换后转回的结果更高,因为它直接针对原始尺度的损失函数优化。
内容的提问来源于stack exchange,提问作者raghav
相关产品推荐
相关产品推荐

