我正在研究回归问题,并且一直在使用R randomForest包以及python sklearn random forest regression估算器 .

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

第一个度量是根据置换OOB数据计算的:对于每个树,记录数据的袋外部分的预测误差(分类的错误率,回归的MSE) . 然后在置换每个预测变量之后完成相同的操作 . 然后将两者之间的差异在所有树上进行平均,并通过差异的标准偏差进行归一化 . 第二个指标是变量上的分裂中节点杂质的总减少量,在所有树上的平均值 . 对于分类,节点杂质通过基尼指数测量 . 对于回归,它通过残差平方和(RSS)来测量 .

而sklearn只是以后一种方式(see here for details) .

我一直对在两种实现中比较方法#2感兴趣,所以我做了以下事情:

R.

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]),]

sklearn

# 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

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

此外,当我使用最好的X特征时,R选择的那些特征比保持样本集中的sklearn中的特征要好得多 .

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

更新

根据关于使用sklearn中的Gini索引计算的要素重要性的注释,随机森林回归的源代码显示MSE is used to calculate impurity .

所以,看起来R使用RSS而sklearn使用MSE,relationship being

enter image description here

这可以说明差异吗?