【NLG】(五)文本生成评价指标—— kl_divergence原理及代码示例

前奏:

【NLG】(一)文本生成评价指标——BLEU原理及代码示例

【NLG】(二)文本生成评价指标—— METEOR原理及代码示例

【NLG】(三)文本生成评价指标—— ENTROPY原理及代码示例

【NLG】(四)文本生成评价指标—— diversity原理及代码示例


1.kl_divergence原理

相对熵又称KL散度,如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异。

在机器学习中,P往往用来表示样本的真实分布,Q用来表示模型所预测的分布,那么KL散度就可以计算两个分布的差异,也就是Loss损失值:

从KL散度公式中可以看到Q的分布越接近P(Q分布越拟合P),那么散度值越小,即损失值越小。

因为对数函数是凸函数,所以KL散度的值为非负数。

有时会将KL散度称为KL距离,但它并不满足距离的性质:

  1. KL散度不是对称的;
  2. KL散度不满足三角不等式。

在文本生成中,用来判断生成的文本跟参考文本数据之间的分布之间的差异。

2.优缺点

这个没有明确的优缺点,该指标在陈述一个事实。

3.如何算kl_divergence

这个demo仅供参考,根据公式以及自己的理解写的代码,得出的KL散度值非常小,10-8,感觉不太对,但是还没有发现哪里有问题。如果那位博友看出问题,求指正~

def kl_divergence(labels, predicts):
    '''
    从predict的角度看,与labels有多大不同,Dkl=sigma P_p * log(P_p / P_l)
    '''
    counter_label = [defaultdict(int), defaultdict(int),
               defaultdict(int), defaultdict(int)]
    for gg in labels:
        g = gg.rstrip().split()
        for n in range(4):
            for idx in range(len(g)-n):
                ngram = ' '.join(g[idx:idx+n+1])
                counter_label[n][ngram] += 1

    counter_predict = [defaultdict(int), defaultdict(int),
               defaultdict(int), defaultdict(int)]
    for gg in predicts:
        g = gg.rstrip().split()
        for n in range(4):
            for idx in range(len(g)-n):
                ngram = ' '.join(g[idx:idx+n+1])
                counter_predict[n][ngram] += 1
    # Dkl=sigma P_p * log(P_p / P_l) 从p的角度看与l有多大不同
    kv_score = [0.0, 0.0, 0.0, 0.0]
    for n in range(4):
        total_label = sum(counter_label[n].values()) + 1e-10
        total_predict = sum(counter_predict[n].values()) + 1e-10
        for k in counter_label[n].keys():
            p_l = (counter_label[n][k] + 0.0) / total_label
            p_p = 0.0
            if k in counter_predict[n].keys():
                p_p = (counter_predict[n][k] + 0.0) / total_predict
            kv_score[n] += p_p * np.log((p_p + 1e-10) / p_l)
    return kv_score

if __name__ == '__main__':
    labels_split = ['你 说 什 么 啊, 听 不 懂?', '你 说 的 是 啥 ?']
    predicts_split = ['你 说 什 么 ?', '你 说 的 是 啥 ?']
    kl_d = kl_divergence(labels_split, predicts_split)

 

参考:

1.原理:https://blog.csdn.net/weixinhum/article/details/85064685

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值