繁体   English   中英

正交线性回归(总最小二乘)拟合,在R中得到RMSE和R平方

[英]Orthogonal Linear Regression (total least squares) fit, get RMSE and R-squared in R

我正在尝试拟合一个 model,它使用 R 线性关联两个变量。我需要拟合正交线性回归(总最小二乘法)。 因此,我正在尝试使用 pracma package 的odregress() function,它通过 PCA 执行正交线性回归

这是一个示例数据:

x <- c(1.0, 0.6, 1.2, 1.4, 0.2, 0.7, 1.0, 1.1, 0.8, 0.5, 0.6, 0.8, 1.1, 1.3, 0.9)
y <- c(0.5, 0.3, 0.7, 1.0, 0.2, 0.7, 0.7, 0.9, 1.2, 1.1, 0.8, 0.7, 0.6, 0.5, 0.8)

我能够拟合 model 并使用以下方法获取系数:

odr <- odregress(y, x)
c <- odr$coeff

因此,model 由以下等式定义:

print(c)
[1]  0.65145762 -0.03328271

Y = 0.65145762*X - 0.03328271

现在我需要 plot 线拟合,计算 RMSE 和 R 平方。 我怎样才能做到这一点?

plot(x, y)

这是计算 MSE 和 RMSE 的两个函数。

library(pracma)

x <- c(1.0, 0.6, 1.2, 1.4, 0.2, 0.7, 1.0, 1.1, 0.8, 0.5, 0.6, 0.8, 1.1, 1.3, 0.9)
y <- c(0.5, 0.3, 0.7, 1.0, 0.2, 0.7, 0.7, 0.9, 1.2, 1.1, 0.8, 0.7, 0.6, 0.5, 0.8)

odr <- odregress(y, x)

mse_odreg <- function(object) mean(object$resid^2)
rmse_odreg <- function(object) sqrt(mse_odreg(object))

rmse_odreg(odr)
#> [1] 0.5307982

创建于 2023-01-10,使用reprex v2.0.2


编辑

R^2 可以用以下 function 计算。请注意, odr$ssq不是残差平方和odr$resid ,而是误差平方和odr$err

r_squared_odreg <- function(object, y) {
  denom <- sum((y - mean(y))^2)
  1 - object$ssq/denom
}
r_squared_odreg(odr, y)
#> [1] 0.1494818

创建于 2023-01-10,使用reprex v2.0.2

根据这篇文章中的解释,这是通过 PCA 解决正交线性回归(总最小二乘法)的另一种方法。 它实际上与pracma::odregress相同。

x <- c(1.0, 0.6, 1.2, 1.4, 0.2, 0.7, 1.0, 1.1, 0.8, 0.5, 0.6, 0.8, 1.1, 1.3, 0.9)
y <- c(0.5, 0.3, 0.7, 1.0, 0.2, 0.7, 0.7, 0.9, 1.2, 1.1, 0.8, 0.7, 0.6, 0.5, 0.8)

在这种情况下,我们使用prcomp() function 执行主成分分析。

v <- prcomp(cbind(x,y))$rotation

然后我们从第一个主成分和截距 ( n ) 计算斜率 ( m ):

# Y = mX + n
m <- v[2,1]/v[1,1]
n <- mean(y) - (m*mean(x))

我们的 model 定义为: f <- function(x){(m*x) + n}

我们可以 plot 它使用:

plot(x, y)
abline(n, m, col="blue")

最后我们 plot 总最小二乘拟合与普通最小二乘拟合。

plot(x, y)
abline(n, m, col="blue")
abline(lm(y~x), col="red")
legend("topleft", legend=c("TLS", "OLS"), col=c("blue", "red"), lty=1, bty="n")

TLS 与 OLS

如您所见,我们获得了与pracma::odregress相同的结果:

odr <- odregress(y, x)
print(odr$coeff)
print(paste(round(m, digits=7), round(n, digits=7)))

[1] 0.5199081 0.2558142
[1] 0.5199081 0.2558142

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM