如果我正确理解了这个问题,它可以通过一种称为线性规划的方法来解决,使用 R 库“lpSolve”:
library(lpSolve)
regression_1 <- function( data )
{
n <- nrow(data)
L.obj <- c( rep(1,n), 0, 0 )
L.con <- rbind( cbind( diag(data$y), data$x, matrix(1,n,1) ),
cbind( diag(data$y), -data$x, -matrix(1,n,1) ) )
L.rhs <- matrix( cbind( data$y, -data$y ), 2*n, 1 )
L.dir <- rep(">=",2*n)
M <- lp("min", L.obj, L.con, L.dir, L.rhs )
a <- M["solution"][[1]][n+1]
b <- M["solution"][[1]][n+2]
return ( c(a,b) )
}
#--------------------------------------------------------------------
Error <- function( data, ab )
{
ab <- unlist(ab)
sum( abs((ab[1]*data$x+ab[2]-data$y)/data$y) )
}
#====================================================================
# Example:
data.x <- 0:12
data.y <- (3.0+0.3*data.x) * (1+sample(-150:150,length(data.x),TRUE)/1000)
data <- data.frame( x = data.x,
y = data.y )
ab <- regression_1(data)
N <- 30
eps <- (-N:N)/1000
neighborhood <- array( unlist(expand.grid(ab[1]+eps,ab[2]+eps)), c(2*N+1,2*N+1,2))
E <- apply(neighborhood,c(1,2),function(ab_plus_eps){Error(data,ab_plus_eps)})
t(data)
min(E)
Error(data,ab)
ab
令“n”为数据框“data”中的行数并假设
(所以“x”和“y”分别对应问题表述中的“X1”和“X0”。)
目标是通过斜率“a”和 y 截距“b”的线性函数来估计“y”。
更准确地说,我们希望最小化误差函数
我们的方法是使用线性规划。定义辅助变量“u[1],...,u[n+2]”。
稍后,对于每个 i
- 根据约束最小化函数“u[1]+...+u[n]”
- u[i]*y[i] >= u[n+1]*x[i]+u[n+2]-y[i] 和
- u[i]*y[i] >= -u[n+1]*x[i]-u[n+2]+y[i] 对于每个 i
在 "u[1]+...+u[n]" 最小化时,"u[i]" 等于 "abs((u[n+1]*x[i]+u[n] +2])/y[i]"
对于每个 i
这是示例的输出:
> t(data)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
x 0.000 1.0000 2.0000 3.0000 4.0000 5.0000 6.00 7.0000 8.0000 9.0000 10.000 11.0000 12.000
y 3.081 3.4353 3.2472 4.4772 3.7758 4.4055 5.04 5.5131 5.4378 5.5119 5.784 6.0102 5.907
> min(E)
[1] 0.6575712
> Error(data,ab)
[1] 0.6575712
> ab
[1] 0.2701 3.0810
比较:
> lm(data$y~data$x)
Call:
lm(formula = data$y ~ data$x)
Coefficients:
(Intercept) data$x
3.1741 0.2611
> Error(data,c(0.2611,3.1741))
[1] 0.67915
这些值不同的原因有两个:
- “lm”最小化回归线和采样数据之间的平方距离,而不是距离的绝对值。
- 在“lm”使用的错误术语中,没有除以“y”值。 (特别是在 0 附近没有问题,如上所述。)