rbloggers - Sugerencias para acelerar los bosques aleatorios.
random forest rbloggers (4)
¿Hay alguna razón en particular por la que no esté usando Python (es decir, los módulos de procesamiento múltiple y aprendizaje) para implementar esto? Usando Joblib, he entrenado bosques aleatorios en conjuntos de datos de tamaño similar en una fracción del tiempo que toma en R. Incluso sin multiprocesamiento, los bosques aleatorios son significativamente más rápidos en Python. Este es un ejemplo rápido de entrenamiento de un clasificador de RF y validación cruzada en Python. También puede extraer fácilmente características importantes y visualizar los árboles.
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)
Estoy trabajando un poco con el paquete randomForest
y aunque funciona bien, puede llevar mucho tiempo. ¿Alguien tiene alguna sugerencia para acelerar las cosas? Estoy usando una caja de Windows 7 con un chip AMD de doble núcleo. Sé que R no es multiproceso / procesador, pero tenía curiosidad por saber si alguno de los paquetes paralelos ( rmpi
, snow
, snowfall
, etc.) funcionaba para cosas randomForest
de randomForest
. Gracias.
EDITAR:
Estoy usando rF para algunos trabajos de clasificación (0''s y 1''s). Los datos tienen aproximadamente 8-12 columnas variables y el conjunto de entrenamiento es una muestra de 10k líneas, por lo que es un tamaño decente pero no loco. Estoy corriendo 500 árboles y un mínimo de 2, 3 o 4.
EDIT 2: Aquí hay algunos resultados:
> 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
>
¿Por qué no usa una implementación ya optimizada y en paralelo de Random Forest? Echa un vistazo a SPRINT utilizando MPI. http://www.r-sprint.org/
El manual del paquete foreach
tiene una sección sobre Bosques aleatorios paralelos ( Uso del paquete foreach , Sección 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 queremos crear un modelo de bosque aleatorio con 1000 árboles, y nuestra computadora tiene cuatro núcleos, podemos dividir el problema en cuatro partes ejecutando la función randomForest
cuatro veces, con el argumento ntree
establecido en 250. Por supuesto, tenemos que combinar los objetos randomForest
resultantes, pero el paquete randomForest
viene con una función llamada combine
.
Hay dos opciones "fuera de la caja" que abordan este problema. Primero, el paquete caret contiene un método ''parRF'' que lo maneja con elegancia. Normalmente uso esto con 16 núcleos con gran efecto. El paquete randomShrubbery también aprovecha los múltiples núcleos para RF en Revolution R.