SciTech-BigDataAIML-Measurement: Euclidian Distance + Manhattan Distance + Area面积 + Density密度 + KLD(KL散度):测度比较"两Distribution(概率分布)"的Similarity(接近度)
Measurement
测度
Euclidian Distance(欧几理得距离)
\(\large \begin{array}{rl} \\
EuDistance(Point_1, Point_2) &= \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} \\
where: & \\
Point_1 &= (x_1, y_1), \\
Point_2 &= (x_2, y_2), \\
\end{array}\)
Manhattan Distance(出租车站点距离)
\(\large \begin{array}{rl} \\
MhtDistance(Point_1, Point_2) &= |x_1 - x_2| + |y_1 - y_2| \\
where: & \\
Point_1 &= (x_1, y_1), \\
Point_2 &= (x_2, y_2), \\
\end{array}\)
KLD(Kullback-Leibler Divergence,KL散度):
测度比较两Distribution的Similarity
- AI领域最重要的 Measure Method of Distributions(分布度量方法)
- 简写和全称: KLD(Kullback-Leibler Divergence, KL散度)
- 用途: 测度比较两Distribution的Similarity(
- 统计应用上, 我们经常需要用一个常用、组件模块化、简单近似的 \(\large Distribution\) $\large f^* $,
去描述另一个复杂的, \(\large Distribution\) $\large f $ 或 \(\large Observations(观察数据)\) \(\large D\); - 这时,我们需要一个度量来衡量选择的 \(\large \bm{ Approximated\ Distribution}\) $\large f^* $
对比原 \(\large Distribution\) \(\large f\) 总共 \(\large Loss\) 多少\(\large \bm{ Information(信息量)}\)。
这就是KLD(散度)起作用的地方。
- 统计应用上, 我们经常需要用一个常用、组件模块化、简单近似的 \(\large Distribution\) $\large f^* $,
\(\large Information\ Entropy\)(信息熵)
KL(Kullback-Leibler Divergence, 散度)起源于 IT(Information Theory, 信息理论)。
I.T.的主要目标是量化数据的信息量。
I.T. 最重要的度量标准称为 \(\large Entropy\)(熵), 常用 \(\large H\) 表示。
\(large \text{for a Distribution} \large p(X)\), \(\large \text{ the } Definition \text{ of } Entropy\) 的定义是:
\(\large \begin{array}{rl} \\
H &= \overset{N}{\underset{i=1}{\sum}}{p(x_{i}) \cdot log_{k}{p(x_{i})}} \\
if\ k = 2, then: \\
\end{array}\)
如果计算时使用\(\large log_{2}\), 我们可以将Entropy(熵)解释为
"Encoding(编码)我们的Information(信息)所需的$ Minimum\ Number \text{ of } bits$(最小比特数)。
举几个例子,有一门语言是由 ABCD 四个字母组成的,整个语料库为 8192个字母。
Example 1, A、B、C、D 四个字母分别占 1/2(4096个), 1/4(2048个), 1/8(1024个), 1/8(1024个)。
那么最有效的一种编码方式为 A(0), B(10), C(110), D(111)。
整个语料库的长度 4096 x 1 + 2048 x 2 + 1024 x 3 x 2=14336,平均长度为 14336/8192=1.75。
和下面代码的【结果1】一致。Example 2, ABCD 等概率, 最有效的一种编码方式为 A(00), B(01), C(10), D(11), 计算平均长度为2,
和代码中的【结果2】一致。Example 3: ABCD 四个字母占比变成1/8(1024个), 1/8(1024个), 1/2(4096个), 1/4(2048个),
最有效的一种编码方式为 A(110), B(111), C(0), D(10), 计算平均长度为1.75,
和代码中的【结果3】一致。
我们用\(\large Entropy\)(熵)的方式计算:
- 代码示例1:
import math
def cal_entropy_log2(prob_distribution):
return -sum(p * math.log2(p) for p in prob_distribution)
p = [0.5, 0.25, 0.125, 0.125]
entropy = cal_entropy_log2(p)
print(f"熵: {entropy}")
#【结果1】输出为:熵: 1.75
q = [0.25, 0.25, 0.25, 0.25]
entropy = cal_entropy_log2(q)
print(f"熵: {entropy}")
#【结果2】输出为:熵: 2.0
q2 = [0.125, 0.125, 0.5, 0.25]
entropy = cal_entropy_log2(q2)
print(f"熵: {entropy}")
#【结果3】输出为:熵: 1.75
import numpy as np
def kl_divergence_log2(a, b):
return sum(a[i] * np.log2(a[i]/b[i]) for i in range(len(a)))
print('KL-divergence_log2(例1 || 例2): %.6f ' % kl_divergence_log2(p, q))
# 输出:KL-divergence_log2(例1 || 例2): 0.250000
print('KL-divergence_log2(例1 || 例3): %.6f ' % kl_divergence_log2(p, q2))
# 输出:KL-divergence_log2(例1 || 例3):
\(\large KL\)(Kullback-Leibler) 散度的计算公式
\(\large KL\text{ is a kind of }Method \text{ for } measuring \text{ the } difference \text{ between } two\ Distributions\)
散度, 是一种衡量两个概率分布之间差异性的度量方法。
\(\large KL\)是对熵公式的轻微修改。
\(\large \begin{array}{ll} \\
Hypothesis, \\
\text{ there is a }Distribution\ p(X), \text{ usually means } Observations,\ Samples,\\
\text{ and } Approximated\ Distribution\ q, \text{ usually means the }output \text{ of } Predicative\ Model,\\
then, \text{ the } difference \text{ between these } two\ Distribution \text{ is as follow }:\\
\end{array}\)
离散性的公式如下:
\(\large \begin{array}{rl} \\
D_{KL}(p || q) &= \overset{N}{\underset{i=1}{\sum}}{[ p(x_{i}) \cdot ( log_{k}{p(x_{i})} - log_{k}{q(x_{i})} ) ]} \\
& = \overset{N}{\underset{i=1}{\sum}}{( p(x_{i}) \cdot log_{k}{ \dfrac{p(x_{i})}{q(x_{i})} } )} \\
\end{array}\)
连续性的公式如下:
\(\large \begin{array}{rl} \\
D_{KL}(p || q) &= \int_{-\infty}^{\infty} { p(x) \cdot [ log_{k}{p(x)} - log_{k}{q(x)} ] } \text{ d}x \\
&= \int_{-\infty}^{\infty} { p(x) \cdot log_{k}{ \dfrac{p(x)}{q(x)} } \text{ d}x } \\
\end{array}\)
二进制编码角度的解释
假如用二进制编码长度来解释 \(\large KL\) , 其衡量的是当使用基于\(\large q(x)\) 的编码而非基于\(\large p(x)\) 的编码对来自\(\large p(x)\)的\(\large Samples\)进行编码时, 所需的额外比特数的\(\large Expectation\), 结果大于等于 0(两个\(\large Distribution\)完全一样时为 0)。
还以【例1】计算 \(\large KL\) 散度(注意:对数的底还是取 2,而不是概率学用到的自然底数 e)。
当我们使用【例2】的 ABCD 编码方式对【例1】的数据编码时,
平均长度显然就是 2,
所以 \(\large KL(例1||例2) =2-1.75=0.25\)。
当我们使用【例3】的 ABCD 编码方式对【例1】的数据编码时,
长度变成 (4096 * 3 + 2048 * 3 + 1024 * 1 + 1024 * 2 )/8192 = 2.625,
所以 \(\large KL(例1||例3) = 2.625-1.75 =0.875\),
和代码一致, 即相对于自身分布的最优编码,用另一个分布的最优编码来编码时,平均额外需要0.875个比特。
KL 散度的分步计算
KL 散度的中间步骤的计算结果, 可能为正, 也可能为负数。
以下为 p 和 q1 的 \(\large KL\) 散度的分步计算结果,可对照上面的数据示例和程序输出看。
| p[i] | q[i] | p[i]/q[i] | log(p[i]/q[i]) | p[i]*log(p[i]/q[i]) |
|---|---|---|---|---|
| 0.15 | 0.14 | 1.071429 | 0.068993 | 0.010349 |
| 0.13 | 0.14 | 0.928571 | -0.074108 | -0.009634 |
| 0.23 | 0.25 | 0.920000 | -0.083382 | -0.019178 |
| 0.09 | 0.08 | 1.125000 | 0.117783 | 0.010600 |
| 0.2 | 0.21 | 0.952381 | -0.048790 | -0.009758 |
| 0.05 | 0.06 | 0.833333 | -0.182322 | -0.009116 |
| 0.15 | 0.12 | 1.250000 | 0.223144 | 0.033472 |
| 求和: | 0.006735 |
分步计算的结果和后面代码的一致。
如下面代码所示。
import numpy as np
from kl_div_data import box_p, box_q1, box_q2
def kl_divergence_step(a, b):
return np.array([a[i] * np.log(a[i]/b[i]) for i in range(len(a))])
np.set_printoptions(precision=6)
print(kl_divergence_step(box_p, box_q1))
# 输出:
# [ 0.010349 -0.009634 -0.019178 0.0106 -0.009758 -0.009116 0.033472]
print(kl_divergence_step(box_p, box_q2))
# 输出:
# [ 0.046523 0.021717 0.010224 -0.051783 0.057536 -0.058158 0.076624]
\(\large KL\) 散度的特点及代码示例
\(\large KL\)散度具有以下显著特点:
- 非对称性: \(\large KL\)散度是非对称的,
即从 P分布到 Q分布 的 \(\large KL\)散度, 与从 Q分布 到 P分布 的 \(\large KL\)散度可能不同。
如代码中示例, \(\large KL(p || q1)\) 和 $\large KL(q1 || p) $ 不同。 - 非负性: \(\large KL\)散度的值始终为非负数。
当且仅当两个概率分布完全一致时, \(\large KL\)散度的值才为零。
\(\large KL\)散度值越大,表示两个概率分布越不相似。
如代码示例,相对 p, q2 的 \(\large KL\) 散度比 q1大, 这和图上的直观显示一致。 - 非度量性: \(\large KL\)散度并不满足度量空间的性质,特别是三角不等式。
由于非对称性和非度量性, \(\large KL\) 散度不能用于计算两个分布之间的“距离”或“相似度”。 - 直观性: \(\large KL\)散度的值越大, 表示用一个分布近似另一个分布时引入的信息损失或误差越大。
这使得KL散度在度量模型的误差或信息损失方面非常直观。
以下代码列出 \(\large KL\) 散度的三种实现方式:
- 简单函数
- 使用 Scipy rel_entr 函数
- 使用 Pytorch KLDivLoss
简单函数
import numpy as np
from scipy.special import rel_entr
from kl_div_data import box_p, box_q1, box_q2
def kl_divergence(a, b):
return sum(a[i] * np.log(a[i]/b[i]) for i in range(len(a)))
print('KL-divergence(p || q1): %.6f ' % kl_divergence(box_p, box_q1))
# KL 散度没有对称性
print('KL-divergence(q1 || p): %.6f ' % kl_divergence(box_q1, box_p))
# 从计算结果可以看出,概率分布 q2 和 p 的差异明显更大
print('KL-divergence(p || q2): %.6f ' % kl_divergence(box_p, box_q2))
使用 Scipy rel_entr 函数
# 使用 Scipy rel_entr 函数
p = np.array(box_p)
q1 = np.array(box_q1)
q2 = np.array(box_q2)
# 和上面函数的计算结果一致
print('rel_entr KL-divergence(p || q1): %.6f ' % sum(rel_entr(p, q1)))
print('rel_entr KL-divergence(p || q2): %.6f ' % sum(rel_entr(p, q2)))
print('rel_entr KL-divergence(q1 || p): %.6f ' % sum(rel_entr(q1, p)))
# 自身的 KL 散度是0
print('rel_entr KL-divergence(p || p): %.6f ' % sum(rel_entr(p, p)))
# ------- 输出如下 -------
# KL-divergence(p || q1): 0.006735
# KL-divergence(q1 || p): 0.006547
# KL-divergence(p || q2): 0.102684
# rel_entr KL-divergence(p || q1): 0.006735
# rel_entr KL-divergence(p || q2): 0.102684
# rel_entr KL-divergence(q1 || p): 0.006547
# rel_entr KL-divergence(p || p): 0.000000
使用 Pytorch KLDivLoss
# torch 的写法,参考:https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html
import torch
kl_loss = torch.nn.KLDivLoss(reduction="sum",log_target=False)
# 第 1 个参数为模型的输出,上面直接指定了概率,故增加一次 log
# 第 2 个参数为真实概率
output = kl_loss(torch.log(torch.tensor(q1)), torch.tensor(p))
print(output)
# 输出:
# tensor(0.0067, dtype=torch.float64)
作为Loss Function(损失函数)
使用 \(\large KL\) 作为Loss Function(损失函数)的算法在机器学习和深度学习中非常常见,尤其在处理涉及概率分布的问题时。例如
- VAE(变分自编码器): VAE是一种生成模型,它结合了自编码器的结构和概率图模型。
在 VAE 中, \(\large KL\) 被用作Loss Function的一部分, 用于衡量Encoder生成的潜在空间分布与先验分布之间的差异。
SciTech-BigDataAIML-Measurement: Euclidian Distance + Manhattan Distance + Area面积 + Density密度 + KLD(KL散度):测度比较"两Distribution(概率分布)"的Similarity(接近度)的更多相关文章
- Manhattan distance(for lab)
Input four integer x1, y1, x2, y2, which is mean that the coordinates of two points A(x1, y1), B(x2, ...
- poj 1265 Area 面积+多边形内点数
Area Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5861 Accepted: 2612 Description ...
- 【TOJ 1449】Area of Circles II(求不同位置的两圆面积之和)
描述 There are two circles on the plane. Now you must to calculate the area which they cover the plane ...
- Annoy 近邻算法
Annoy 随机选择两个点,以这两个节点为初始中心节点,执行聚类数为2的kmeans过程,最终产生收敛后两个聚类中心点 二叉树底层是叶子节点记录原始数据节点,其他中间节点记录的是分割超平面的信息 但是 ...
- 概率分布之间的距离度量以及python实现
1. 欧氏距离(Euclidean Distance) 欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式.(1)二维平面上两点a(x1,y1)与b(x2,y2)间的欧 ...
- Approximate Nearest Neighbors.接近最近邻搜索
(一):次优最近邻:http://en.wikipedia.org/wiki/Nearest_neighbor_search 有少量修改:如有疑问,请看链接原文.....1.Survey:Neares ...
- 从线性模型(linear model)衍生出的机器学习分类器(classifier)
1. 线性模型简介 0x1:线性模型的现实意义 在一个理想的连续世界中,任何非线性的东西都可以被线性的东西来拟合(参考Taylor Expansion公式),所以理论上线性模型可以模拟物理世界中的绝大 ...
- PyTorch 实战:计算 Wasserstein 距离
PyTorch 实战:计算 Wasserstein 距离 2019-09-23 18:42:56 This blog is copied from: https://mp.weixin.qq.com/ ...
- GAN实战笔记——第五章训练与普遍挑战:为成功而GAN
训练与普遍挑战:为成功而GAN 一.评估 回顾一下第1章中伪造达・芬奇画作的类比.假设一个伪造者(生成器)正在试图模仿达・芬奇,想使这幅伪造的画被展览接收.伪造者要与艺术评论家(判别器)竞争,后者试图 ...
- C博客作业01--分支,顺序结构
本章学习总结(2分) 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 本周初次接触C语言,一开始难度较大,很多代码都看不懂,书里面的章节要看很多遍.开始编写代码时也遇到很多困难 ...
随机推荐
- 【MOOC】华中科技大学操作系统慕课答案-期末测试题
文章目录 单选题 填空题 判断题 主观题 单选题 1 当操作系统处理缺页中断的时候,CPU处在 . A. 用户态 √B. 核态 C. 不确定的状态 D. 空闲状态 2 操作系统的用户界面可以分为两 ...
- Axure RP中后台管理系统通用原型模板元件库
Axure RP中后台管理系统通用原型方案 v2是一套通用型的中后台信息系统原型方案,可以快速扩展并输出标准美观的中后台产品原型,极大的提升输出效率和节省协作成本.方案中提供了几十套不同风格和结构的系 ...
- 操作系统综合题之“采用记录型信号量机制实现进程INPUT、PROCESS和OUTPUT的同步算法(代码补充)”
1.问题:系统中有有三个进程INPUT.PROCESS和OUTPUT,共用两个缓冲区BUF1和BUF2.假期设BUF1中最多可放10个数据,现已放入了2个数据:BUF2最多可放5个数据.INPUT进程 ...
- uniapp跨平台开发HarmonyOS NEXT应用初体验
之前写过使用uniapp开发鸿蒙应用的教程,简单介绍了如何配置开发环境和运行项目.那时候的HbuilderX还是4.22版本,小一年过去了HbuilderX的正式版本已经来到4.64,历经了多个版本的 ...
- 鸿蒙NEXT实战教程—实现音乐歌词同步滚动
之前写过一个音乐播放器项目,今天再给它完善一下,加一个歌词同步滚动. 先看效果图: 要做歌词同步滚动,我们首先需要的文件资源就是音乐文件和与之匹配的歌词文件.现在歌词文件不太好找,没关系,我们可以 ...
- Python基础 - 常用内置对象
数字.字符串.字节串.列表.元组.字典.集合.布尔型.空类型.异常.文件.可迭代对象.编程单元def.class.module 常量与变量 x = 3 type(x) # 查看变量类型 int typ ...
- C#实现SSE通信方式的MCP Server
前面的课程,我们使用MCP Server,用的是网络上魔搭提供的. 下面我们一起来实现,用C#实现自己的MCP Server. MCP Server通信方式支持SSE.Stdio. 下面我们先实现SS ...
- Spring注解之@Bean 用法介绍
注解 @Bean是一个方法级别的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里.添加的bean的id为方法名. 定义Bean 下面摘录@Configur ...
- 如何用Leangoo破解需求隔离与频繁变更的协作困局?
作为一位经历过"需求文档满天飞.系统各自为战"的研发负责人,我深知团队在需求频繁变更时面临的痛点--信息割裂导致响应滞后.优先级混乱引发返工.协作低效拖慢交付节奏. 近期,我深度测 ...
- AWK用法全解
一.awk介绍 awk是Linux自带的一个逐行扫描的文本处理工具,支持正则表达式.循环控制.条件判断.格式化输出.AWK自身带有一些变量,可以在书写脚本时调用. 二.基本语法格式 2.1.在shel ...