Lo siguiente Correo electrónico: en la validación cruzada tiene una respuesta bastante buena:
"El bosque aleatorio utiliza el método de "bagging" (selección de una muestra de observaciones en lugar de todas ellas) y el método de subespacio aleatorio (selección de una muestra de características en lugar de todas ellas, es decir, "attribute bagging") para hacer crecer un árbol. Si el número de observaciones es grande, pero el número de árboles es demasiado pequeño, algunas observaciones sólo se predecirán una vez o incluso no se predecirán. Si el número de predictores es grande, pero el número de árboles es demasiado pequeño, entonces algunas características pueden (teóricamente) perderse en todos los subespacios utilizados. En ambos casos, el poder de predicción del bosque aleatorio disminuye. Pero el último es un caso bastante extremo, ya que la selección del subespacio se realiza en cada nodo".
He realizado algunas pruebas empíricas para validar esto. Primero creé datos sintéticos utilizando lo siguiente:
# Create data
X, y = make_classification(n_samples=20000, n_features=50,
n_informative=10, n_redundant=0,
random_state=42, shuffle=True, n_classes=2, class_sep=1.0)
# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, shuffle=True, stratify=None)
Hay 50 funciones, de las cuales sólo 10 son informativas. Hay una clara separación de clases y 20000 observaciones.
A continuación, ajusto un bosque aleatorio que está limitado por el número de árboles y el número de características que puede utilizar (n_estimadores, max_características).
max_trees = 100
max_feat_used = 50
store = []
for num_trees in range(2, max_trees, 2):
print(num_trees)
for num_feat in range(1, max_feat_used, 2):
rnd_clf = RandomForestClassifier(criterion='entropy', n_estimators=num_trees, max_features=num_feat, n_jobs=-1)
rnd_clf.fit(X_train, y_train)
y_pred_rf = rnd_clf.predict(X_test)
store.append([num_trees, num_feat, accuracy_score(y_test, y_pred_rf)])
# Pivot and save results
results = pd.DataFrame(store, columns=['N', 'F', 'Score'])
pivot_results = results.pivot(index='N', columns='F', values='Score')
pivot_results = pivot_results.sort_index(ascending=False)
Por último, podemos observar la relación en un mapa de calor: