离散label的优化trick

转自https://mp.weixin.qq.com/s/jH9grYg-xiuQxMTDq99olg

https://www.jianshu.com/p/37e689bab29b

https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/quadratic_weighted_kappa.py

1.quadratic_weighted_kappa- 二次方

实现:

def quadratic_weighted_kappa(rater_a, rater_b, min_rating=None, max_rating=None):

    rater_a = np.array(rater_a, dtype=int)
    rater_b = np.array(rater_b, dtype=int)
    assert(len(rater_a) == len(rater_b))
    if min_rating is None:
        min_rating = min(min(rater_a), min(rater_b))
    if max_rating is None:
        max_rating = max(max(rater_a), max(rater_b))
    conf_mat = confusion_matrix(rater_a, rater_b,
                                min_rating, max_rating)#计算混淆矩阵
    num_ratings = len(conf_mat)
    num_scored_items = float(len(rater_a))

    hist_rater_a = histogram(rater_a, min_rating, max_rating)
    hist_rater_b = histogram(rater_b, min_rating, max_rating)

    numerator = 0.0
    denominator = 0.0

    for i in range(num_ratings):
        for j in range(num_ratings):
            expected_count = (hist_rater_a[i] * hist_rater_b[j]
                              / num_scored_items)
            d = pow(i - j, 2.0) / pow(num_ratings - 1, 2.0)#d是惩罚系数,以指数增加,当两个label比如0-3/0-4就会惩罚指数增加
            #如果i==j的话,那么d=0
            numerator += d * conf_mat[i][j] / num_scored_items
            denominator += d * expected_count / num_scored_items

    return 1.0 - numerator / denominator    

 

对它的介绍:

计算二次加权kappa Quadratic_weighted_kappa计算二次加权kappa值,该值是提供离散数值等级的两个评估者之间评估者之间一致性的度量。 潜在值的范围从-1(表示完全不同意)到1(表示完全同意)。 如果所有协议都是偶然的,则预期kappa值为0。

也就是说,如果a和b完全一样,那么返回值为1,numerator 值为1;

那么什么情况下会返回-1呢?

尝试了一下下面的例子:

from ml_metrics import quadratic_weighted_kappa
a=[1,0,1]
b=[0,1,0]
print(quadratic_weighted_kappa(a,b))

#输出:
-0.7999999999999998

 

预测完全相反居然不是-1??

我又把函数拿出来单独做了运算,发现:

    print(conf_mat)
    print(hist_rater_a,hist_rater_b)
    
    for i in range(num_ratings):
        for j in range(num_ratings):
            expected_count = (hist_rater_a[i] * hist_rater_b[j]
                              / num_scored_items)
            d = pow(i - j, 2.0) / pow(num_ratings - 1, 2.0)
            numerator += d * conf_mat[i][j] / num_scored_items
            denominator += d * expected_count / num_scored_items
            print(expected_count,numerator,denominator)
    return 1.0 - numerator / denominator

a=[1,0,1]
b=[0,1,0]
print(quadratic_weighted_kappa(a,b))

#输出:
[[0, 1], [2, 0]]
[1, 2] [2, 1]
0.6666666666666666 0.0 0.0
0.3333333333333333 0.3333333333333333 0.1111111111111111
1.3333333333333333 1.0 0.5555555555555556
0.6666666666666666 1.0 0.5555555555555556
-0.7999999999999998

可以手动算一下,确实是这样的。

Kappa系数是一种比例,代表着分类与完全随机的分类产生错误减少的比例

2.linear_weighted_kappa

与二次方的相比,只有d的计算方式不同:

d = abs(i - j) / float(num_ratings - 1)

这样的话,它对不同的label没有特别的惩罚,label之间如果误判的话代价是相同的。

3.例子

https://www.kaggle.com/aroraaman/quadratic-kappa-metric-explained-in-5-simple-steps,这个总结的非常好,可以点击去看,就不在这里搬运了。

 

posted @ 2020-06-07 18:34  lypbendlf  阅读(272)  评论(0编辑  收藏  举报