【问题标题】:Getting the accuracy for multi-label prediction in scikit-learn在 scikit-learn 中获得多标签预测的准确性
【发布时间】:2015-11-21 06:10:51
【问题描述】:

multilabel classification 设置中,sklearn.metrics.accuracy_score 仅计算子集精度 (3):即为样本预测的标签集必须与 y_true 中的相应标签集完全匹配。

这种计算准确度的方法有时被命名为,也许不太含糊,精确匹配率 (1):

有没有什么方法可以在 scikit-learn 中获得另一种计算准确率的典型方法,即

(如 (1) 和 (2) 中所定义,不太含糊地称为 汉明分数 (4)(因为它与汉明损失密切相关),或 基于标签的 准确性) ?


(1) Sorower, Mohammad S. "A literature survey on algorithms for multi-label learning." 俄勒冈州立大学,科瓦利斯 (2010)。

(2) Tsoumakas、Grigorios 和 Ioannis Katakis。 "Multi-label classification: An overview." 希腊塞萨洛尼基亚里士多德大学信息学系 (2006)。

(3) Ghamrawi、Nadia 和 Andrew McCallum。 “Collective multi-label classification.”第14届ACM信息与知识管理国际会议论文集。 ACM,2005 年。

(4) Godbole、Shantanu 和 Sunita Sarawagi。 "Discriminative methods for multi-labeled classification." 知识发现和数据挖掘的进展。施普林格柏林海德堡,2004. 22-30.

【问题讨论】:

    标签: python scikit-learn classification


    【解决方案1】:

    你可以自己写一个版本,这里是一个不考虑权重和归一化的例子。

    import numpy as np
    
    y_true = np.array([[0,1,0],
                       [0,1,1],
                       [1,0,1],
                       [0,0,1]])
    
    y_pred = np.array([[0,1,1],
                       [0,1,1],
                       [0,1,0],
                       [0,0,0]])
    
    def hamming_score(y_true, y_pred, normalize=True, sample_weight=None):
        '''
        Compute the Hamming score (a.k.a. label-based accuracy) for the multi-label case
        http://stackoverflow.com/q/32239577/395857
        '''
        acc_list = []
        for i in range(y_true.shape[0]):
            set_true = set( np.where(y_true[i])[0] )
            set_pred = set( np.where(y_pred[i])[0] )
            #print('\nset_true: {0}'.format(set_true))
            #print('set_pred: {0}'.format(set_pred))
            tmp_a = None
            if len(set_true) == 0 and len(set_pred) == 0:
                tmp_a = 1
            else:
                tmp_a = len(set_true.intersection(set_pred))/\
                        float( len(set_true.union(set_pred)) )
            #print('tmp_a: {0}'.format(tmp_a))
            acc_list.append(tmp_a)
        return np.mean(acc_list)
    
    if __name__ == "__main__":
        print('Hamming score: {0}'.format(hamming_score(y_true, y_pred))) # 0.375 (= (0.5+1+0+0)/4)
    
        # For comparison sake:
        import sklearn.metrics
    
        # Subset accuracy
        # 0.25 (= 0+1+0+0 / 4) --> 1 if the prediction for one sample fully matches the gold. 0 otherwise.
        print('Subset accuracy: {0}'.format(sklearn.metrics.accuracy_score(y_true, y_pred, normalize=True, sample_weight=None)))
    
        # Hamming loss (smaller is better)
        # $$ \text{HammingLoss}(x_i, y_i) = \frac{1}{|D|} \sum_{i=1}^{|D|} \frac{xor(x_i, y_i)}{|L|}, $$
        # where
        #  - \\(|D|\\) is the number of samples  
        #  - \\(|L|\\) is the number of labels  
        #  - \\(y_i\\) is the ground truth  
        #  - \\(x_i\\)  is the prediction.  
        # 0.416666666667 (= (1+0+3+1) / (3*4) )
        print('Hamming loss: {0}'.format(sklearn.metrics.hamming_loss(y_true, y_pred))) 
    

    输出:

    Hamming score: 0.375
    Subset accuracy: 0.25
    Hamming loss: 0.416666666667
    

    【讨论】:

    【解决方案2】:

    一个简单的汇总函数:

    import numpy as np
    
    def hamming_score(y_true, y_pred):
        return (
            (y_true & y_pred).sum(axis=1) / (y_true | y_pred).sum(axis=1)
        ).mean()
    
    
    hamming_score(y_true, y_pred)
    # 0.375
    

    【讨论】:

      猜你喜欢
      • 2019-06-07
      • 2019-11-18
      • 2018-10-18
      • 2015-05-21
      • 2018-05-04
      • 2016-10-17
      • 2017-08-07
      • 2017-12-23
      相关资源
      最近更新 更多