1. 歐氏距離(Euclidean Distance)
歐氏距離是最易於理解的一種距離計算方法,源自歐氏空間中兩點間的距離公式。
(1)二維平面上兩點a(x1,y1)與b(x2,y2)間的歐氏距離:
(2)三維空間兩點a(x1,y1,z1)與b(x2,y2,z2)間的歐氏距離:
(3)兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的歐氏距離:
(4)也可以用表示成向量運算的形式:
python中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解 6 d1=np.sqrt(np.sum(np.square(x-y))) 7 8 #方法二:根據scipy庫求解 9 from scipy.spatial.distance import pdist 10 X=np.vstack([x,y]) 11 d2=pdist(X)
2. 曼哈頓距離(Manhattan Distance)
從名字就可以猜出這種距離的計算方法了。想象你在曼哈頓要從一個十字路口開車到另外一個十字路口,駕駛距離是兩點間的直線距離嗎?顯然不是,除非你能穿越大樓。實際駕駛距離就是這個“曼哈頓距離”。而這也是曼哈頓距離名稱的來源, 曼哈頓距離也稱為城市街區距離(City Block distance)。
(1)二維平面兩點a(x1,y1)與b(x2,y2)間的曼哈頓距離
(2)兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的曼哈頓距離
python中的實現 :
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解 6 d1=np.sum(np.abs(x-y)) 7 8 #方法二:根據scipy庫求解 9 from scipy.spatial.distance import pdist 10 X=np.vstack([x,y]) 11 d2=pdist(X,'cityblock')
3. 切比雪夫距離 ( Chebyshev Distance )
國際象棋玩過么?國王走一步能夠移動到相鄰的8個方格中的任意一個。那么國王從格子(x1,y1)走到格子(x2,y2)最少需要多少步?自己走走試試。你會發現最少步數總是max( | x2-x1 | , | y2-y1 | ) 步 。有一種類似的一種距離度量方法叫切比雪夫距離。
(1)二維平面兩點a(x1,y1)與b(x2,y2)間的切比雪夫距離
(2)兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的切比雪夫距離
這個公式的另一種等價形式是
看不出兩個公式是等價的?提示一下:試試用放縮法和夾逼法則來證明。
在python中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解 6 d1=np.max(np.abs(x-y)) 7 8 #方法二:根據scipy庫求解 9 from scipy.spatial.distance import pdist 10 X=np.vstack([x,y]) 11 d2=pdist(X,'chebyshev')
4. 閔可夫斯基距離(Minkowski Distance)
閔氏距離不是一種距離,而是一組距離的定義。
(1) 閔氏距離的定義
兩個n維變量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的閔可夫斯基距離定義為:
也可寫成
其中p是一個變參數。
當p=1時,就是曼哈頓距離
當p=2時,就是歐氏距離
當p→∞時,就是切比雪夫距離
根據變參數的不同,閔氏距離可以表示一類的距離。
(2)閔氏距離的缺點
閔氏距離,包括曼哈頓距離、歐氏距離和切比雪夫距離都存在明顯的缺點。
舉個例子:二維樣本(身高,體重),其中身高范圍是150~190,體重范圍是50~60,有三個樣本:a(180,50),b(190,50),c(180,60)。那么a與b之間的閔氏距離(無論是曼哈頓距離、歐氏距離或切比雪夫距離)等於a與c之間的閔氏距離,但是身高的10cm真的等價於體重的10kg么?因此用閔氏距離來衡量這些樣本間的相似度很有問題。
簡單說來,閔氏距離的缺點主要有兩個:(1)將各個分量的量綱(scale),也就是“單位”當作相同的看待了。(2)沒有考慮各個分量的分布(期望,方差等)可能是不同的。
python中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解,p=2 6 d1=np.sqrt(np.sum(np.square(x-y))) 7 8 #方法二:根據scipy庫求解 9 from scipy.spatial.distance import pdist 10 X=np.vstack([x,y]) 11 d2=pdist(X,'minkowski',p=2)
5. 標准化歐氏距離 (Standardized Euclidean distance )
(1)標准歐氏距離的定義
標准化歐氏距離是針對簡單歐氏距離的缺點而作的一種改進方案。標准歐氏距離的思路:既然數據各維分量的分布不一樣,好吧!那我先將各個分量都“標准化”到均值、方差相等吧。均值和方差標准化到多少呢?這里先復習點統計學知識吧,假設樣本集X的均值(mean)為m,標准差(standard deviation)為s,那么X的“標准化變量”表示為:
標准化后的值 = ( 標准化前的值 - 分量的均值 ) /分量的標准差
經過簡單的推導就可以得到兩個n維向量a(x11,x12,…,x1n)與 b(x21,x22,…,x2n)間的標准化歐氏距離的公式:
如果將方差的倒數看成是一個權重,這個公式可以看成是一種加權歐氏距離(Weighted Euclidean distance)。
python中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 X=np.vstack([x,y]) 6 7 #方法一:根據公式求解 8 sk=np.var(X,axis=0,ddof=1) 9 d1=np.sqrt(((x - y) ** 2 /sk).sum()) 10 11 #方法二:根據scipy庫求解 12 from scipy.spatial.distance import pdist 13 d2=pdist(X,'seuclidean')
6. 馬氏距離(Mahalanobis Distance)
(1)馬氏距離定義
有M個樣本向量X1~Xm,協方差矩陣記為S,均值記為向量μ,則其中樣本向量X到u的馬氏距離表示為:
而其中向量Xi與Xj之間的馬氏距離定義為:
若協方差矩陣是單位矩陣(各個樣本向量之間獨立同分布),則公式就成了:
也就是歐氏距離了。
若協方差矩陣是對角矩陣,公式變成了標准化歐氏距離。
python 中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #馬氏距離要求樣本數要大於維數,否則無法求協方差矩陣 6 #此處進行轉置,表示10個樣本,每個樣本2維 7 X=np.vstack([x,y]) 8 XT=X.T 9 10 #方法一:根據公式求解 11 S=np.cov(X) #兩個維度之間協方差矩陣 12 SI = np.linalg.inv(S) #協方差矩陣的逆矩陣 13 #馬氏距離計算兩個樣本之間的距離,此處共有10個樣本,兩兩組合,共有45個距離。 14 n=XT.shape[0] 15 d1=[] 16 for i in range(0,n): 17 for j in range(i+1,n): 18 delta=XT[i]-XT[j] 19 d=np.sqrt(np.dot(np.dot(delta,SI),delta.T)) 20 d1.append(d) 21 22 #方法二:根據scipy庫求解 23 from scipy.spatial.distance import pdist 24 d2=pdist(XT,'mahalanobis')
馬氏優缺點:
1)馬氏距離的計算是建立在總體樣本的基礎上的,這一點可以從上述協方差矩陣的解釋中可以得出,也就是說,如果拿同樣的兩個樣本,放入兩個不同的總體中,最后計算得出的兩個樣本間的馬氏距離通常是不相同的,除非這兩個總體的協方差矩陣碰巧相同;
2)在計算馬氏距離過程中,要求總體樣本數大於樣本的維數,否則得到的總體樣本協方差矩陣逆矩陣不存在,這種情況下,用歐式距離計算即可。
3)還有一種情況,滿足了條件總體樣本數大於樣本的維數,但是協方差矩陣的逆矩陣仍然不存在,比如三個樣本點(3,4),(5,6)和(7,8),這種情況是因為這三個樣本在其所處的二維空間平面內共線。這種情況下,也采用歐式距離計算。
4)在實際應用中“總體樣本數大於樣本的維數”這個條件是很容易滿足的,而所有樣本點出現3)中所描述的情況是很少出現的,所以在絕大多數情況下,馬氏距離是可以順利計算的,但是馬氏距離的計算是不穩定的,不穩定的來源是協方差矩陣,這也是馬氏距離與歐式距離的最大差異之處。
優點:它不受量綱的影響,兩點之間的馬氏距離與原始數據的測量單位無關;由標准化數據和中心化數據(即原始數據與均值之差)計算出的二點之間的馬氏距離相同。馬氏距離還可以排除變量之間的相關性的干擾。缺點:它的缺點是誇大了變化微小的變量的作用。
7. 夾角余弦(Cosine)
也可以叫余弦相似度。 幾何中夾角余弦可用來衡量兩個向量方向的差異,
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解 6 d1=np.dot(x,y)/(np.linalg.norm(x)*np.linalg.norm(y)) 7 8 #方法二:根據scipy庫求解 9 from scipy.spatial.distance import pdist 10 X=np.vstack([x,y]) 11 d2=1-pdist(X,'cosine')
兩個向量完全相等時,余弦值為1,如下的代碼計算出來的d=1。
1 d=1-pdist([x,x],'cosine')
8. 皮爾遜相關系數(Pearson correlation)
(1) 皮爾遜相關系數的定義
前面提到的余弦相似度只與向量方向有關,但它會受到向量的平移影響,在夾角余弦公式中如果將 x 平移到 x+1, 余弦值就會改變。怎樣才能實現平移不變性?這就要用到皮爾遜相關系數(Pearson correlation),有時候也直接叫相關系數。
如果將夾角余弦公式寫成:
表示向量x和向量y之間的夾角余弦,則皮爾遜相關系數則可表示為:
皮爾遜相關系數具有平移不變性和尺度不變性,計算出了兩個向量(維度)的相關性。
在python中的實現:
1 import numpy as np 2 x=np.random.random(10) 3 y=np.random.random(10) 4 5 #方法一:根據公式求解 6 x_=x-np.mean(x) 7 y_=y-np.mean(y) 8 d1=np.dot(x_,y_)/(np.linalg.norm(x_)*np.linalg.norm(y_)) 9 10 #方法二:根據numpy庫求解 11 X=np.vstack([x,y]) 12 d2=np.corrcoef(X)[0][1]
相關系數是衡量隨機變量X與Y相關程度的一種方法,相關系數的取值范圍是[-1,1]。相關系數的絕對值越大,則表明X與Y相關度越高。當X與Y線性相關時,相關系數取值為1(正線性相關)或-1(負線性相關)。
9. 漢明距離(Hamming distance)
(1)漢明距離的定義
兩個等長字符串s1與s2之間的漢明距離定義為將其中一個變為另外一個所需要作的最小替換次數。例如字符串“1111”與“1001”之間的漢明距離為2。
應用:信息編碼(為了增強容錯性,應使得編碼間的最小漢明距離盡可能大)。
在python中的實現:
1 import numpy as np 2 from scipy.spatial.distance import pdist 3 x=np.random.random(10)>0.5 4 y=np.random.random(10)>0.5 5 6 x=np.asarray(x,np.int32) 7 y=np.asarray(y,np.int32) 8 9 #方法一:根據公式求解 10 d1=np.mean(x!=y) 11 12 #方法二:根據scipy庫求解 13 X=np.vstack([x,y]) 14 d2=pdist(X,'hamming')
10. 傑卡德相似系數(Jaccard similarity coefficient)
(1) 傑卡德相似系數
兩個集合A和B的交集元素在A,B的並集中所占的比例,稱為兩個集合的傑卡德相似系數,用符號J(A,B)表示。
傑卡德相似系數是衡量兩個集合的相似度一種指標。
(2) 傑卡德距離
與傑卡德相似系數相反的概念是傑卡德距離(Jaccard distance)。傑卡德距離可用如下公式表示:
傑卡德距離用兩個集合中不同元素占所有元素的比例來衡量兩個集合的區分度。
(3) 傑卡德相似系數與傑卡德距離的應用
可將傑卡德相似系數用在衡量樣本的相似度上。
樣本A與樣本B是兩個n維向量,而且所有維度的取值都是0或1。例如:A(0111)和B(1011)。我們將樣本看成是一個集合,1表示集合包含該元素,0表示集合不包含該元素。
在python中的實現:
1 import numpy as np 2 from scipy.spatial.distance import pdist 3 x=np.random.random(10)>0.5 4 y=np.random.random(10)>0.5 5 6 x=np.asarray(x,np.int32) 7 y=np.asarray(y,np.int32) 8 9 #方法一:根據公式求解 10 up=np.double(np.bitwise_and((x != y),np.bitwise_or(x != 0, y != 0)).sum()) 11 down=np.double(np.bitwise_or(x != 0, y != 0).sum()) 12 d1=(up/down) 13 14 15 #方法二:根據scipy庫求解 16 X=np.vstack([x,y]) 17 d2=pdist(X,'jaccard')
11. 布雷柯蒂斯距離(Bray Curtis Distance)
Bray Curtis距離主要用於生態學和環境科學,計算坐標之間的距離。該距離取值在[0,1]之間。它也可以用來計算樣本之間的差異。
樣本數據:
計算:
在python中的實現:
1 import numpy as np 2 from scipy.spatial.distance import pdist 3 x=np.array([11,0,7,8,0]) 4 y=np.array([24,37,5,18,1]) 5 6 #方法一:根據公式求解 7 up=np.sum(np.abs(y-x)) 8 down=np.sum(x)+np.sum(y) 9 d1=(up/down) 10 11 #方法二:根據scipy庫求解 12 X=np.vstack([x,y]) 13 d2=pdist(X,'braycurtis')
1、卡方檢驗
統計學上的χ2統計量,由於它最初是由英國統計學家Karl Pearson在1900年首次提出的,因此也稱之為Pearson χ2,其計算公式為
其中,Ai為i水平的觀察頻數,Ei為i水平的期望頻數,n為總頻數,pi為i水平的期望頻率。i水平的期望頻數Ei等於總頻數n×i水平的期望概率pi。當n比較大時,χ2統計量近似服從k-1(計算Ei時用到的參數個數)個自由度的卡方分布。
卡方檢驗經常用來檢驗某一種觀測分布是不是符合某一類典型的理論分布(如二項分布,正態分布等)。觀察頻數與期望頻數越接近,兩者之間的差異越小,χ2值越小;如果兩個分布完全一致,χ2值為0;反之,觀察頻數與期望頻數差別越大,兩者之間的差異越大,χ2值越大。換言之,大的χ2值表明觀察頻數遠離期望頻數,即表明遠離假設。小的χ2值表明觀察頻數接近期望頻數,接近假設。因此,χ2是觀察頻數與期望頻數之間距離的一種度量指標,也是假設成立與否的度量指標。如果χ2值“小”,研究者就傾向於不拒絕H0;如果χ2值大,就傾向於拒絕H0。至於χ2在每個具體研究中究竟要大到什么程度才能拒絕H0,則要借助於卡方分布求出所對應的P值來確定(通常取p=0.05)。
在python中的實現:
1 # -*- coding: utf-8 -*- 2 ''' 3 卡方公式(o-e)^2 / e 4 期望值和收集到數據不能低於5,o(observed)觀察到的數據,e(expected)表示期望的數據 5 (o-e)平方,最后除以期望的數據e 6 ''' 7 8 import numpy as np 9 from scipy.stats import chisquare 10 list_observe=np.array([30,14,34,45,57,20]) 11 list_expect=np.array([20,20,30,40,60,30]) 12 13 #方法一:根據公式求解(最后根據c1的值去查表判斷) 14 c1=np.sum(np.square(list_observe-list_expect)/list_expect) 15 16 #方法二:使用scipy庫來求解 17 c2,p=chisquare(f_obs=list_observe, f_exp=list_expect) 18 ''' 19 返回NAN,無窮小 20 ''' 21 if p>0.05 or p=="nan": 22 print("H0 win,there is no difference") 23 else: 24 print("H1 win,there is difference")
2、交叉熵
通常,一個信源發送出什么符號是不確定的,衡量它的不確定性可以根據其出現的概率來度量。概率大,出現機會多,不確定性小;反之就大。
不確定性函數f必須滿足兩個條件:
1)是概率P的單調遞降函數;
2)兩個獨立符號所產生的不確定性應等於各自不確定性之和,即f(P1,P2)=f(P1)+f(P2),這稱為可加性。
交叉熵在CNN分類中經常用到,用來作為預測值和真實標簽值的距離度量。經過卷積操作后,最后一層出來的特征經過softmax函數后會變成一個概率向量,我們可以看作為是概率分布q, 而真實標簽我們可以看作是概率分布p, 因此真實分布p和預測分布q的交叉熵就是我們要求的loss損失值,即
在python中的實現:
1 import numpy as np 2 import tensorflow as tf 3 4 fea=np.asarray([6.5,4.2,7.4,3.5],np.float32) 5 label=np.array([1,0,0,0]) 6 7 #方法一:根據公式求解 8 def softmax(x): 9 return np.exp(x)/np.sum(np.exp(x),axis=0) 10 loss1=-np.sum(label*np.log(softmax(fea))) 11 12 #方法二:調用tensorflow深度學習框架求解 13 sess=tf.Session() 14 logits=tf.Variable(fea) 15 labels=tf.Variable(label) 16 sess.run(tf.global_variables_initializer()) 17 loss2=sess.run(tf.losses.softmax_cross_entropy(labels,logits)) 18 sess.close()
3、相對熵(relative entropy)
又稱為KL散度(Kullback–Leibler divergence,簡稱KLD),信息散度(information divergence),信息增益(information gain)。
相對熵是交叉熵與信息熵的差值。即
相對熵=交叉熵-信息熵
KL(p||q)=H(p,q)-H(p)
表示用分布q模擬真實分布p相比用p模擬p,所需的額外信息。
相對熵(KL散度)有兩個主要的性質。如下
(1)盡管 KL 散度從直觀上是個度量或距離函數,但它並不是一個真正的度量或者距離,因為它不具有對稱性,即
(2)相對熵具有非負性
總結一下:
信息熵公式:
交叉熵公式:
相對熵公式:
三者的關系:
在python中的實現:
1 import numpy as np 2 import scipy.stats 3 4 p=np.asarray([0.65,0.25,0.07,0.03]) 5 q=np.array([0.6,0.25,0.1,0.05]) 6 7 #方法一:根據公式求解 8 kl1=np.sum(p*np.log(p/q)) 9 10 #方法二:調用scipy包求解 11 kl2=scipy.stats.entropy(p, q)
4、js散度(Jensen-Shannon)
因為kl散度不具對稱性,因此js散度在kl散度的基礎上進行了改進:
現有兩個分布p1和p2,其JS散度公式為:
在python中的實現:
1 import numpy as np 2 import scipy.stats 3 4 p=np.asarray([0.65,0.25,0.07,0.03]) 5 q=np.array([0.6,0.25,0.1,0.05]) 6 7 M=(p+q)/2 8 9 #方法一:根據公式求解 10 js1=0.5*np.sum(p*np.log(p/M))+0.5*np.sum(q*np.log(q/M)) 11 12 #方法二:調用scipy包求解 13 js2=0.5*scipy.stats.entropy(p, M)+0.5*scipy.stats.entropy(q, M)
1、f 散度(f-divergence)
KL-divergence 的壞處在於它是無界的。事實上KL-divergence 屬於更廣泛的 f-divergence 中的一種。
如果P和Q被定義成空間中的兩個概率分布,則f散度被定義為:
一些通用的散度,如KL-divergence, Hellinger distance, 和total variation distance,都是f散度的一種特例。只是f函數的取值不同而也。
在python中的實現 :
1 import numpy as np 2 import scipy.stats 3 4 p=np.asarray([0.65,0.25,0.07,0.03]) 5 q=np.array([0.6,0.25,0.1,0.05]) 6 7 def f(t): 8 return t*np.log(t) 9 10 #方法一:根據公式求解 11 f1=np.sum(q*f(p/q)) 12 13 #方法二:調用scipy包求解 14 f2=scipy.stats.entropy(p, q)
2、Hellinger distance
1 定義
1.1 度量理論
為了從度量理論的角度定義Hellinger距離,我們假設P和Q是兩個概率測度,並且它們對於第三個概率測度λ來說是絕對連續的,則P和Q的Hellinger距離的平方被定義如下:
這里的dP / dλ 和 dQ / dλ分別是P和Q的Radon–Nikodym微分。這里的定義是與λ無關的,因此當我們用另外一個概率測度替換λ時,只要P和Q關於它絕對連續,那么上式就不變。為了簡單起見,我們通常把上式改寫為:
1.2 基於Lebesgue度量的概率理論
為了在經典的概率論框架下定義Hellinger距離,我們通常將λ定義為Lebesgue度量,此時dP / dλ 和 dQ / dλ就變為了我們通常所說的概率密度函數。如果我們把上述概率密度函數分別表示為 f 和 g ,那么可以用以下的積分形式表示Hellinger距離:
上述等式可以通過展開平方項得到,注意到任何概率密度函數在其定義域上的積分為1。
根據柯西-施瓦茨不等式(Cauchy-Schwarz inequality),Hellinger距離滿足如下性質:
1.3 離散概率分布
對於兩個離散概率分布 P=(p1,p2,...,pn)和 Q=(q1,q2,...,qn),它們的Hellinger距離可以定義如下:
上式可以被看作兩個離散概率分布平方根向量的歐式距離,如下所示:
也可以寫成:
在python中的實現:
1 import numpy as np 2 3 p=np.asarray([0.65,0.25,0.07,0.03]) 4 q=np.array([0.6,0.25,0.1,0.05]) 5 6 #方法一: 7 h1=1/np.sqrt(2)*np.linalg.norm(np.sqrt(p)-np.sqrt(q)) 8 9 #方法二: 10 h2=np.sqrt(1-np.sum(np.sqrt(p*q)))
3、巴氏距離(Bhattacharyya Distance)
在統計中,Bhattacharyya距離測量兩個離散或連續概率分布的相似性。它與衡量兩個統計樣品或種群之間的重疊量的Bhattacharyya系數密切相關。Bhattacharyya距離和Bhattacharyya系數以20世紀30年代曾在印度統計研究所工作的一個統計學家A. Bhattacharya命名。同時,Bhattacharyya系數可以被用來確定兩個樣本被認為相對接近的,它是用來測量中的類分類的可分離性。
對於離散概率分布 p和q在同一域 X,巴氏距離被定義為:
其中BC(p,q)是Bhattacharyya系數:
對於連續概率分布,Bhattacharyya系數被定義為:
從公式可以看出,Bhattacharyya系數BC(P,Q)可以和前面的Hellinger距離聯系起來,此時Hellinger距離可以被定義為:
因此,求得巴氏系數之后,就可以求得巴氏距離和Hellinger距離。
在python中的實現:
1 import numpy as np 2 3 p=np.asarray([0.65,0.25,0.07,0.03]) 4 q=np.array([0.6,0.25,0.1,0.05]) 5 6 BC=np.sum(np.sqrt(p*q)) 7 8 #Hellinger距離: 9 h=np.sqrt(1-BC) 10 11 #巴氏距離: 12 b=-np.log(BC)
4、MMD距離(Maximum mean discrepancy)
最大均值差異(Maximum mean discrepancy),度量在再生希爾伯特空間中兩個分布的距離,是一種核學習方法。兩個隨機變量的距離為:
其中k(.)是映射,用於把原變量映射到高維空間中。X,Y表示兩種分布的樣本,F表示映射函數集。
基於兩個分布的樣本,通過尋找在樣本空間上的映射函數K,求不同分布的樣本在K上的函數值的均值,通過把兩個均值作差可以得到兩個分布對應於K的mean discrepancy。尋找一個K使得這個mean discrepancy有最大值,就得到了MMD。最后取MMD作為檢驗統計量(test statistic),從而判斷兩個分布是否相同。如果這個值足夠小,就認為兩個分布相同,否則就認為它們不相同。更加簡單的理解就是:求兩堆數據在高維空間中的均值的距離。
近年來,MMD越來越多地應用在遷移學習中。在遷移學習環境下訓練集和測試集分別取樣自分布p和q,兩類樣本集不同但相關。我們可以利用深度神經網絡的特征變換能力,來做特征空間的變換,直到變換后的特征分布相匹配,這個過程可以是source domain一直變換直到匹配target domain。匹配的度量方式就是MMD。
在python中的實現,根據核函數不同,公式可能不一樣,根據公式編程即可。
5、Wasserstein distance
Wasserstein 距離,也叫Earth Mover's Distance,推土機距離,簡稱EMD,用來表示兩個分布的相似程度。
Wasserstein distance 衡量了把數據從分布“移動成”分布時所需要移動的平均距離的最小值(類似於把一堆土從一個形狀移動到另一個形狀所需要做的功的最小值)
EMD是2000年IJCV期刊文章《The Earth Mover's Distance as a Metric for Image Retrieval》提出的一種直方圖相似度量(作者在之前的會議論文中也已經提到,不過鑒於IJCV的權威性和完整性,建議參考這篇文章)。
假設有兩個工地P和Q,P工地上有m堆土,Q工地上有n個坑,現在要將P工地上的m堆土全部移動到Q工地上的n個坑中,所做的最小的功。
每堆土我們用一個二元組來表示(p,w),p表示土堆的中心,w表示土的數量。則這兩個工地可表示為:
每個土堆中心pi到每個土坑中心qj都會有一個距離dij,則構成了一個m*n的距離矩陣。
那么問題就是我們希望找到一個流(flow),當然也是個矩陣[fij],每一項fij代表從pi到qj的流動數量,從而最小化整體的代價函數:
問題描述清楚了:就是把P中的m個坑的土,用最小的代價搬到Q中的n個坑中,pi到qj的兩個坑的距離由dij來表示。fij是從pi搬到qj的土的量;dij是pi位置到qj位置的代價(距離)。要最小化WORK工作量。EMD是把這個工作量歸一化以后的表達,即除以對fij的求和。
EMD公式:
更多關於EMD的理解請參考:
http://blog.csdn.net/zhangping1987/article/details/25368183
在python中的實現:調用opencv
1 import numpy as np 2 import cv 3 4 #p、q是兩個矩陣,第一列表示權值,后面三列表示直方圖或數量 5 p=np.asarray([[0.4,100,40,22], 6 [0.3,211,20,2], 7 [0.2,32,190,150], 8 [0.1,2,100,100]],np.float32) 9 q=np.array([[0.5,0,0,0], 10 [0.3,50,100,80], 11 [0.2,255,255,255]],np.float32) 12 pp=cv.fromarray(p) 13 qq=cv.fromarray(q) 14 emd=cv.CalcEMD2(pp,qq,cv.CV_DIST_L2)
最后計算出來的emd:
1 emd = 160.542770