Sklearn:使用 CalibratedClassifierCV 校准多标签分类
Sklearn: Calibrate a multi-label classification with CalibratedClassifierCV
我已经构建了许多 sklearn classifier 模型来执行多标签 classification,我想校准它们的 predict_proba
输出以便我可以获得置信度分数.我还想使用 sklearn.metrics.recall_score
等指标来评估它们。
我有 4 个标签要预测,真实标签是多热编码的(例如 [0, 1, 1, 1]
)。结果CalibratedClassifierCV
没有直接接受我的数据:
clf = tree.DecisionTreeClassifier(max_depth=15)
clf = clf.fit(train_X, train_Y)
calibrated_clf = CalibratedClassifierCV(clf, cv="prefit", method="sigmoid")
calibrated_clf.fit(dev_X, dev_Y)
这会 return 一个错误:
ValueError: classes [[0 1]
[0 1]
[0 1]
[0 1]] mismatch with the labels [0 1 2 3] found in the data
因此,我尝试将其包装在 OneVsRestClassifier
:
clf = OneVsRestClassifier(tree.DecisionTreeClassifier(max_depth=15), n_jobs=4)
clf = clf.fit(train_X, train_Y)
calibrated_clf = CalibratedClassifierCV(clf, cv="prefit", method="sigmoid")
calibrated_clf.fit(dev_X, dev_Y)
请注意,MultiOutputClassifier
和 ClassifierChain
不起作用,尽管它们可能更适合我的问题。
它有效,但是校准后的 classifier 的 predict
输出是 multi-class 而不是 multi-label 因为its implementation。有四个classes([0 1 2 3]
)但是如果不用打label的话,还是预测一个0
.
通过校准曲线进一步检查后,发现包裹在校准后的 classifier 中的基本估计器根本没有校准。也就是说,(calibrated_clf.calibrated_classifiers_)[0].base_estimator
return与校准前相同clf
。
我想观察我的(校准的)模型进行确定性(predict
)和概率性(predict_proba
)预测的性能。我应该如何在其他容器中设计我的 model/wrap 事物以获得每个标签的校准概率和可理解的标签预测?
在您的示例中,您使用的 DecisionTreeClassifier
默认情况下 support targets 维度 (n, m),其中 m > 1。
但是如果你想得到每个 class 的 marginal probability 的结果,那么使用 OneVsRestClassifier.
请注意 CalibratedClassifierCV
需要 target to be 1d so the "trick" is to extend it to support Multilabel Classification with MultiOutputClassifier。
完整示例
from sklearn.datasets import make_multilabel_classification
from sklearn.tree import DecisionTreeClassifier
from sklearn.multioutput import MultiOutputClassifier
from sklearn.model_selection import train_test_split, StratifiedKFold
import numpy as np
# Generate a sample multilabel target
X, y = make_multilabel_classification(n_classes=4, random_state=0)
y
>>>
array([[1, 0, 1, 0],
[0, 0, 0, 0],
[1, 0, 1, 0],
...
[0, 0, 0, 0],
[0, 1, 1, 1],
[1, 1, 0, 1]])
# Split in train/test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.9, random_state=42
)
# Splits Stratify target variable
cv = StratifiedKFold(n_splits=2)
# Decision tree support by default multiclass target or use OneVsRest if marginal probabilities
clf = OneVsRestClassifier(DecisionTreeClassifier(max_depth=10))
# Calibrate estimator probabilities
calibrated_clf = CalibratedClassifierCV(base_estimator=clf, cv=cv)
# calibrated_clf target is one dimensional, extend classifier to multi-target classification.
multioutput_clf = MultiOutputClassifier(calibrated_clf).fit(X_train, y_train)
# Check predict
multioutput_clf.predict(X_test[-5:])
>>>
array([[0, 0, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1]])
# Check predict_proba
multioutput_clf.predict_proba(X_test[-5:])
>>>
[array([[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685]]),
array([[0.59166537, 0.40833463],
[0.59166537, 0.40833463],
[0.40833361, 0.59166639],
[0.59166537, 0.40833463],
[0.59166537, 0.40833463]]),
array([[0.61666922, 0.38333078],
[0.61666427, 0.38333573],
[0.80000098, 0.19999902],
[0.61666427, 0.38333573],
[0.61666427, 0.38333573]]),
array([[0.26874774, 0.73125226],
[0.26874774, 0.73125226],
[0.45208444, 0.54791556],
[0.26874774, 0.73125226],
[0.26874774, 0.73125226]])]
注意 predict_proba
的结果是一个包含 4 个数组的列表,每个数组是属于 class i 的概率。例如,第一个数组的第一个样本内是第一个样本属于 class 1 的概率,依此类推。
关于校准曲线,scikit-learn 提供了示例来绘制 two dimension and three dimension 目标的概率路径。
我已经构建了许多 sklearn classifier 模型来执行多标签 classification,我想校准它们的 predict_proba
输出以便我可以获得置信度分数.我还想使用 sklearn.metrics.recall_score
等指标来评估它们。
我有 4 个标签要预测,真实标签是多热编码的(例如 [0, 1, 1, 1]
)。结果CalibratedClassifierCV
没有直接接受我的数据:
clf = tree.DecisionTreeClassifier(max_depth=15)
clf = clf.fit(train_X, train_Y)
calibrated_clf = CalibratedClassifierCV(clf, cv="prefit", method="sigmoid")
calibrated_clf.fit(dev_X, dev_Y)
这会 return 一个错误:
ValueError: classes [[0 1]
[0 1]
[0 1]
[0 1]] mismatch with the labels [0 1 2 3] found in the data
因此,我尝试将其包装在 OneVsRestClassifier
:
clf = OneVsRestClassifier(tree.DecisionTreeClassifier(max_depth=15), n_jobs=4)
clf = clf.fit(train_X, train_Y)
calibrated_clf = CalibratedClassifierCV(clf, cv="prefit", method="sigmoid")
calibrated_clf.fit(dev_X, dev_Y)
请注意,MultiOutputClassifier
和 ClassifierChain
不起作用,尽管它们可能更适合我的问题。
它有效,但是校准后的 classifier 的 predict
输出是 multi-class 而不是 multi-label 因为its implementation。有四个classes([0 1 2 3]
)但是如果不用打label的话,还是预测一个0
.
通过校准曲线进一步检查后,发现包裹在校准后的 classifier 中的基本估计器根本没有校准。也就是说,(calibrated_clf.calibrated_classifiers_)[0].base_estimator
return与校准前相同clf
。
我想观察我的(校准的)模型进行确定性(predict
)和概率性(predict_proba
)预测的性能。我应该如何在其他容器中设计我的 model/wrap 事物以获得每个标签的校准概率和可理解的标签预测?
在您的示例中,您使用的 DecisionTreeClassifier
默认情况下 support targets 维度 (n, m),其中 m > 1。
但是如果你想得到每个 class 的 marginal probability 的结果,那么使用 OneVsRestClassifier.
请注意 CalibratedClassifierCV
需要 target to be 1d so the "trick" is to extend it to support Multilabel Classification with MultiOutputClassifier。
完整示例
from sklearn.datasets import make_multilabel_classification
from sklearn.tree import DecisionTreeClassifier
from sklearn.multioutput import MultiOutputClassifier
from sklearn.model_selection import train_test_split, StratifiedKFold
import numpy as np
# Generate a sample multilabel target
X, y = make_multilabel_classification(n_classes=4, random_state=0)
y
>>>
array([[1, 0, 1, 0],
[0, 0, 0, 0],
[1, 0, 1, 0],
...
[0, 0, 0, 0],
[0, 1, 1, 1],
[1, 1, 0, 1]])
# Split in train/test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.9, random_state=42
)
# Splits Stratify target variable
cv = StratifiedKFold(n_splits=2)
# Decision tree support by default multiclass target or use OneVsRest if marginal probabilities
clf = OneVsRestClassifier(DecisionTreeClassifier(max_depth=10))
# Calibrate estimator probabilities
calibrated_clf = CalibratedClassifierCV(base_estimator=clf, cv=cv)
# calibrated_clf target is one dimensional, extend classifier to multi-target classification.
multioutput_clf = MultiOutputClassifier(calibrated_clf).fit(X_train, y_train)
# Check predict
multioutput_clf.predict(X_test[-5:])
>>>
array([[0, 0, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1]])
# Check predict_proba
multioutput_clf.predict_proba(X_test[-5:])
>>>
[array([[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685],
[0.78333315, 0.21666685]]),
array([[0.59166537, 0.40833463],
[0.59166537, 0.40833463],
[0.40833361, 0.59166639],
[0.59166537, 0.40833463],
[0.59166537, 0.40833463]]),
array([[0.61666922, 0.38333078],
[0.61666427, 0.38333573],
[0.80000098, 0.19999902],
[0.61666427, 0.38333573],
[0.61666427, 0.38333573]]),
array([[0.26874774, 0.73125226],
[0.26874774, 0.73125226],
[0.45208444, 0.54791556],
[0.26874774, 0.73125226],
[0.26874774, 0.73125226]])]
注意 predict_proba
的结果是一个包含 4 个数组的列表,每个数组是属于 class i 的概率。例如,第一个数组的第一个样本内是第一个样本属于 class 1 的概率,依此类推。
关于校准曲线,scikit-learn 提供了示例来绘制 two dimension and three dimension 目标的概率路径。