Suggestions pour accélérer les forêts aléatoires

Je travaille avec le paquet randomForest et bien que cela fonctionne bien, cela peut prendre du temps. Quelqu'un a des suggestions pour accélérer les choses? J'utilise une boîte Windows 7 avec une puce AMD Dual core. Je sais que R n'est pas multi-thread / processeur, mais était curieux de savoir si l'un des paquets parallèles (rmpi, snow, snowfall, etc.) travaillé pour randomForest trucs. Grâce.

Modifier:

J'utilise rF pour certains travaux de classification (0 et 1). Les données ont environ 8-12 colonnes variables et l'ensemble d'entraînement est un échantillon de lignes 10k, donc c'est une taille décente mais pas folle. Je cours 500 arbres et un mtry de 2, 3 ou 4.

Édition 2: Voici quelques sorties:

> head(t22)
  Id Fail     CCUse Age S-TFail         DR MonInc #OpenLines L-TFail RE M-TFail Dep
1  1    1 0.7661266  45       2 0.80298213   9120         13       0  6       0   2
2  2    0 0.9571510  40       0 0.12187620   2600          4       0  0       0   1
3  3    0 0.6581801  38       1 0.08511338   3042          2       1  0       0   0
4  4    0 0.2338098  30       0 0.03604968   3300          5       0  0       0   0
5  5    0 0.9072394  49       1 0.02492570  63588          7       0  1       0   0
6  6    0 0.2131787  74       0 0.37560697   3500          3       0  1       0   1
> ptm <- proc.time()
> 
> RF<- randomForest(t22[,-c(1,2,7,12)],t22$Fail
+                    ,sampsize=c(10000),do.trace=F,importance=TRUE,ntree=500,,forest=TRUE)
Warning message:
In randomForest.default(t22[, -c(1, 2, 7, 12)], t22$Fail, sampsize = c(10000),  :
  The response has five or fewer unique values.  Are you sure you want to do regression?
> proc.time() - ptm
   user  system elapsed 
 437.30    0.86  450.97 
> 
22
demandé sur rcs 2011-10-20 05:46:56

4 réponses

Le manuel du paquet foreach comporte une section sur les forêts aléatoires parallèles ( en utilisant le paquet foreach , Section 5.1):

> library("foreach")
> library("doSNOW")
> registerDoSNOW(makeCluster(4, type="SOCK"))

> x <- matrix(runif(500), 100)
> y <- gl(2, 50)

> rf <- foreach(ntree = rep(250, 4), .combine = combine, .packages = "randomForest") %dopar%
+    randomForest(x, y, ntree = ntree)
> rf
Call:
randomForest(x = x, y = y, ntree = ntree)
Type of random forest: classification
Number of trees: 1000

Si nous voulons vouloir créer un modèle de forêt aléatoire avec un 1000 arbres, et notre ordinateur a quatre cores, nous pouvons diviser le problème en quatre morceaux en exécutant la fonction randomForest quatre fois, avec l'argument ntree défini sur 250. Bien sûr, nous devons combiner les objets randomForest résultants, mais le paquet randomForest est livré avec une fonction appelée combine.

33
répondu rcs 2011-10-20 06:17:03

Il y a deux options "prêtes à l'emploi" qui résolvent ce problème. Tout d'abord, le paquet caret contient une méthode 'parRF' qui gère cela avec élégance. Je l'utilise couramment avec 16 cœurs à grand effet. Le paquet randomShrubbery profite également de plusieurs cœurs pour RF sur Revolution R.

8
répondu Brent 2012-07-02 22:23:45

Pourquoi n'utilisez-vous pas une implémentation déjà parallélisée et optimisée de Random Forest? Jetez un oeil à SPRINT en utilisant MPI. http://www.r-sprint.org/

5
répondu Manolete 2013-04-15 13:14:41

Y a-t-il une raison particulière pour laquelle vous n'utilisez pas Python (à savoir les modules scikit-learn et multiprocessing) pour implémenter cela? En utilisant joblib, j'ai formé des forêts aléatoires sur des ensembles de données de taille similaire en une fraction du temps nécessaire à R. même sans multitraitement, les forêts aléatoires sont nettement plus rapides en Python. Voici un exemple rapide de formation D'un classificateur RF et de validation croisée en Python. Vous pouvez également facilement extraire les importances de fonctionnalités et visualiser les arbres.

import numpy as np
from sklearn.metrics import *
from sklearn.cross_validation import StratifiedKFold
from sklearn.ensemble import RandomForestClassifier

#assuming that you have read in data with headers
#first column corresponds to response variable 
y = data[1:, 0].astype(np.float)
X = data[1:, 1:].astype(np.float)

cm = np.array([[0, 0], [0, 0]])
precision = np.array([])
accuracy = np.array([])
sensitivity = np.array([])
f1 = np.array([])
matthews = np.array([])

rf = RandomForestClassifier(n_estimators=100, max_features = 5, n_jobs = 2)

#divide dataset into 5 "folds", where classes are equally balanced in each fold
cv = StratifiedKFold(y, n_folds = 5)
for i, (train, test) in enumerate(cv):
        classes = rf.fit(X[train], y[train]).predict(X[test])
        precision = np.append(precision, (precision_score(y[test], classes)))
        accuracy = np.append(accuracy, (accuracy_score(y[test], classes)))
        sensitivity = np.append(sensitivity, (recall_score(y[test], classes)))
        f1 = np.append(f1, (f1_score(y[test], classes)))
        matthews = np.append(matthews, (matthews_corrcoef(y[test], classes)))
        cm = np.add(cm, (confusion_matrix(y[test], classes)))

print("Accuracy: %0.2f (+/- %0.2f)" % (accuracy.mean(), accuracy.std() * 2))
print("Precision: %0.2f (+/- %0.2f)" % (precision.mean(), precision.std() * 2))
print("Sensitivity: %0.2f (+/- %0.2f)" % (sensitivity.mean(), sensitivity.std() * 2))
print("F1: %0.2f (+/- %0.2f)" % (f1.mean(), f1.std() * 2))
print("Matthews: %0.2f (+/- %0.2f)" % (matthews.mean(), matthews.std() * 2))
print(cm)
5
répondu eagle34 2013-09-24 08:12:19