R 'randomForest не може обробити більше 32 рівнів. Що таке вирішення?


22

R-пакет randomForest R не може обробляти коефіцієнт з більш ніж 32 рівнями. Коли йому задано більше 32 рівнів, він видає повідомлення про помилку:

Не може працювати з категоричними прогнозами з більш ніж 32 категоріями.

Але у мене є кілька факторів. Деякі з них мають рівні 1000+, а деякі - 100+. У неї навіть є "держава" Сполучених Штатів, яка становить 52 роки.

Отже, ось моє запитання.

  1. Чому існує таке обмеження? randomForest відмовляються запускатись навіть для простого випадку.

    > 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.
    

    Якщо це просто через обмеження пам’яті, то як scikit може засвоїти випадковий ForeestRegressor з більш ніж 32 рівнями?

  2. Який найкращий спосіб вирішити цю проблему? Припустимо, у мене X1, X2, ..., X50 незалежні змінні, а Y - залежна змінна. І припустимо, що X1, X2 і X3 має понад 32 рівні. Що я повинен зробити?

    Я думаю про те, що це алгоритм кластеризації для кожного з X1, X2 і X3, де відстань визначається як різниця в Y. Я запускаю три кластеризації, оскільки є три проблемні змінні. І в кожному кластері я б хотів знайти схожі рівні. І я злитлю їх.

    Як це звучить?


Пошук в Інтернеті з назвою пакета та повідомленням про помилку дає деякі відповіді.
Roland

5
@Roland Насправді це мене привело сюди…
isomorphismes

1
Ви можете спробувати науку про дані, оскільки декілька статистичних розумів мають досвід програмування даних у багатьох вимірах.
aeroNotAuto

2
ОНОВЛЕННЯ: Починаючи з версії 4.6-9, randomForestможна обробляти категоричні прогнози до 53 рівнів. Новини
Бен

Як випадковий ліс R визначає кількість рівнів? Я думаю, що рівень означає категорії.
ajp

Відповіді:


25

Це насправді досить розумно Обмежити тому розкол на фактор з рівнів насправді є вибір одного з 2 N - 2 можливих комбінацій. Тож навіть при N як 25 простір комбінацій настільки величезний, що таке висновок має незначний сенс.N2N-2N

N

Інший варіант - змінити представництво - можливо, ваш результат не залежить безпосередньо від держави, але, наприклад, площі, населення, кількості сосни на душу населення чи іншого атрибута, який ви можете замість цього підключити до своєї інформаційної системи.

Можливо, також, що кожна держава є настільки ізольованою і некоррельованою сутністю, що їй потрібна окрема модель для себе.

Кластеризація на основі рішення - це, мабуть, погана ідея, оскільки таким чином ви переправляєте інформацію з рішення в атрибути, що часто закінчується надмірним розміщенням.


4
Його можна легко переміщати, хоч і трохи втомливо. Наприклад, якщо у вас між 33 і 1024 рівнями, створіть два коефіцієнти на кожному з <= 32 рівнів.
KalEl

15

Основна причина полягає в тому, як реалізується randomForest. Реалізація з R значною мірою випливає з оригінальних специфікацій Breiman. Тут важливо зазначити, що для змінних факторів / категорій критерії розділення є двійковими з деякими значеннями міток зліва та рештою значень міток праворуч.

01[0;2М-1]

Чому реалізація від Weka та Python працює?

Реалізація weka за замовчуванням не використовує дерева CART. Він використовує дерева C45, у яких немає цієї обчислювальної проблеми, оскільки для категоричних входів він розбивається на декілька вузлів, по одному на кожне значення рівня.

Реалізація випадкового лісу python не може використовувати категоричні / факторні змінні. Ви повинні кодувати ці змінні в манекенні чи числові змінні.

М


2
Дуже дякую! Чи випливає з вашої відповіді, що реалізація R для лікування категоричних значень перевершує програму Python (я пам’ятаю, що Макс Кун згадував, що групування категоріальних змінних для РФ дає дещо кращі результати, ніж їх деміфікування), або щонайменше працює Random Forest у R vs Python У мене дуже хороші шанси отримати різні результати (точність тощо)? З вашого досвіду під час моделювання має сенс спробувати як групувати вари (у R), так і думіфікувати їх, а потім порівнювати два підходи?
Сергій Бушманов

2
Кодування манекена працює, але воно може створювати лише одну категорію проти всіх. Після кодування змінні тестуються раз за разом. Отже, реалізувати двійнінг неможливо. Якщо ця функція може допомогти, я думаю, що практично немає великих відмінностей. Однак є й інші речі, які можуть вимагати уваги при роботі зі змінною важливістю: деякі реалізації є упередженими до категоричних з декількома рівнями. Докладніше див. У статті Кароліна Стробля: statistic.uni-dortmund.de/useR-2008/slides/Strobl+Zeileis.pdf . У R є деякі реалізації, які не мають цього зміщення.
rapaio

2

Ви можете спробувати представити цей один стовпець по-різному. Ви можете представити ті самі дані, що і рідкісні рамки даних.

Мінімальний життєздатний код;

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)
}

Зверніть увагу, як кожне значення в початковому стовпчику тепер стає окремим стовпчиком манекена.

Більш широкий приклад коду;

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 )

Незважаючи на те, що цей фрагмент коду показує, що ви дійсно більше не отримаєте помилку, ви помітите, що алгоритму randomForest зараз потрібно довгий час, перш ніж він закінчиться. Це пов’язано з обмеженням процесора, ви також можете зменшити це завдання через вибірку.

Для отримання додаткової інформації ознайомтесь із цим поштовим блогом:

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


Другий блок коду виглядає заплутаним. Хоча ви використовуєте df_hard у всьому тілі, в останніх рядках ви встановлюєте "перше" та "друге" на NULL, а також використовуєте "приклад" як дані для randomForest цього не має сенсу мені, оскільки між прикладом та df_hard немає зв'язку.
Özgür

Вінсент, ти не відчуваєш, що я зіткнуся з такою великою проблемою, якщо в мене будуть рівні порядку 100+, ти пропонуєш додати кожен стовпець як вхід до випадкових?
Хардік Гупта

Інша альтернатива - використання реалізації випадкових лісів у h2o; це має кращу підтримку великих наборів даних. Я не розумію біт "додати кожен стовпець як вхід до випадкових".
Вінсент Вармердам

0

Ви можете використовувати пакет extraTrees замість цього. Надзвичайно рандомізований алгоритм лісів не пробує жодної точки розриву / розколу, а лише обмежену випадкову підмножину розщеплень.


1
extraTrees має обмеження, в сенсі ваш вхід повинен бути числовою матрицею даних, правда?
Гардік Гупта

0

Інший варіант: залежно від кількості рівнів та кількості спостережень у ваших даних, ви можете об'єднати деякі рівні. Окрім того, щоб потрапити під межу, це може зменшити дисперсію, якщо у вас багато рівнів із кількома спостереженнями. Hadley «S forcats: fct_lump робить це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.