更改随机森林分类器的阈值
Change threshold value for Random Forest classifier
我需要开发一个没有(或接近没有)假阴性值的模型。为此,我绘制了召回精度曲线并确定阈值应设置为 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)
有什么想法吗?
how to define threshold value upon model training?
在模型训练过程中只是没有阈值;随机森林是一个 概率 class 生成器,它只输出 class 概率。 "Hard" classes(即 0/1)确实需要一个阈值,在模型训练的任何阶段都不会产生或使用 - 仅在预测期间,甚至仅在我们确实需要的情况下需要硬 classification(并非总是如此)。请参阅 了解更多详情。
实际上,RF 的 scikit-learn 实现实际上根本不使用阈值,即使是硬 class 预测也是如此;仔细阅读 predict
方法的 docs:
the predicted class is the one with highest mean probability estimate across the trees
简而言之,这意味着实际的 RF 输出是 [p0, p1]
(假设二进制 class化),predict
方法只是 returns class 具有最高值,即如果 p0 > p1
则为 0,否则为 1。
假设你真正想要做的是 return 1 如果 p1
大于小于 0.5 的某个阈值,你必须放弃 predict
,使用 predict_proba
相反,然后操纵这些 returned 概率来得到你想要的。这是一个带有虚拟数据的示例:
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]
# 0
因为
clf.predict_proba(X)[0]
# array([0.85266881, 0.14733119])
即p0 > p1
.
要得到你想要的东西(即这里 returning class 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))]
之后,很容易看出现在对于第一个预测样本我们有:
preds[0]
# 1
因为,如上所示,对于此示例,我们有 p1 = 0.14733119 > threshold
。
我需要开发一个没有(或接近没有)假阴性值的模型。为此,我绘制了召回精度曲线并确定阈值应设置为 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)
有什么想法吗?
how to define threshold value upon model training?
在模型训练过程中只是没有阈值;随机森林是一个 概率 class 生成器,它只输出 class 概率。 "Hard" classes(即 0/1)确实需要一个阈值,在模型训练的任何阶段都不会产生或使用 - 仅在预测期间,甚至仅在我们确实需要的情况下需要硬 classification(并非总是如此)。请参阅
实际上,RF 的 scikit-learn 实现实际上根本不使用阈值,即使是硬 class 预测也是如此;仔细阅读 predict
方法的 docs:
the predicted class is the one with highest mean probability estimate across the trees
简而言之,这意味着实际的 RF 输出是 [p0, p1]
(假设二进制 class化),predict
方法只是 returns class 具有最高值,即如果 p0 > p1
则为 0,否则为 1。
假设你真正想要做的是 return 1 如果 p1
大于小于 0.5 的某个阈值,你必须放弃 predict
,使用 predict_proba
相反,然后操纵这些 returned 概率来得到你想要的。这是一个带有虚拟数据的示例:
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]
# 0
因为
clf.predict_proba(X)[0]
# array([0.85266881, 0.14733119])
即p0 > p1
.
要得到你想要的东西(即这里 returning class 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))]
之后,很容易看出现在对于第一个预测样本我们有:
preds[0]
# 1
因为,如上所示,对于此示例,我们有 p1 = 0.14733119 > threshold
。