如果我将两个 RandomForestClassifiers 分别拟合 500 棵树并在测试集上平均它们的预测概率,它会比用 1000 棵树拟合 RandomForestClassifier 并使用它来获得测试集概率有更好的结果吗?
由于这些算法是基于随机的,我会说它们的性能应该大致相同?
我可以用一些数学来证明它,或者任何其他可能证明它的方式。
如果我将两个 RandomForestClassifiers 分别拟合 500 棵树并在测试集上平均它们的预测概率,它会比用 1000 棵树拟合 RandomForestClassifier 并使用它来获得测试集概率有更好的结果吗?
由于这些算法是基于随机的,我会说它们的性能应该大致相同?
我可以用一些数学来证明它,或者任何其他可能证明它的方式。
简短的回答:它们是等价的。
任何暗示其他结果的结果都是由于随机机会或由于修改了除树数之外的参数。随机森林只是决策树的投票集合。默认情况下,每棵树的投票权重相等,然后这些投票被平均。假设集合 X 和 Y 的大小相同。然后,如果你取 X 的平均值,Y 的平均值,然后将这两者取平均值,这与将 X 和 Y 组合并取平均值完全相同。这就像您有两个具有相同数量的树的随机森林一样。
但是请注意,如果他们有不同数量的树,那么如果您构建两个森林并将它们平均,则构成较小森林的单个树木的投票权重将高于较大森林中的树木。
使用玩具数据集,我使用 RF 1000 树获得了稍微好一点的结果
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from scipy.stats import ks_2samp
import matplotlib.pyplot as plt
plt.style.use("seaborn-whitegrid")
n_models = 2
threshold = .5
X, y = load_breast_cancer(return_X_y= True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42, test_size = .3)
rForest1000 = RandomForestClassifier(n_estimators= 1000, random_state= 42, oob_score= True).fit(X_train, y_train)
preds1000 = rForest1000.predict_proba(X_test)[:,1]
roc_score = roc_auc_score(y_true = y_test, y_score= preds1000)
print(f"Test set score for 1K trees is : {round(roc_score, 4)}")
ls = list()
for i in range(n_models):
model = RandomForestClassifier(n_estimators= 500, random_state= i).fit(X_train, y_train)
ls.append(model.predict_proba(X_test)[:,1])
preds = np.array(ls).mean(axis =0)
roc_score = roc_auc_score(y_true = y_test, y_score= preds)
print(f"Test set score for 500trees X 2 avg is : {round(roc_score, 4)}")
fig, ax = plt.subplots(1,2, figsize = (12,5))
ax[0].hist(preds1000[y_test == 0], color = "darkgreen", alpha = .5)
ax[0].hist(preds1000[y_test == 1], color = "darkred", alpha = .5)
ax[0].set_title(f"Predictions distribution with 1K Trees RF\n KS: {[round(ks_2samp(preds1000[y_test == 0], preds1000[y_test == 1])[0],3)]}")
ax[1].hist(preds[y_test == 0], color = "darkgreen", alpha = .5)
ax[1].hist(preds[y_test == 1], color = "darkred", alpha = .5)
ax[1].set_title(f"Predictions distribution with X2 500 Trees RF Trees RF\n KS: {[round(ks_2samp(preds[y_test == 0], preds[y_test == 1])[0],3)]}");