如何覆盖 Sklearn 模块功能
How to override Sklearn module function
我正在使用 sklearn.metrics.cohen_kappa_score
来评估我的模块。函数权重可以是 None , 'linear' or 'quadratic'
我想覆盖函数以便能够发送自定义权重矩阵。怎么做到的?
def cohen_kappa_score(y1, y2, *, labels=None, weights=None,
sample_weight=None):
confusion = confusion_matrix(y1, y2, labels=labels,
sample_weight=sample_weight)
n_classes = confusion.shape[0]
sum0 = np.sum(confusion, axis=0)
sum1 = np.sum(confusion, axis=1)
expected = np.outer(sum0, sum1) / np.sum(sum0)
if type(w_mat) != np.ndarray: # <------------------------- line I want to add
if weights is None:
w_mat = np.ones([n_classes, n_classes], dtype=int)
w_mat.flat[:: n_classes + 1] = 0
elif weights == "linear" or weights == "quadratic":
w_mat = np.zeros([n_classes, n_classes], dtype=int)
w_mat += np.arange(n_classes)
if weights == "linear":
w_mat = np.abs(w_mat - w_mat.T)
else:
w_mat = (w_mat - w_mat.T) ** 2
else:
raise ValueError("Unknown kappa weighting type.")
k = np.sum(w_mat * confusion) / np.sum(w_mat * expected)
return 1 - k
最好的选择是使用 sklearn.metrics.make_scorer
封装您自己的评分函数,以便将其用于 GridSearchCV
和 cross_val_score
。
如下:
from sklearn.metrics import make_scorer
weighted_cohen_kappa_score = make_scorer(custom_cohen_kappa,
greater_is_better=True,
needs_proba=False,
needs_threshold=False
)
其中 custom_cohen_kappa
是您在问题中定义的自定义评分函数。
您可以按照@Antoine 在另一个答案中显示的那样使用 make_scorer
,或者您可以覆盖函数本身:
import numpy as np
import sklearn.metrics as sm
from sklearn.metrics import confusion_matrix
def custom_cohen_kappa_score(y1, y2, *, labels=None, weights=None, sample_weight=None):
print("This is the custom function")
confusion = confusion_matrix(y1, y2, labels=labels,
sample_weight=sample_weight)
n_classes = confusion.shape[0]
sum0 = np.sum(confusion, axis=0)
sum1 = np.sum(confusion, axis=1)
expected = np.outer(sum0, sum1) / np.sum(sum0)
if weights is None:
w_mat = np.ones([n_classes, n_classes], dtype=int)
w_mat.flat[:: n_classes + 1] = 0
elif weights == "linear" or weights == "quadratic":
w_mat = np.zeros([n_classes, n_classes], dtype=int)
w_mat += np.arange(n_classes)
if weights == "linear":
w_mat = np.abs(w_mat - w_mat.T)
else:
w_mat = (w_mat - w_mat.T) ** 2
else:
raise ValueError("Unknown kappa weighting type.")
k = np.sum(w_mat * confusion) / np.sum(w_mat * expected)
return 1 - k
# override it
sm.cohen_kappa_score = custom_cohen_kappa_score
# Test: Here every time `cohen_kappa_score` is called,
# the custom one will be invoked instead!
from sklearn.metrics import cohen_kappa_score
y_true = [2, 0, 2, 2, 0, 1]
y_pred = [0, 0, 2, 2, 0, 2]
print(cohen_kappa_score(y_true, y_pred))
输出
This is the custom function
0.4285714285714286
我正在使用 sklearn.metrics.cohen_kappa_score
来评估我的模块。函数权重可以是 None , 'linear' or 'quadratic'
我想覆盖函数以便能够发送自定义权重矩阵。怎么做到的?
def cohen_kappa_score(y1, y2, *, labels=None, weights=None,
sample_weight=None):
confusion = confusion_matrix(y1, y2, labels=labels,
sample_weight=sample_weight)
n_classes = confusion.shape[0]
sum0 = np.sum(confusion, axis=0)
sum1 = np.sum(confusion, axis=1)
expected = np.outer(sum0, sum1) / np.sum(sum0)
if type(w_mat) != np.ndarray: # <------------------------- line I want to add
if weights is None:
w_mat = np.ones([n_classes, n_classes], dtype=int)
w_mat.flat[:: n_classes + 1] = 0
elif weights == "linear" or weights == "quadratic":
w_mat = np.zeros([n_classes, n_classes], dtype=int)
w_mat += np.arange(n_classes)
if weights == "linear":
w_mat = np.abs(w_mat - w_mat.T)
else:
w_mat = (w_mat - w_mat.T) ** 2
else:
raise ValueError("Unknown kappa weighting type.")
k = np.sum(w_mat * confusion) / np.sum(w_mat * expected)
return 1 - k
最好的选择是使用 sklearn.metrics.make_scorer
封装您自己的评分函数,以便将其用于 GridSearchCV
和 cross_val_score
。
如下:
from sklearn.metrics import make_scorer
weighted_cohen_kappa_score = make_scorer(custom_cohen_kappa,
greater_is_better=True,
needs_proba=False,
needs_threshold=False
)
其中 custom_cohen_kappa
是您在问题中定义的自定义评分函数。
您可以按照@Antoine 在另一个答案中显示的那样使用 make_scorer
,或者您可以覆盖函数本身:
import numpy as np
import sklearn.metrics as sm
from sklearn.metrics import confusion_matrix
def custom_cohen_kappa_score(y1, y2, *, labels=None, weights=None, sample_weight=None):
print("This is the custom function")
confusion = confusion_matrix(y1, y2, labels=labels,
sample_weight=sample_weight)
n_classes = confusion.shape[0]
sum0 = np.sum(confusion, axis=0)
sum1 = np.sum(confusion, axis=1)
expected = np.outer(sum0, sum1) / np.sum(sum0)
if weights is None:
w_mat = np.ones([n_classes, n_classes], dtype=int)
w_mat.flat[:: n_classes + 1] = 0
elif weights == "linear" or weights == "quadratic":
w_mat = np.zeros([n_classes, n_classes], dtype=int)
w_mat += np.arange(n_classes)
if weights == "linear":
w_mat = np.abs(w_mat - w_mat.T)
else:
w_mat = (w_mat - w_mat.T) ** 2
else:
raise ValueError("Unknown kappa weighting type.")
k = np.sum(w_mat * confusion) / np.sum(w_mat * expected)
return 1 - k
# override it
sm.cohen_kappa_score = custom_cohen_kappa_score
# Test: Here every time `cohen_kappa_score` is called,
# the custom one will be invoked instead!
from sklearn.metrics import cohen_kappa_score
y_true = [2, 0, 2, 2, 0, 1]
y_pred = [0, 0, 2, 2, 0, 2]
print(cohen_kappa_score(y_true, y_pred))
输出
This is the custom function
0.4285714285714286