[英]How do I use the means of the columns of a matrix as prediction values in a linear regression in R?
問題陳述:可以通過data(gasoline, package="pls").
使用問題 4 中的五種不同方法計算每個頻率的平均值並預測最佳模型的響應。
注意:這是 Julian Faraway 的第 2 版 R 線性模型練習 11.5。 此外,“來自問題 4 的五種不同方法”是:所有預測變量的線性回歸、使用 AIC 選擇的變量的線性回歸、主成分回歸、偏最小二乘法和嶺回歸。
到目前為止我的工作:我們做
require(pls)
data(gasoline, package="pls")
test_index = seq(1,nrow(gasoline),10)
train_index = 1:nrow(gasoline)
train_index = train_index[!train_index %in% test_index]
train_gas = gasoline[train_index,]
test_gas = gasoline[test_index,]
lmod = lm(octane~NIR,train_gas)
到目前為止,一切都很好。 但是,如果我查看模型的摘要,我會發現 348 個系數由於奇異性而沒有定義。 (為什么?)此外,將NIR
矩陣(預測變量)的列的平均值按摩到可接受的數據幀中是困難的。
我的問題:我怎樣才能達到高度挑剔的predict
功能會讓我做這樣的事情的地步:
new_data = apply(train_gas$NIR, 2, mean)
*some code here*
predict(lmod, new_data)
?
順便說一句,由於我在 Stats.SE 上進行了大量審核,我可以肯定地斷言,這個問題將在 Stats.SE 上關閉,因為它是題外話。 這是一個“編程或數據請求”,因此在 Stats.SE 上不受歡迎。
我還查找了一些關於 SO 的相關問題,但似乎沒有什么完全適合。
這對我來說確實看起來很CrossValidated -ish ... gasoline
是一個相當奇怪的對象,包含一個 401 列矩陣的“列”(元素):
data.frame': 60 obs. of 2 variables:
$ octane: num 85.3 85.2 88.5 83.4 87.9 ...
$ NIR : 'AsIs' num [1:60, 1:401] -0.0502 -0.0442 -0.0469 -0.0467 -0.0509 ...
但是,根本問題是這是一個 p>>n 問題; 有 60 個觀察值和 401 個預測變量。 因此,標准的線性回歸可能沒有意義——您可能想要使用像 LASSO/ridge (即glmnet
)這樣的懲罰方法。 這就是為什么你得到未定義的系數(沒有某種懲罰,你不能從 60 個觀察中估計 402 個系數(ncols + 1 的截距)......)
但是,如果我們確實想將其破解為可以進行線性模型和預測的形狀(盡管不明智):
NIR <- gasoline$NIR
class(NIR) <- "matrix" ## override "AsIs" class
g2 <- data.frame(octane = gasoline$octane, NIR)
dim(g2) ## 60 402 - now this is a 'regular' data frame
## using train_index from above
train_gas <- g2[train_index,]
lmod = lm(octane~., train_gas)
## drop first column (response); use `lapply()` to maintain list structure
new_data <- as.data.frame(lapply(train_gas[-1], mean))
predict(lmod, new_data)
## 1
## 87.16019
## Warning message:
## In predict.lm(lmod, new_data) :
## prediction from a rank-deficient fit may be misleading
稍微直接一點的方法(但仍然丑陋)是將模型擬合到原始的怪異結構,並構造一個與該怪異結構匹配的預測框架,即
pp <- data.frame(NIR=I(matrix(colMeans(train_gas$NIR), nrow = 1)))
如果你願意放棄predict()
你可以這樣做:
sum(na.omit(coef(lmod) * c(1, colMeans(train_gas$NIR))))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.