【问题标题】:How to override Sklearn module function如何覆盖 Sklearn 模块功能
【发布时间】:2021-08-03 14:02:59
【问题描述】:

我正在使用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

【问题讨论】:

    标签: python function scikit-learn overriding cohen-kappa


    【解决方案1】:

    您可以按照@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
    

    【讨论】:

      【解决方案2】:

      最好的选择是使用sklearn.metrics.make_scorer 封装您自己的评分函数,以便将其用于GridSearchCVcross_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 是您在问题中定义的自定义评分函数。

      【讨论】:

      • 感谢您的回复,但是 custom_cohen_kappa 依赖于模块内的函数,所以我无法按原样通过......还是我遗漏了什么?
      • 对我来说,它只依赖于可以导入的 scikit-learn confusion_matrixnumpy
      猜你喜欢
      • 1970-01-01
      • 2011-09-02
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 2017-11-17
      相关资源
      最近更新 更多