O randomForest de R não pode lidar com mais de 32 níveis. O que é solução alternativa?

22

O pacote randomForest de R não pode lidar com fatores com mais de 32 níveis. Quando recebe mais de 32 níveis, emite uma mensagem de erro:

Não é possível lidar com preditores categóricos com mais de 32 categorias.

Mas os dados que tenho têm vários fatores. Alguns deles têm mais de 1000 níveis e outros mais de 100. Tem até 'estado' dos estados unidos, que é 52.

Então, aqui está a minha pergunta.

  1. Por que existe essa limitação? randomForest se recusa a executar mesmo para o caso simples.

    > d <- data.frame(x=factor(1:50), y=1:50)
    > randomForest(y ~ x, data=d)
      Error in randomForest.default(m, y, ...) : 
      Can not handle categorical predictors with more than 32 categories.

    Se é simplesmente devido à limitação de memória, como o randomForeestRegressor do scikit learn pode ser executado com mais de 32 níveis?

  2. Qual é a melhor maneira de lidar com esse problema? Suponha que eu possua variáveis ​​independentes X1, X2, ..., X50 e Y seja variável dependente. E suponha que X1, X2 e X3 tenham mais de 32 níveis. O que devo fazer?

    O que estou pensando é em executar o algoritmo de agrupamento para cada um dos X1, X2 e X3, em que a distância é definida como diferença em Y. Vou executar três agrupamentos, pois há três variáveis ​​problemáticas. E em cada agrupamento, desejo encontrar níveis semelhantes. E eu vou fundi-los.

    Como isso soa?

Minkoo Seo
fonte
Pesquisando na web com o nome do pacote e a mensagem de erro fornece algumas respostas.
Roland
5
@Roland Na verdade, isso me trouxe aqui ...
isomorphismes
1
você pode tentar a ciência de dados, já que várias mentes estatísticas têm experiência em programação de dados com muitas dimensões.
aeroNotAuto
2
ATUALIZAÇÃO: Desde a versão 4.6-9, randomForestpode lidar com preditores categóricos com até 53 níveis. Notícias
Ben
Como a floresta aleatória de R determina o número de níveis? Eu acho que nível significa categorias.
26417 ajp

Respostas:

25

É realmente um constrangimento muito razoável porque um split em um fator com níveis é realmente uma seleção de um dos 2 N - 2 combinações possíveis. Assim, mesmo com N como 25, o espaço das combinações é tão grande que essa inferência faz pouco sentido.N2N-2N

N

A outra opção é alterar a representação - talvez seu resultado não dependa diretamente da entidade do estado, mas, por exemplo, área, população, número de pinheiros per capita ou outros atributos que você possa conectar ao seu sistema de informação.

Também pode ser que cada estado seja uma entidade tão isolada e não correlacionada que exija um modelo separado para si.

O agrupamento com base em uma decisão provavelmente é uma má idéia, pois dessa maneira você contrabandeia informações da decisão para atributos, que geralmente terminam em super ajuste.


fonte
4
Pode ser facilmente movido, embora de uma maneira um pouco tediosa. Por exemplo, se você tiver entre 33 e 1024 níveis, crie dois fatores cada um de <= 32 níveis.
KalEl 23/05
15

O principal motivo é como o randomForest é implementado. A implementação de R segue muito as especificações originais de Breiman. O que é importante notar aqui é que, para variáveis ​​fatoriais / categóricas, o critério de divisão é binário com alguns valores de rótulo à esquerda e os demais valores de rótulo à direita.

0 01[0 0;2M-1]

Por que as implementações de Weka e Python funcionam?

A implementação weka não usa árvores CART por padrão. Utiliza árvores C45 que não apresentam esse problema computacional, pois para entradas categóricas se divide em vários nós, um para cada valor de nível.

A implementação da floresta aleatória python não pode usar variáveis ​​categóricas / fator. Você precisa codificar essas variáveis ​​em variáveis ​​dummy ou numéricas.

M

rapaio
fonte
2
Muito obrigado! Segue da sua resposta que a implementação de R para tratar valores categóricos é superior à do Python (lembro-me que Max Kuhn mencionou que o agrupamento de variáveis ​​categóricas para RF fornece resultados um pouco melhores do que dummificá-las) ou, pelo menos, em execução Random Forest in R vs Python Eu tenho uma chance muito boa de obter resultados diferentes (precisão, etc ...)? Pela sua experiência, ao modelar, faz sentido tentar agrupar vars (em R) e dummificá-los e depois comparar duas abordagens?
Sergey Bushmanov
2
A codificação fictícia funciona, mas pode produzir apenas uma categoria vs todas. Após a codificação, as variáveis ​​são testadas uma vez por vez. Portanto, é impossível implementar o twoing. Se esse recurso puder ajudar, acho que praticamente não há grandes diferenças. No entanto, há outras coisas que podem exigir atenção ao trabalhar com importância variável: algumas implementações são direcionadas para categorias com vários níveis. Veja os documentos de Carolin Strobl para obter detalhes: statistik.uni-dortmund.de/useR-2008/slides/Strobl+Zeileis.pdf . Em R, existem algumas implementações que não possuem esse viés.
Rapaio 21/10
2

Você pode tentar representar essa coluna de maneira diferente. Você pode representar os mesmos dados que um quadro de dados esparso.

Código mínimo viável;

example <- as.data.frame(c("A", "A", "B", "F", "C", "G", "C", "D", "E", "F"))
names(example) <- "strcol"

for(level in unique(example$strcol)){
      example[paste("dummy", level, sep = "_")] <- ifelse(example$strcol == level,     1, 0)
}

Observe como agora cada valor na coluna original se torna uma coluna dummy separada.

Código de exemplo mais extenso;

set.seed(0)
combs1 = sample.int(33, size= 10000, replace=TRUE)
combs2 = sample.int(33, size= 10000, replace=TRUE)
combs3 = combs1 * combs2 + rnorm(10000,mean=0,100)
df_hard = data.frame(y=combs3, first=factor(combs1), second=factor(combs2))

for(level in unique(df_hard$first)){
    df_hard[paste("first", level, sep = "_")] <- ifelse(df_hard$first == level, 1, 0)
}

for(level in unique(df_hard$second)){
    df_hard[paste("second", level, sep = "_")] <- ifelse(df_hard$second == level, 1, 0)
}

example$first <- NULL
example$second <- NULL

rf_mod = randomForest( y ~ ., data=example )

Mesmo que esse trecho de código mostre que você realmente não receberá mais o erro, notará que o algoritmo randomForest agora precisa de um longo tempo antes de terminar. Isso ocorre devido a uma restrição de CPU; agora, você também pode mapear essa tarefa por amostragem.

Para mais informações, consulte este blogpost:

https://blog.cloudera.com/blog/2013/02/how-to-resample-from-a-large-data-set-in-parallel-with-r-on-hadoop/

Vincent Warmerdam
fonte
O segundo bloco de código parece confuso. Embora você use df_hard em todo o corpo, nas últimas linhas, você define "first" e "second" como NULL e também usa "example" como dados para randomForest, isso não faz sentido. eu, já que não há conexão entre exemplo e df_hard.
Özgür
Vincent, você não acha que vou acabar com um problema tão grande se tiver níveis da ordem de mais de 100? Você sugere adicionar aleatoriamente cada coluna como entrada?
Hardik Gupta
Outra alternativa é usar a implementação da floresta aleatória em h2o; isso tem melhor suporte para grandes conjuntos de dados. Eu não entendo o bit "adicionar cada coluna como entrada para aleatório".
Vincent Warmerdam
0

Você pode usar o pacote extraTrees. O algoritmo de florestas extremamente aleatórias não tenta nenhum ponto de interrupção / divisão, mas apenas um subconjunto aleatório limitado de divisões.

Soren Havelund Welling
fonte
1
extraTrees tem limitação, no sentido de que sua entrada precisa ser uma matriz de dados numérica, certo?
Hardik Gupta
0

Outra opção: dependendo do número de níveis e do número de observações em seus dados, você pode mesclar alguns níveis. Além de ficar abaixo do limite, pode reduzir a variação se você tiver muitos níveis com apenas algumas observações. Hadley é forcats: fct_lump faz isso.

Scott Kaiser
fonte