R 和 sklearn 随机森林回归中的特征重要性结果不同

Con*_*ino 5 python regression r random-forest scikit-learn

我正在研究回归问题,并且一直在使用R randomForest包以及 python sklearn 随机森林回归估计器。

R 包可以通过两种不同的方式计算特征重要性得分:

  1. 第一个度量是根据排列 OOB 数据计算的:对于每棵树,记录数据的袋外部分的预测误差(分类错误率,回归 MSE)。然后在排列每个预测变量后做同样的事情。然后将两者之间的差异在所有树上取平均值,并通过差异的标准偏差进行归一化。

  2. 第二个度量是对变量进行拆分后节点杂质的总减少量,对所有树求平均值。对于分类,节点杂质是通过基尼指数来衡量的。对于回归,它是通过残差平方和 (RSS) 来衡量的。

而 sklearn 仅以后一种方式执行此操作(有关详细信息,请参见此处)。

我对比较两种实现中的方法 #2 很感兴趣,所以我做了以下工作:

电阻

iteration_count <- 3
seeds <- seq(1,iteration_count,1)
tree_count <- 500

for(i in 1:iteration_count) {
  set.seed(seeds[[i]])
  rfmodels[[i]]<- randomForest(y ~ .,X,ntree=tree_count,importance=TRUE,na.action=na.omit)
}

# convert all iterations into matrix form
imp_score_matrix <- do.call(cbind, lapply(models_selected, function(x) { importance(x, scale=T, type=1)[,1] }))

# Calculate mean and s.d. for importance ranking of each feature based on a matrix of feature importance scores
imp_score_stats <- (cbind(rowMeans(imp_score_matrix),rowSds(imp_score_matrix)))

# Order the matrix so that the features are ranked by mean (most important features will be in the last rows)
ordered_imp_score_stats <- imp_score_stats[order(imp_score_stats[,1]),]
Run Code Online (Sandbox Code Playgroud)

学习

# get FIS through mean decrease in impurity (default method for sklearn)
num_iter = 3 # number of times to generate FIS; will average over these scores
trees = 500
seeds = [l for l in range(num_iter)]
FIS = []

# R implementation of RF settings - https://cran.r-project.org/web/packages/randomForest/randomForest.pdf
num_features = 1/3.0 # see mtry
leaf = 5 # see nodesize

FIS_map = {v:k for k,v in enumerate(X.columns.values)} # {feature: i}
for i in range(num_iter):
    print "Iteration", i
    clf = RandomForestRegressor(n_jobs = -1, n_estimators = trees, random_state = seeds[i],
                               max_features = num_features, min_samples_leaf = leaf)
    clf = clf.fit(X,y)
    FIS.append(clf.feature_importances_)

FIS_stats = pd.DataFrame(FIS).describe().T # will have columns mean, std, etc
FIS_stats = FIS_stats.sort("mean", ascending = False) # most important features on top
FIS_stats['OTU'] = FIS_map # add the OTU ID
FIS_stats = FIS_stats.set_index('OTU')
FIS_stats = FIS_stats[FIS_stats['mean'] > 0] # remove those OTU features with no mean importance 
Run Code Online (Sandbox Code Playgroud)

如您所见,我已尝试调整 sklearn 中的默认设置以匹配 R 中使用的设置。问题是,每个实现我得到不同的结果。现在,我知道随机森林有各种非确定性维度,所以我不希望这些特征的排名完全相同;但是,我发现重要功能几乎没有重叠。

此外,当我使用最好的X特征时,R 选择的那些在保留样本集上的表现比 sklearn 中的要好得多。

难道我做错了什么?什么可以解释由此产生的差异?

更新

根据关于在 sklearn 中使用 Gini 指数计算特征重要性的评论,随机森林回归的源代码显示MSE 用于计算杂质

所以,看起来 R 使用 RSS 而 sklearn 使用 MSE,关系是

在此处输入图片说明

这可以解释差异吗?