向线性回归模型添加边界条件
Adding boundary conditions to linear regression model
是否可以在 R 中向 lm()
模型添加边界条件?
weight <- data.frame(mass = c(0.02, 0, 0.3, 0.05, 0.006, 0.01), size = c(0.5, 0.001, 0.1, 0.2, 0.06, 0.02), density = c(1, 0, 0.05, 0.012, 0.1, 0.01))
t <- lm(mass ~ size + density, data = weight)
例如,如果 result < 0
那么 result = 0
? - 因为质量不可能小于零。
写了之后找了一些资料?lm
但是没有例子怎么用
model, x, y, qr logicals. If TRUE the corresponding components of the
fit (the model frame, the model matrix, the response, the QR
decomposition) are returned.
我可以 运行 模型并在编译后检查边界条件的结果,但也许有更优雅的方法:)
result <- t$residuals + weight$mass
check <- function(x){
if(x < 0){
return(0)
}
return(x)
}
sapply(result, check)
这不再是线性模型,因为输出会有弯曲,所以您不能使用 lm
。但是,您可以使用 nls
函数(非线性最小二乘法)来解决这个问题,在您的公式中使用 pmax
。
为了证明这一点,让我们简化数据,使其只有一个预测变量(更容易绘制图表),并且这条线显然会低于零。
weight <- data.frame(mass = c(0, 0, 1, 2, 3), size = c(1, 3, 4, 6, 5))
# simple linear model
mod_linear <- lm(mass ~ size, data = weight)
# nls; note that you had to take guesses for the parameters.
mod_nls <- nls(mass ~ pmax(intercept + b1 * size, 0),
weight, start = list(intercept = 0, b1 = 1))
那么模型的系数就大不相同了:
coefficients(summary(mod_linear))
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.9054054 0.9404279 -0.962759 0.40668973
#> size 0.5540541 0.2254503 2.457544 0.09106616
coefficients(summary(mod_nls))
#> Estimate Std. Error t value Pr(>|t|)
#> intercept -2.1 1.6062378 -1.307403 0.282250
#> b1 0.8 0.3464102 2.309401 0.104088
您可以通过绘制两者的图形来查看预测的差异(并且可以看到非线性版本是更好的数据模型)。
library(ggplot2)
weight$linear <- predict(mod_linear)
weight$nonlinear <- predict(mod_nls)
ggplot(weight, aes(size, mass)) +
geom_point() +
geom_line(aes(y = linear), color = "red") +
geom_line(aes(y = nonlinear), color = "blue")
您可以使用日志 link 函数来执行此操作。尝试使用 glm()
指定日志 link.
是否可以在 R 中向 lm()
模型添加边界条件?
weight <- data.frame(mass = c(0.02, 0, 0.3, 0.05, 0.006, 0.01), size = c(0.5, 0.001, 0.1, 0.2, 0.06, 0.02), density = c(1, 0, 0.05, 0.012, 0.1, 0.01))
t <- lm(mass ~ size + density, data = weight)
例如,如果 result < 0
那么 result = 0
? - 因为质量不可能小于零。
写了之后找了一些资料?lm
但是没有例子怎么用
model, x, y, qr logicals. If TRUE the corresponding components of the fit (the model frame, the model matrix, the response, the QR decomposition) are returned.
我可以 运行 模型并在编译后检查边界条件的结果,但也许有更优雅的方法:)
result <- t$residuals + weight$mass
check <- function(x){
if(x < 0){
return(0)
}
return(x)
}
sapply(result, check)
这不再是线性模型,因为输出会有弯曲,所以您不能使用 lm
。但是,您可以使用 nls
函数(非线性最小二乘法)来解决这个问题,在您的公式中使用 pmax
。
为了证明这一点,让我们简化数据,使其只有一个预测变量(更容易绘制图表),并且这条线显然会低于零。
weight <- data.frame(mass = c(0, 0, 1, 2, 3), size = c(1, 3, 4, 6, 5))
# simple linear model
mod_linear <- lm(mass ~ size, data = weight)
# nls; note that you had to take guesses for the parameters.
mod_nls <- nls(mass ~ pmax(intercept + b1 * size, 0),
weight, start = list(intercept = 0, b1 = 1))
那么模型的系数就大不相同了:
coefficients(summary(mod_linear))
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -0.9054054 0.9404279 -0.962759 0.40668973
#> size 0.5540541 0.2254503 2.457544 0.09106616
coefficients(summary(mod_nls))
#> Estimate Std. Error t value Pr(>|t|)
#> intercept -2.1 1.6062378 -1.307403 0.282250
#> b1 0.8 0.3464102 2.309401 0.104088
您可以通过绘制两者的图形来查看预测的差异(并且可以看到非线性版本是更好的数据模型)。
library(ggplot2)
weight$linear <- predict(mod_linear)
weight$nonlinear <- predict(mod_nls)
ggplot(weight, aes(size, mass)) +
geom_point() +
geom_line(aes(y = linear), color = "red") +
geom_line(aes(y = nonlinear), color = "blue")
您可以使用日志 link 函数来执行此操作。尝试使用 glm()
指定日志 link.