As previsões de um modelo de floresta aleatória têm um intervalo de previsão?


52

Se eu executar um randomForestmodelo, posso fazer previsões com base no modelo. Existe uma maneira de obter um intervalo de previsão de cada uma das previsões, de modo que eu saiba o quão "seguro" o modelo é de sua resposta. Se isso é possível, é simplesmente baseado na variabilidade da variável dependente para todo o modelo ou terá intervalos mais amplos e mais estreitos, dependendo da árvore de decisão específica que foi seguida para uma previsão específica?


3
AFAIK, todas as bibliotecas de RF têm algum tipo de scorefunção para avaliar o desempenho. Como a produção é baseada no voto majoritário das árvores na floresta, em caso de classificação, será dada uma probabilidade de que esse resultado seja verdadeiro, com base na distribuição de votos. Mas não tenho certeza da regressão .... Qual biblioteca você usa?
precisa saber é o seguinte

11
Você deve ler o seguinte: stats.stackexchange.com/questions/12425/…
0asa

Respostas:


40

Isso é parcialmente uma resposta ao @Sashikanth Dareddy (já que não caberá em um comentário) e parcialmente uma resposta à postagem original.

Lembre-se do que é um intervalo de previsão, é um intervalo ou conjunto de valores em que previmos que futuras observações ocorrerão. Geralmente, o intervalo de previsão possui 2 partes principais que determinam sua largura, uma parte que representa a incerteza sobre a média prevista (ou outro parâmetro), que é a parte do intervalo de confiança e uma parte que representa a variabilidade das observações individuais em torno dessa média. O intervalo de confiança é robusto devido ao Teorema do Limite Central e, no caso de uma floresta aleatória, o bootstrapping também ajuda. Mas o intervalo de previsão depende completamente das suposições sobre como os dados são distribuídos, dadas as variáveis ​​preditoras, CLT e bootstrapping não afetam essa parte.

O intervalo de previsão deve ser maior, onde o intervalo de confiança correspondente também seria maior. Outras coisas que afetariam a largura do intervalo de previsão são suposições sobre variância igual ou não; isso tem que vir do conhecimento do pesquisador, não do modelo de floresta aleatória.

Um intervalo de previsão não faz sentido para um resultado categórico (você poderia fazer um conjunto de previsões em vez de um intervalo, mas na maioria das vezes provavelmente não seria muito informativo).

Podemos ver alguns dos problemas relacionados aos intervalos de previsão simulando dados em que sabemos a verdade exata. Considere os seguintes dados:

set.seed(1)

x1 <- rep(0:1, each=500)
x2 <- rep(0:1, each=250, length=1000)

y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000)

Esses dados específicos seguem as premissas para uma regressão linear e são razoavelmente diretos para um ajuste aleatório da floresta. Sabemos pelo modelo "verdadeiro" que, quando ambos os preditores são 0, a média é 10, também sabemos que os pontos individuais seguem uma distribuição normal com desvio padrão de 1. Isso significa que o intervalo de previsão de 95%, com base no conhecimento perfeito para esses pontos seriam de 8 a 12 (bem, na verdade, de 8,04 a 11,96, mas o arredondamento o torna mais simples). Qualquer intervalo de previsão estimado deve ser maior que isso (não ter informações perfeitas adiciona largura para compensar) e inclui esse intervalo.

Vejamos os intervalos da regressão:

fit1 <- lm(y ~ x1 * x2)

newdat <- expand.grid(x1=0:1, x2=0:1)

(pred.lm.ci <- predict(fit1, newdat, interval='confidence'))
#        fit       lwr      upr
# 1 10.02217  9.893664 10.15067
# 2 14.90927 14.780765 15.03778
# 3 20.02312 19.894613 20.15162
# 4 21.99885 21.870343 22.12735

(pred.lm.pi <- predict(fit1, newdat, interval='prediction'))
#        fit      lwr      upr
# 1 10.02217  7.98626 12.05808
# 2 14.90927 12.87336 16.94518
# 3 20.02312 17.98721 22.05903
# 4 21.99885 19.96294 24.03476

Podemos ver que há alguma incerteza nos meios estimados (intervalo de confiança) e isso nos dá um intervalo de previsão que é mais amplo (mas inclui) o intervalo de 8 a 12.

Agora, vejamos o intervalo com base nas previsões individuais de árvores individuais (devemos esperar que sejam mais amplas, pois a floresta aleatória não se beneficia das suposições (que sabemos que são verdadeiras para esses dados) que a regressão linear):

library(randomForest)
fit2 <- randomForest(y ~ x1 + x2, ntree=1001)

pred.rf <- predict(fit2, newdat, predict.all=TRUE)

pred.rf.int <- apply(pred.rf$individual, 1, function(x) {
  c(mean(x) + c(-1, 1) * sd(x), 
  quantile(x, c(0.025, 0.975)))
})

t(pred.rf.int)
#                           2.5%    97.5%
# 1  9.785533 13.88629  9.920507 15.28662
# 2 13.017484 17.22297 12.330821 18.65796
# 3 16.764298 21.40525 14.749296 21.09071
# 4 19.494116 22.33632 18.245580 22.09904

Os intervalos são maiores que os intervalos de previsão de regressão, mas não cobrem todo o intervalo. Eles incluem os valores verdadeiros e, portanto, podem ser legítimos como intervalos de confiança, mas estão prevendo apenas onde está a média (valor previsto), não a peça adicional para a distribuição em torno dessa média. Para o primeiro caso em que x1 e x2 são 0, os intervalos não ficam abaixo de 9,7, isso é muito diferente do verdadeiro intervalo de previsão que desce para 8. Se gerarmos novos pontos de dados, haverá vários pontos (muito mais de 5%) que estão nos intervalos verdadeiro e de regressão, mas não se enquadram nos intervalos aleatórios da floresta.

Para gerar um intervalo de predição, você precisará fazer algumas suposições fortes sobre a distribuição dos pontos individuais em torno das médias previstas, em seguida, você poderá obter as previsões das árvores individuais (a parte do intervalo de confiança de inicialização) e gerar um valor aleatório a partir da suposição distribuição com esse centro. Os quantis dessas peças geradas podem formar o intervalo de previsão (mas eu ainda o testaria, talvez seja necessário repetir o processo várias vezes e combinar).

Aqui está um exemplo de como fazer isso adicionando desvios normais (já que sabemos que os dados originais usavam um normal) às previsões com o desvio padrão com base no MSE estimado dessa árvore:

pred.rf.int2 <- sapply(1:4, function(i) {
  tmp <- pred.rf$individual[i, ] + rnorm(1001, 0, sqrt(fit2$mse))
  quantile(tmp, c(0.025, 0.975))
})
t(pred.rf.int2)
#           2.5%    97.5%
# [1,]  7.351609 17.31065
# [2,] 10.386273 20.23700
# [3,] 13.004428 23.55154
# [4,] 16.344504 24.35970

Esses intervalos contêm aqueles baseados em conhecimento perfeito, portanto, pareça razoável. Porém, eles dependerão muito das suposições feitas (as suposições são válidas aqui porque usamos o conhecimento de como os dados foram simulados, elas podem não ser tão válidas em casos reais de dados). Eu ainda repetiria as simulações várias vezes para dados mais parecidos com os dados reais (mas simulados para que você saiba a verdade) várias vezes antes de confiar totalmente nesse método.


11

Percebo que este é um post antigo, mas tenho feito algumas simulações e pensei em compartilhar minhas descobertas.

O @GregSnow fez um post muito detalhado sobre isso, mas acredito que, ao calcular o intervalo usando previsões de árvores individuais, ele estava olhando que é apenas um intervalo de previsão de 70%. Precisamos examinar para obter o intervalo de previsão de 95%.[ μ + 1,96 σ , μ - 1,96 σ ][μ+σ,μσ][μ+1.96σ,μ1.96σ]

Fazendo essa alteração no código @GregSnow, obtemos os seguintes resultados

set.seed(1)
x1 <- rep( 0:1, each=500 )
x2 <- rep( 0:1, each=250, length=1000 )
y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000)

library(randomForest)
fit2 <- randomForest(y~x1+x2)
pred.rf <- predict(fit2, newdat, predict.all=TRUE)
pred.rf.int <- t(apply( pred.rf$individual, 1, function(x){ 
  c( mean(x) + c(-1.96,1.96)*sd(x), quantile(x, c(0.025,0.975)) )}))

pred.rf.int
                          2.5%    97.5%
1  7.826896 16.05521  9.915482 15.31431
2 11.010662 19.35793 12.298995 18.64296
3 14.296697 23.61657 14.749248 21.11239
4 18.000229 23.73539 18.237448 22.10331

Agora, comparando-os com os intervalos gerados pela adição de desvio normal às previsões com desvio padrão, conforme MSE como o @GregSnow sugeriu que obtivéssemos,

pred.rf.int2 <- sapply(1:4, function(i) {
   tmp <- pred.rf$individual[i,] + rnorm(1000, 0, sqrt(fit2$mse))
   quantile(tmp, c(0.025, 0.975))
   })
t(pred.rf.int2)
          2.5%    97.5%
[1,]  7.486895 17.21144
[2,] 10.551811 20.50633
[3,] 12.959318 23.46027
[4,] 16.444967 24.57601

O intervalo de ambas as abordagens agora parece muito próximo. A plotagem do intervalo de previsão para as três abordagens contra a distribuição de erros neste caso é mostrada abaixo

insira a descrição da imagem aqui

  • Linhas pretas = intervalos de previsão da regressão linear,
  • Linhas vermelhas = intervalos aleatórios da floresta calculados em previsões individuais,
  • Linhas azuis = Intervalos aleatórios da floresta calculados adicionando desvio normal às previsões

Agora, vamos executar novamente a simulação, mas desta vez aumentando a variação do termo de erro. Se nossos cálculos de intervalo de previsão forem bons, devemos terminar com intervalos mais amplos do que os que obtivemos acima.

set.seed(1)
x1 <- rep( 0:1, each=500 )
x2 <- rep( 0:1, each=250, length=1000 )
y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000,mean=0,sd=5)

fit1 <- lm(y~x1+x2)
newdat <- expand.grid(x1=0:1,x2=0:1)
predict(fit1,newdata=newdat,interval = "prediction")
      fit       lwr      upr
1 10.75006  0.503170 20.99695
2 13.90714  3.660248 24.15403
3 19.47638  9.229490 29.72327
4 22.63346 12.386568 32.88035

set.seed(1)
fit2 <- randomForest(y~x1+x2,localImp=T)
pred.rf.int <- t(apply( pred.rf$individual, 1, function(x){ 
  c( mean(x) + c(-1.96,1.96)*sd(x), quantile(x, c(0.025,0.975)) )}))
pred.rf.int
                          2.5%    97.5%
1  7.889934 15.53642  9.564565 15.47893
2 10.616744 18.78837 11.965325 18.51922
3 15.024598 23.67563 14.724964 21.43195
4 17.967246 23.88760 17.858866 22.54337

pred.rf.int2 <- sapply(1:4, function(i) {
   tmp <- pred.rf$individual[i,] + rnorm(1000, 0, sqrt(fit2$mse))
   quantile(tmp, c(0.025, 0.975))
   })
t(pred.rf.int2)
         2.5%    97.5%
[1,] 1.291450 22.89231
[2,] 4.193414 25.93963
[3,] 7.428309 30.07291
[4,] 9.938158 31.63777

insira a descrição da imagem aqui

Agora, isso deixa claro que o cálculo dos intervalos de previsão pela segunda abordagem é muito mais preciso e está produzindo resultados bem próximos do intervalo de previsão da regressão linear.

Partindo da premissa de normalidade, existe outra maneira mais fácil de calcular os intervalos de previsão de floresta aleatória. De cada uma das árvores, temos o valor previsto ( ) e o erro quadrático médio ( ). Portanto, a previsão de cada árvore individual pode ser considerada como . Usando as propriedades normais de distribuição, nossa previsão da floresta aleatória teria a distribuição . Aplicando isso ao exemplo que discutimos acima, obtemos os resultados abaixo M S E i N ( μ i , R M S E i ) N ( μ i / n , R M S E i / n )μiMSEiN(μi,RMSEi)N(μi/n,RMSEi/n)

mean.rf <- pred.rf$aggregate
sd.rf <- mean(sqrt(fit2$mse))
pred.rf.int3 <- cbind(mean.rf - 1.96*sd.rf, mean.rf + 1.96*sd.rf)
pred.rf.int3
1  1.332711 22.09364
2  4.322090 25.08302
3  8.969650 29.73058
4 10.546957 31.30789

Eles são muito bons com os intervalos lineares do modelo e também com a abordagem sugerida pelo @GregSnow. Mas observe que a suposição subjacente em todos os métodos que discutimos é que os erros seguem uma distribuição Normal.


10

Se você usar R, poderá produzir facilmente intervalos de previsão para as previsões de uma regressão aleatória de florestas: Basta usar o pacote quantregForest(disponível no CRAN ) e ler o artigo de N. Meinshausen sobre como quantis condicionais podem ser inferidos com florestas de regressão quantil e como eles pode ser usado para criar intervalos de previsão. Muito informativo, mesmo se você não trabalha com o R!



2
Essa parece ser a resposta apropriada e não requer premissas distributivas em relação ao intervalo preditivo. Há um tutorial sobre como fazer isso em python aqui: blog.datadive.net/prediction-intervals-for-random-forests
colin

6

Isso é fácil de resolver com o randomForest.

Primeiro, deixe-me lidar com a tarefa de regressão (supondo que sua floresta tenha 1000 árvores). Na predictfunção, você tem a opção de retornar resultados de árvores individuais. Isso significa que você receberá 1000 colunas de saída. Podemos calcular a média das 1000 colunas para cada linha - essa é a saída regular que o RF teria produzido de qualquer maneira. Agora, para obter o intervalo de previsão, digamos +/- 2 std. desvios, tudo o que você precisa fazer é, para cada linha, dos 1000 valores calcular +/- 2 std. desvios e torne esses limites superiores e inferiores em sua previsão.

Segundo, no caso de classificação, lembre-se de que cada árvore gera 1 ou 0 (por padrão) e a soma de todas as 1000 árvores divididas por 1000 fornece a probabilidade de classe (no caso de classificação binária). Para colocar um intervalo de previsão na probabilidade, você precisa modificar o valor mínimo. opção nodesize (consulte a documentação randomForest para obter o nome exato dessa opção) depois de definir um valor >> 1, as árvores individuais produzirão números entre 1 e 0. Agora, daqui em diante, você pode repetir o mesmo processo descrito acima para a tarefa de regressão.

Espero que faça sentido.


Eu não tentei, mas parece fazer sentido. Obrigado por responder minha pergunta antiga.
precisa

11
Eu acho que esse método daria algo mais como um intervalo de confiança do que um intervalo de previsão. Os resultados devem ser comparados a um modelo linear, onde a teoria dos intervalos de previsão está bem estabelecida. Melhor em alguns dados simulados em que a verdade é conhecida e todas as suposições são válidas.
Greg Neve

11
@ GregSnow: O que você obterá do que descrevi acima é definitivamente o intervalo de previsão. Observe que os intervalos de previsão são geralmente muito mais amplos que os intervalos de confiança, já que os intervalos de confiança estão realmente especificando onde está a estatística média de uma quantia, onde a previsão se refere a apenas uma observação, portanto, maior incerteza e, portanto, intervalos mais amplos. As 1000 previsões que você recebe de 1000 árvores podem ser consideradas uma amostra inicializada e você não precisa aplicar as premissas de normalidade aqui. Mesmo análises simples de decil fornecerão bons resultados.

5
@SashikanthDareddy, O que você obterá com o que você descreve definitivamente não é um intervalo de previsão. Um intervalo de previsão é determinado por mais do que apenas ser maior. Sim, as árvores individuais formam um bootstrap, mas o bootstrap estima parâmetros, não valores individuais. O intervalo de previsão depende muito da distribuição dos pontos individuais. O fato de seu método fornecer um intervalo para as proporções com um resultado categórico em vez das categorias mostra isso. Veja meu exemplo na resposta adicionada.
Greg Neve

0

Eu tentei algumas opções (tudo isso WIP):

  1. Na verdade, eu fiz da variável dependente um problema de classificação com os resultados como intervalos, em vez de um único valor. Os resultados obtidos foram ruins, em comparação com o uso de um valor simples. Eu desisti dessa abordagem.

  2. Em seguida, converti-o em vários problemas de classificação, cada um dos quais com um limite inferior para o intervalo (o resultado era o modelo cruzando o limite inferior ou não) e, em seguida, executei todos os modelos (~ 20) e, em seguida, combinou o resultado para obter uma resposta final como um intervalo. Isso funciona melhor que 1 acima, mas não tão bom quanto eu preciso. Ainda estou trabalhando para melhorar essa abordagem.

Usei estimativas OOB e deixe de fora para decidir o quão bom / ruim meus modelos são.


0

O problema de construir intervalos de previsão para previsões aleatórias de florestas foi abordado no seguinte artigo:

Zhang, Haozhe, Joshua Zimmerman, Dan Nettleton e Daniel J. Nordman. "Intervalos aleatórios de previsão de florestas". Estatístico Americano, 2019.

O pacote R "rfinterval" é sua implementação disponível no CRAN.

Instalação

Para instalar o pacote R rfinterval :

#install.packages("devtools")
#devtools::install_github(repo="haozhestat/rfinterval")
install.packages("rfinterval")
library(rfinterval)
?rfinterval

Uso

Começo rápido:

train_data <- sim_data(n = 1000, p = 10)
test_data <- sim_data(n = 1000, p = 10)

output <- rfinterval(y~., train_data = train_data, test_data = test_data,
                     method = c("oob", "split-conformal", "quantreg"),
                     symmetry = TRUE,alpha = 0.1)

### print the marginal coverage of OOB prediction interval
mean(output$oob_interval$lo < test_data$y & output$oob_interval$up > test_data$y)

### print the marginal coverage of Split-conformal prediction interval
mean(output$sc_interval$lo < test_data$y & output$sc_interval$up > test_data$y)

### print the marginal coverage of Quantile regression forest prediction interval
mean(output$quantreg_interval$lo < test_data$y & output$quantreg_interval$up > test_data$y)

Exemplo de dados:

oob_interval <- rfinterval(pm2.5 ~ .,
                            train_data = BeijingPM25[1:1000, ],
                            test_data = BeijingPM25[1001:2000, ],
                            method = "oob",
                            symmetry = TRUE,
                            alpha = 0.1)
str(oob_interval)

11
Bem-vindo ao site, @ xiaolongmao.Você pode querer fazer nosso tour . Não poste respostas idênticas em vários tópicos. Tente personalizar suas respostas para a pergunta específica em cada segmento. Se você tem um caso em que realmente acredita que uma resposta idêntica responde completamente à pergunta, isso implica que é uma duplicata. Quando você alcança 50 reputação, pode postar um comentário no OP. Enquanto isso, você pode sinalizar o Q para fechar como uma duplicata.
gung - Restabelece Monica
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.