添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

改变随机森林分类器的阈值

4 人关注

我需要开发一个没有(或接近于没有)假阴性值的模型。为此,我绘制了召回率-精确度曲线,并确定阈值应设置为0.11

我的问题是,如何在模型训练时定义阈值?以后在评估时再定义就没有意义了,因为它不会反映在新的数据上。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)
rfc_model = RandomForestClassifier(random_state=101)
rfc_model.fit(X_train, y_train)
rfc_preds = rfc_model.predict(X_test)
recall_precision_vals = []
for val in np.linspace(0, 1, 101):
    predicted_proba = rfc_model.predict_proba(X_test)
    predicted = (predicted_proba[:, 1] >= val).astype('int')
    recall_sc = recall_score(y_test, predicted)
    precis_sc = precision_score(y_test, predicted)
    recall_precision_vals.append({
        'Threshold': val,
        'Recall val': recall_sc,
        'Precis val': precis_sc
recall_prec_df = pd.DataFrame(recall_precision_vals)

有什么想法吗?

python
machine-learning
scikit-learn
random-forest
DaxHR
DaxHR
发布于 2019-08-01
1 个回答
desertnaut
desertnaut
发布于 2019-08-02
已采纳
0 人赞同

如何在模型训练时定义阈值?

There is simply no 模型训练过程中的阈值;随机森林是一种 概率性的 分类器,而且它只输出类别概率。确实需要阈值的 "硬 "类(即0/1)在模型训练的任何阶段既不产生也不使用--只在预测过程中使用,即使如此也只在我们确实需要硬分类的情况下(并不总是这样)。请看 预测类或类的概率? 了解更多细节。

实际上,scikit-learn对RF的实现根本没有采用阈值,即使是对硬类预测也是如此;仔细阅读 docs for the predict method:

预测的类别是在整个树中具有最高平均概率估计的类别。

简单地说,这意味着实际的RF输出是 [p0, p1] (假设是二进制分类),由此, predict 方法只是返回具有最高值的类别,即如果 p0 > p1 为0,否则为1。

假设你实际想做的是,如果 p1 大于某个小于0.5的阈值,则返回1,你必须放弃 predict ,用 predict_proba 代替,然后操作这些返回的概率以得到你想要的东西。下面是一个有虚拟数据的例子。

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=4,
                          n_informative=2, n_redundant=0,
                           n_classes=2, random_state=0, shuffle=False)
clf = RandomForestClassifier(n_estimators=100, max_depth=2,
                            random_state=0)
clf.fit(X, y)

在这里,简单地用predict来表示,比如说,X的第一个元素,将得到0。

clf.predict(X)[0] 
clf.predict_proba(X)[0]
# array([0.85266881, 0.14733119])

i.e. p0 > p1.

为了得到你想要的东西(即这里返回1类,因为p1 > threshold的阈值为0.11),这里是你必须做的。

prob_preds = clf.predict_proba(X)
threshold = 0.11 # define threshold here
preds = [1 if prob_preds[i][1]> threshold else 0 for i in range(len(prob_preds))]

之后,很容易看到,现在对于第一个预测的样本,我们有。