2016-08-29 24 views
4

我急需幫助:因此,我使用dplyr按組運行迴歸。即是這樣的:關於級別數據的預測(使用組模型)

regressions <- mtcars %>% group_by(cyl) %>% 
do(fit = lm(wt ~ mpg + qsec + gear, .)) 

,我得到的模型在數據幀,看起來像這樣:

##  cyl  fit 
    ## (dbl) (chr) 
    ## 1  4 <S3:lm> 
    ## 2  6 <S3:lm> 
    ## 3  8 <S3:lm> 

現在我想預測對新的數據是短(也就是不一樣的漁政船爲我的培訓數據),並且具有相同的水平。 I.e 4,6,8 for cyl。我的問題是:我如何預測使用新/ testdata,以便每個模型僅在我的測試集中引用它們的級別。

so model cyl 4 only uses data 4 cyl to predict 
model cyl 6 uses data 6 cyl to predict 
model cyl 8 uses data 8 cyl to predict 
and so on and so forth.enter code here 

請記住測試數據包含其中的所有級別/組。

有沒有更簡單的方法來做到這一點。即按級別進行預測。目前我正試圖在掃帚包裝中使用增強功能,但它並不真正起作用。它所做的是:它通過我的所有測試數據運行每個模型,同時忽略該級別。

請幫忙!我正在以更大的規模進行此項工作,並且需要快速高效的工作。

回答

3

這可能是purrr以及dplyrtidyr嗚嗚嗚包是與列表一起工作的,我相信從長遠來看將取代do

例如,如果您有一個包含相同變量的測試數據集,我將調用mtcars_test

mtcars_test = mtcars 

您可以根據cyl將此數據集分爲三部分。

test_split = split(mtcars_test, mtcars_test$cyl) 

然後你可以使用map2通過三種模式來運行分裂測試數據一起做出預測。

library(purrr) 

map2(regressions$fit, test_split, predict) 

結果是一個列表。在你真實的情況下,你可能想要以更整潔的格式結果你的結果。在這種情況下,你可以使用帶有mutatetidyr::nest沿purrr功能,形成原始的迴歸結果:

library(tidyr) 

regs = mtcars %>% 
    group_by(cyl) %>% 
    nest() %>% 
    mutate(fit = map(data, ~lm(wt ~ mpg + qsec + gear, .))) 

然後通過map2同上,但內mutate添加的預測。在您的示例中嘗試使用do之後,此方法無效。

regs %>% 
    mutate(testpred = map2(fit, test_split, predict)) 

要獲得氣缸的測試預測的數量和最終的結果,使用tidyr::unnest

regs %>% 
    mutate(testpred = map2(fit, test_split, predict)) %>% 
    unnest(testpred) 

# A tibble: 32 × 2 
    cyl testpred 
    <dbl> <dbl> 
1  6 3.607719 
2  6 4.263550 
3  6 5.418092 
4  6 4.386157 
5  6 3.898692 
6  6 4.632542 
... 
+0

非常感謝您的回覆。有沒有一種方法可以使用相同的邏輯運行,例如使用auto.arima函數的ARIMA模型或使用相同邏輯的holtwinters?即按照上面的方式分割數據集,運行一個holtwitters,然後返回一個預測,例如每個週期的x個週期。 –

0

我遇到了一些問題,讓到data.frame內lm對象,以便在第一循環不漂亮:

A <- list() 
for (i in unique(mtcars$cyl)) { 
    A[[as.character(i)]] <- predict(as.list(regressions[regressions$cyl == i, ])$fit[[1]], 
        newdata = mtcars[mtcars$cyl == i, ]) 
} 

一個簡單的辦法是做兩個步驟(迴歸再預測)內的同循環。

reg <- list() 
pred <- list() 
for (cyl in unique(mtcars$cyl)) { 
    reg[[as.character(cyl)]] <- lm(wt ~ mpg + qsec + gear, filter(mtcars, cyl == cyl)) 
    pred[[as.character(cyl)]] <- predict(reg[[as.character(cyl)]], 
             newdata = filter(mtcars, cyl == cyl)) 
} 

很明顯,你可以在unqieu(mtcars$cyl)使用lapply對於任何這兩個方法的直接。在這兩種情況下,我都在循環迭代器上使用了as.character,以確保結果列表不會增加到六個圓柱體,留下五個空白點。

最後,您可以使用*元素將所有變量與cyl變量交叉,以便事實上創建與組相同數量的模型。然後您可以直接使用預測而不必子集。請注意,我將cyl變量切換爲factor類,以確保每組有一個斜坡。我還在公式括號中明確指定了截距,以確保按組進行不同的截取。

mtcars$cyl <- factor(mtcars$cyl) 
reg <- lm(wt ~ (1 + mpg + qsec + gear)*cyl, mtcars) 
predict(reg, mtcars) 

用這種方法唯一的問題是,係數是比較難以解釋,(即:係數mpg爲組cyl = 6是係數mpg加上mpg:cyl6係數)

0

這是使用broom::augment非常緊湊和容易實現的。

你適合迴歸和評分:

library(broom) 
library(dplyr) 

# fit the set of regressions by cyl 
regressions = mtcars %>% group_by(cyl) %>% 
    do(fit = lm(wt ~ mpg + qsec + gear, .)) 

# score the regressions by cyl 
scores = regressions %>% 
    augment(fit) 

您可以檢查這個結果是相同的個體迴歸擬合和評分的結果由cyl值定義的組。

# check that regression with cyl == 4 and predictions gives the same result 
lm_4 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 4)) 
predict(lm_4, newdata = subset(mtcars, cyl == 4)) 
scores %>% 
    filter(cyl == 4) 

# check that regression with cyl == 8 and predictions gives the same result 
lm_8 = lm(wt ~ mpg + qsec + gear, data = subset(mtcars, cyl == 8)) 
predict(lm_8, newdata = subset(mtcars, cyl == 8)) 
scores %>% 
    filter(cyl == 8) 
+0

'augment'對訓練集上的預測非常有用,但是我沒有看到如何使用它來進行新的測試集預測。 – aosmith

+0

@aosmith感謝您的評論。 'augment'支持'newdata'參數。請參閱'augment.lm'的文檔。 – tchakravarty

+0

在使用它之前,新數據是否必須按因子拆分,或者您能否定義正確的子集來用於'augment'內的每個組的預測? – aosmith

相關問題