我正在使用lm()包含多項式的訓練資料集。與在函式呼叫中[ ]使用subset引數相比,當我提前使用子集進行子集化時,我會得到不同的系數lm()。為什么?
library(ISLR2)
set.seed (1)
train <- sample(392, 196)
auto_train <- Auto[train,]
lm.fit.data <- lm(mpg ~ poly(horsepower, 2), data = auto_train)
summary(lm.fit.data)
#>
#> Call:
#> lm(formula = mpg ~ poly(horsepower, 2), data = auto_train)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -12.8711 -2.6655 -0.0096 2.0806 16.1063
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 23.8745 0.3171 75.298 < 2e-16 ***
#> poly(horsepower, 2)1 -89.3337 4.4389 -20.125 < 2e-16 ***
#> poly(horsepower, 2)2 33.2985 4.4389 7.501 2.25e-12 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 4.439 on 193 degrees of freedom
#> Multiple R-squared: 0.705, Adjusted R-squared: 0.702
#> F-statistic: 230.6 on 2 and 193 DF, p-value: < 2.2e-16
lm.fit.subset <- lm(mpg ~ poly(horsepower, 2), data = Auto, subset = train)
summary(lm.fit.subset)
#>
#> Call:
#> lm(formula = mpg ~ poly(horsepower, 2), data = Auto, subset = train)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -12.8711 -2.6655 -0.0096 2.0806 16.1063
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 23.5496 0.3175 74.182 < 2e-16 ***
#> poly(horsepower, 2)1 -123.5881 6.4587 -19.135 < 2e-16 ***
#> poly(horsepower, 2)2 47.7189 6.3613 7.501 2.25e-12 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 4.439 on 193 degrees of freedom
#> Multiple R-squared: 0.705, Adjusted R-squared: 0.702
#> F-statistic: 230.6 on 2 and 193 DF, p-value: < 2.2e-16
由reprex 包(v2.0.1)于 2021 年 12 月 26 日創建
uj5u.com熱心網友回復:
tl;dr正如其他評論和答案中所建議的那樣,正交多項式基的特征是在考慮子集之前計算的。
要在@JonManes 的回答中添加更多技術細節,讓我們看看定義 'model.frame' 的 R 代碼的第 545-553 行。
首先我們有(第 545-549 行)
if(is.null(attr(formula, "predvars"))) {
for (i in seq_along(varnames))
predvars[[i 1L]] <- makepredictcall(variables[[i]], vars[[i 1L]])
attr(formula, "predvars") <- predvars
}
- 在代碼中的這一點上,
formula將不是一個實際的公式(那太簡單了!),而是一個terms包含有關模型結構的各種對開發人員有用的資訊的物件...... predvars是定義需要像正交多項式和樣條曲線適當地恢復資料相關的基地資訊的屬性(見?makepredictcall一個小位的更多資訊,或在這里,雖然在一般這個東西真的是不良記錄,我希望它記錄在案在這里,但它不是......)。例如,
attr(terms(model.frame(mpg ~ poly(horsepower, 2), data = auto_train)), "predvars")
給
list(mpg, poly(horsepower, 2, coefs = list(alpha = c(102.612244897959,
142.498828460405), norm2 = c(1, 196, 277254.530612245, 625100662.205702
))))
這些是多項式的系數,取決于輸入資料的分布。
只有在這些資訊建立之后,在第 553 行,我們才能得到
subset <- eval(substitute(subset), data, env)
換句話說,在確定多項式特征之后,子集引數甚至不會被評估(然后所有這些資訊都被傳遞給內部C_modelframe函式,你真的不想看......)
請注意,這個問題并沒有導致統計學習場景訓練和測驗集之間的資訊泄漏:多項式的引數不影響模型的所有預測(理論上,雖然像往常一樣與浮點結果不太可能完全相同)。在最壞的情況下(如果訓練集和完整集非常不同),它可能會稍微降低數值穩定性。
FWIW 這一切都令人驚訝(對我而言)并且似乎值得在[email protected]郵件串列中提出(至少檔案中的注釋似乎是有序的)。
uj5u.com熱心網友回復:
在您的第二次呼叫中,它看起來poly()是在子集化之前首先計算的。比較以下輸出model.frame():
# first call
model.frame(mpg ~ poly(horsepower, 2), data = auto_train)[1:5,]
#> mpg poly(horsepower, 2).1 poly(horsepower, 2).2
#> 326 44.3 -0.1037171808 0.1498371034
#> 169 23.0 -0.0372467155 -0.0099055358
#> 131 26.0 -0.0429441840 -0.0000530004
#> 301 23.9 -0.0239526225 -0.0300950106
#> 272 23.2 0.0045347198 -0.0601592336
# second call
model.frame(mpg ~ poly(horsepower, 2), data = Auto, subset = train)[1:5,]
#> mpg poly(horsepower, 2).1 poly(horsepower, 2).2
#> 326 44.3 -0.0741931315 0.1133792778
#> 169 23.0 -0.0282078693 -0.0034299423
#> 131 26.0 -0.0321494632 0.0039029222
#> 301 23.9 -0.0190108168 -0.0185862638
#> 272 23.2 0.0006971527 -0.0418538153
# same as
model.frame(mpg ~ poly(horsepower, 2), data = Auto)[train,][1:5,]
#> mpg poly(horsepower, 2).1 poly(horsepower, 2).2
#> 326 44.3 -0.0741931315 0.1133792778
#> 169 23.0 -0.0282078693 -0.0034299423
#> 131 26.0 -0.0321494632 0.0039029222
#> 301 23.9 -0.0190108168 -0.0185862638
#> 272 23.2 0.0006971527 -0.0418538153
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/394669.html
上一篇:如何用R繪圖
下一篇:如何從r中的現有列創建新列
