作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 lm
的一些令人不安的行为感兴趣函数和相关的predict.lm
R 中的函数。splines
基础包提供函数bs
生成 b 样条展开,然后可用于使用 lm
拟合样条模型,一个通用的线性模型拟合函数。lm
和 predict.lm
函数具有许多利用公式和术语的内置便利性。如果调用bs()
嵌套在 lm
中调用,则用户可以向 predict
提供单变量数据,并且此数据将自动扩展为适当的 b 样条基础。然后像往常一样预测这个扩展的数据矩阵。
library(splines)
x <- sort(runif(50, 0, 10))
y <- x^2
splineModel <- lm(y ~ bs(x, y, degree = 3, knots = c(3, 6)))
newData <- data.frame(x = 4)
prediction <- predict(splineModel, newData) # 16
plot(x, y)
lines(x, splineModel$fitted.values, col = 'blue3')
points(newData$x, prediction, pch = 3, cex = 3, col = 'red3')
legend("topleft", legend = c("Data", "Fitted Values", "Predicted Value"),
pch = c(1, NA, 3), col = c('black', 'blue3', 'red3'), lty = c(NA, 1, NA))
::
时,就会发生奇怪的事情。运算符明确指出
bs
函数从
splines
的命名空间导出包裹。除了该更改之外,以下代码段是相同的:
library(splines)
x <- sort(runif(50, 0, 10))
y <- x^2
splineModel <- lm(y ~ splines::bs(x, y, degree = 3, knots = c(3, 6)))
newData <- data.frame(x = 4)
prediction <- predict(splineModel, newData) # 6.40171
plot(x, y)
lines(x, splineModel$fitted.values, col = 'blue3')
points(newData$x, prediction, pch = 3, cex = 3, col = 'red3')
legend("topleft", legend = c("Data", "Fitted Values", "Predicted Value"),
pch = c(1, NA, 3), col = c('black', 'blue3', 'red3'), lty = c(NA, 1, NA))
splines
则在第二个片段中产生完全相同的结果。从未使用
library
附加软件包首先。我想不出使用
::
的另一种情况。已加载包上的运算符(operator)会更改程序行为。
splines
中的其他函数也会出现相同的行为。像自然样条基础实现
ns
.有趣的是,在这两种情况下,“y 帽子”或拟合值都是合理的并且相互匹配。据我所知,除了属性名称外,拟合的模型对象是相同的。
predict.lm
但无法确定分歧发生的位置。 最佳答案
所以问题是模型需要跟踪使用原始数据计算的节点,并在预测新数据时使用这些值。这通常发生在 model.frame()
调用lm()
称呼。 bs()
函数返回一个类 "bs"
并且在制作 model.frame 时,该列被发送到 splines:::makepredictcall.bs
试图捕捉边界结。 (您可以在 makepredictcall
函数中看到 model.frame.default
调用。)
但是如果我们比较结果
splineModel1 <- lm(y ~ bs(x, y, degree = 3, knots = c(3, 6)))
attr(terms(splineModel1), "predvar")
# list(y, bs(x, degree = 3L, knots = c(3, 6), Boundary.knots = c(0.275912734214216,
# 9.14309860439971), intercept = FALSE))
splineModel2 <- lm(y ~ splines::bs(x, y, degree = 3, knots = c(3, 6)))
attr(terms(splineModel2), "predvar")
# list(y, splines::bs(x, y, degree = 3, knots = c(3, 6)))
Boundary.knots
.这是因为
splines:::makepredictcall.bs
实际查看调用名称的函数
function (var, call) {
if (as.character(call)[1L] != "bs")
return(call)
...
}
splines::bs
在公式中,然后
as.character(call)[1L]
返回
"splines::bs"
不匹配
"bs"
所以什么也没有发生。我不清楚为什么要进行此检查。似乎方法调度应该足以假设它是
bs
目的。
bs()
不应该在没有加载包的情况下调用,因为像
makepredictcall.bs
这样的函数也不要导入,因此这些对象的自定义调度将被破坏。
关于r - lm() 和 predict.lm() 的奇怪行为取决于显式命名空间访问器的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43505053/
我是一名优秀的程序员,十分优秀!