scikit-learn RandomForestClassifier 概率预测与多数投票

Posted

技术标签:

【中文标题】scikit-learn RandomForestClassifier 概率预测与多数投票【英文标题】:scikit-learn RandomForestClassifier probabilistic prediction vs majority vote 【发布时间】:2015-01-10 00:45:05 【问题描述】:

在section 1.9.2.1 的 scikit-learn 文档中(摘录在下面),为什么随机森林的实现与 Breiman 的原始论文不同?据我所知,在聚合分类器集合时,Breiman 选择了分类的多数票(模式)和回归的平均值(由原始 R 代码的维护者 Liaw 和 Wiener 撰写的论文,引用如下)。

    为什么 scikit-learn 使用概率预测而不是多数投票? 使用概率预测有什么优势吗?

有问题的部分:

与原始出版物 [B2001] 相比,scikit-learn 实现通过平均它们的概率来组合分类器 预测,而不是让每个分类器投票给单个 类。

资料来源:Liaw, A. 和 Wiener, M. (2002)。 randomForest的分类和回归。 R 新闻,2(3),18-22。

【问题讨论】:

【参考方案1】:

这个问题现在是answered on Cross Validated。包含在此处以供参考:

最好通过查看代码来回答此类问题,如果 你精通 Python。

RandomForestClassifier.predict,至少在当前版本中 0.16.1,预测具有最高概率估计的类,由predict_proba 给出。 (this line)

predict_proba 的文档说:

输入样本的预测类别概率计算为森林中树木的平均预测类别概率。这 一棵树的类概率是 同一类在一片叶子中。

与原始方法的区别可能只是这样 predict 给出与predict_proba 一致的预测。这 结果有时被称为“软投票”,而不是“硬” 原始 Breiman 论文中使用的多数票。我不能快速 搜索找到两者性能的适当比较 方法,但在这种情况下它们似乎都相当合理。

predict 文档充其量是误导性的;我有 提交a pull request到 修复它。

如果您想改为进行多数投票预测,这里有一个函数 去做吧。将其称为 predict_majvote(clf, X) 而不是 clf.predict(X)。 (基于predict_proba;仅经过轻微测试,但 我认为它应该有效。)

from scipy.stats import mode
from sklearn.ensemble.forest import _partition_estimators, _parallel_helper
from sklearn.tree._tree import DTYPE
from sklearn.externals.joblib import Parallel, delayed
from sklearn.utils import check_array
from sklearn.utils.validation import check_is_fitted

def predict_majvote(forest, X):
    """Predict class for X.

    Uses majority voting, rather than the soft voting scheme
    used by RandomForestClassifier.predict.

    Parameters
    ----------
    X : array-like or sparse matrix of shape = [n_samples, n_features]
        The input samples. Internally, it will be converted to
        ``dtype=np.float32`` and if a sparse matrix is provided
        to a sparse ``csr_matrix``.
    Returns
    -------
    y : array of shape = [n_samples] or [n_samples, n_outputs]
        The predicted classes.
    """
    check_is_fitted(forest, 'n_outputs_')

    # Check data
    X = check_array(X, dtype=DTYPE, accept_sparse="csr")

    # Assign chunk of trees to jobs
    n_jobs, n_trees, starts = _partition_estimators(forest.n_estimators,
                                                    forest.n_jobs)

    # Parallel loop
    all_preds = Parallel(n_jobs=n_jobs, verbose=forest.verbose,
                         backend="threading")(
        delayed(_parallel_helper)(e, 'predict', X, check_input=False)
        for e in forest.estimators_)

    # Reduce
    modes, counts = mode(all_preds, axis=0)

    if forest.n_outputs_ == 1:
        return forest.classes_.take(modes[0], axis=0)
    else:
        n_samples = all_preds[0].shape[0]
        preds = np.zeros((n_samples, forest.n_outputs_),
                         dtype=forest.classes_.dtype)
        for k in range(forest.n_outputs_):
            preds[:, k] = forest.classes_[k].take(modes[:, k], axis=0)
        return preds

在我尝试的愚蠢合成案例中,预测与 predict 方法每次。

【讨论】:

【参考方案2】:

Breiman 在 Bagging predictor (http://statistics.berkeley.edu/sites/default/files/tech-reports/421.pdf) 中对此进行了研究。

这给出了几乎相同的结果,但使用软投票可以得到更平滑的概率。请注意,如果您使用的是完全开发的树,则不会有任何区别。

【讨论】:

以上是关于scikit-learn RandomForestClassifier 概率预测与多数投票的主要内容,如果未能解决你的问题,请参考以下文章

如何从 python 输出 RandomForest 分类器?

scikit-learn随机森林调参小结

转载:scikit-learn随机森林调参小结

使用 scikit-learn 并行生成随机森林

如何在 scikit-learn 的随机森林的 graphviz-graph 中找到一个类?

在 Python Scikit-Learn 中训练测试拆分得分高但 CV 得分低