Scikit-Learn:逻辑回归 OvR 访问二进制 estimators/classifier
Scikit-Learn: Logistic Regression OvR access binary estimators/classifier
我们可能知道,在多类分类问题上使用 solver='liblinear'
时,逻辑回归将使用一对一的策略。这是否意味着应该有 n_classes
个二进制数 classifiers/estimators?如果是这样,我怎样才能访问它们?
我已阅读 documentation,但找不到任何方法。
似乎没有简单的方法来访问这些子模型。但是,您可以使用 model.coef_
和 model.intercept_
.
重新计算这些子模型
如下:
from sklearn.linear_model import LogisticRegression
from sklearn import svm, datasets
import numpy as np
X_train, y_train = datasets.load_iris(return_X_y=True)
model = LogisticRegression(
penalty="l1",
multi_class="ovr",
class_weight="balanced",
solver="liblinear",
)
model.fit(X_train, y_train)
n_labels = len(np.unique(y_train))
for i in range(n_labels):
sub_model = LogisticRegression(penalty=model.penalty, C=model.C)
sub_model.coef_ = model.coef_[i].reshape(1, -1)
sub_model.intercept_ = model.intercept_[i].reshape(-1, 1)
sub_model.classes_ = np.array([0, 1])
y_train_ovr = np.where(y_train == i, 1, 0)
score = sub_model.score(X_train, y_train_ovr)
print(f"OVR for label={i}, score={score:.4f}")
输出:
OVR for label=0, score=1.0000
OVR for label=1, score=0.7333
OVR for label=2, score=0.9667
此代码基本上是根据原始模型系数、截距、C 和惩罚为每个标签创建一个新的 LogisticRegression()
。最后 y_train 标签被编码以表示这个 OVR
任务。
LogisticRegression 模型的预测由拟合期间估计的 coef_
和 intercept_
属性决定。
看这个例子:
X, y = load_iris(return_X_y=True)
# ovr model
ovr = LogisticRegression(multi_class='ovr', penalty='none').fit(X, y)
# manually estimate binary model for each label
y_0 = np.array([label == 0 for label in y])
y_1 = np.array([label == 1 for label in y])
y_2 = np.array([label == 2 for label in y])
m0 = LogisticRegression(penalty='none').fit(X, y_0)
m1 = LogisticRegression(penalty='none').fit(X, y_1)
m2 = LogisticRegression(penalty='none').fit(X, y_2)
ovr.coef_
# array([[ 2.02162242, 6.99849918, -11.14813559, -5.15488554],
# [ -0.24535745, -2.79656276, 1.31365383, -2.77836927],
# [ -2.46523384, -6.6809256 , 9.42922775, 18.28660819]])
m0.coef_
# array([[ 2.02162242, 6.99849918, -11.14813559, -5.15488554]])
m1.coef_
# array([[-0.24535745, -2.79656276, 1.31365383, -2.77836927]])
m2.coef_
# array([[-2.46523384, -6.6809256 , 9.42922775, 18.28660819]])
OVR模型系数矩阵的行是三个二元问题的系数向量。
这是因为在 OVR 模型的拟合过程中,三个二元模型中的每一个都被估计了。然后,OVR 模型会记住 coef_
个向量(以及 intercept_
个向量)。
所以回答这个问题:是的,在拟合 OVR 模型后有 n_classes
个不同的二元估计器。每个都由它的截距和系数表示(但不是由单独的 scikit-learn 估计器对象表示)。
我们可能知道,在多类分类问题上使用 solver='liblinear'
时,逻辑回归将使用一对一的策略。这是否意味着应该有 n_classes
个二进制数 classifiers/estimators?如果是这样,我怎样才能访问它们?
我已阅读 documentation,但找不到任何方法。
似乎没有简单的方法来访问这些子模型。但是,您可以使用 model.coef_
和 model.intercept_
.
如下:
from sklearn.linear_model import LogisticRegression
from sklearn import svm, datasets
import numpy as np
X_train, y_train = datasets.load_iris(return_X_y=True)
model = LogisticRegression(
penalty="l1",
multi_class="ovr",
class_weight="balanced",
solver="liblinear",
)
model.fit(X_train, y_train)
n_labels = len(np.unique(y_train))
for i in range(n_labels):
sub_model = LogisticRegression(penalty=model.penalty, C=model.C)
sub_model.coef_ = model.coef_[i].reshape(1, -1)
sub_model.intercept_ = model.intercept_[i].reshape(-1, 1)
sub_model.classes_ = np.array([0, 1])
y_train_ovr = np.where(y_train == i, 1, 0)
score = sub_model.score(X_train, y_train_ovr)
print(f"OVR for label={i}, score={score:.4f}")
输出:
OVR for label=0, score=1.0000
OVR for label=1, score=0.7333
OVR for label=2, score=0.9667
此代码基本上是根据原始模型系数、截距、C 和惩罚为每个标签创建一个新的 LogisticRegression()
。最后 y_train 标签被编码以表示这个 OVR
任务。
LogisticRegression 模型的预测由拟合期间估计的 coef_
和 intercept_
属性决定。
看这个例子:
X, y = load_iris(return_X_y=True)
# ovr model
ovr = LogisticRegression(multi_class='ovr', penalty='none').fit(X, y)
# manually estimate binary model for each label
y_0 = np.array([label == 0 for label in y])
y_1 = np.array([label == 1 for label in y])
y_2 = np.array([label == 2 for label in y])
m0 = LogisticRegression(penalty='none').fit(X, y_0)
m1 = LogisticRegression(penalty='none').fit(X, y_1)
m2 = LogisticRegression(penalty='none').fit(X, y_2)
ovr.coef_
# array([[ 2.02162242, 6.99849918, -11.14813559, -5.15488554],
# [ -0.24535745, -2.79656276, 1.31365383, -2.77836927],
# [ -2.46523384, -6.6809256 , 9.42922775, 18.28660819]])
m0.coef_
# array([[ 2.02162242, 6.99849918, -11.14813559, -5.15488554]])
m1.coef_
# array([[-0.24535745, -2.79656276, 1.31365383, -2.77836927]])
m2.coef_
# array([[-2.46523384, -6.6809256 , 9.42922775, 18.28660819]])
OVR模型系数矩阵的行是三个二元问题的系数向量。
这是因为在 OVR 模型的拟合过程中,三个二元模型中的每一个都被估计了。然后,OVR 模型会记住 coef_
个向量(以及 intercept_
个向量)。
所以回答这个问题:是的,在拟合 OVR 模型后有 n_classes
个不同的二元估计器。每个都由它的截距和系数表示(但不是由单独的 scikit-learn 估计器对象表示)。