1. 歐氏距離
歐式距離歐氏距離是最常見也是最常用的一種距離計算方式,也叫歐幾里得距離、
距離。 函數形式如下:
表示兩個
維向量,
為兩個
維向量的歐式距離。
python實現
import numpy as np
x = np.random.random(10)
y = np.random.random(10)
# n維向量
#方法一:根據公式求解
d1 = np.sqrt(np.sum(np.square(x - y)))
#方法二:根據np.linalg.norm求解
d2 = np.linalg.norm(x-y)
#方法三:根據scipy庫求解
from scipy.spatial.distance import pdist
X = np.vstack([x,y]) #將x,y兩個一維數組合并成一個2D數組 ;[[x1,x2,x3...],[y1,y2,y3...]]
d3 = pdist(X) #d2=np.sqrt(x1-y1)
# m * n維矩陣歐氏距離計算, 一行代表一個樣本,一列代表一個特征,計算對應樣本間歐氏距離
from sklearn.metrics import pairwise_distances
from scipy.spatial import distance_matrix
from scipy.spatial.distance import cdist
d1 = pairwise_distances(x.reshape(-1, 10), y.reshape(-1, 10)) # 運行時間次之 占cpu多
d2 = distance_matrix(x.reshape(-1, 10), y.reshape(-1, 10))
d3 = cdist(x.reshape(-1, 10), y.reshape(-1, 10)) # 運行時間最短 占cpu少,建議使用
2. 曼哈頓距離
曼哈頓距離也稱為城市街區距離、
距離,顧名思義,假設在曼哈頓街區從P點到Q點,我們不能直接穿過高樓大廈走直線的距離,而是表示走過的街道的距離。在二維坐標上的表示,即兩個點在標準坐標系上的絕對軸距之和。具體公式表示:
表示兩個
維向量,
為兩個
維向量的曼哈頓距離。
python實現
import numpy as np
x = np.array([1,2,3])
y = np.array([4,5,6])
d1 = np.sum(np.abs(x-y))
d2 = np.linalg.norm(x-y, ord=1)
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d3=pdist(X,'cityblock')
3. 閔氏距離
閔氏距離,全名閔可夫斯基距離,它不是一種距離,而是一組距離的定義,是對多個距離度量公式的概括性的表述。函數表達:
p取1或2時的明氏距離是最為常用的:
p = 2即為歐氏距離。
p = 1時則為曼哈頓距離。
當p取無窮時的極限情況下,可以得到切比雪夫距離
P為不同值時,等距離組成的形狀:
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
#方法一:根據公式求解,p=2
d1=np.sqrt(np.sum(np.square(x-y)))
d2 = np.linalg.norm(x-y, ord=2)
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d3=pdist(X,'minkowski',p=2)
4. 切比雪夫距離
切比雪夫距離,也叫
度量,在國際象棋中,國王可以直行、橫行、斜行,所以國王走一步可以移動到相鄰的8個方格中的任意一個。國王從格子(x1,y1)走到格子(x2,y2)最少需要多少步,這個距離就叫切比雪夫距離。表示為:
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
d1=np.max(np.abs(x-y))
d2 = np.linalg.norm(x-y,ord=np.inf)
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d3=pdist(X,'chebyshev')
閔氏距離,包括曼哈頓距離、歐氏距離和切比雪夫距離都存在明顯的缺點:將各個分量的量綱(scale),也就是“單位”當作相同的看待,量綱不同時,通常需要對數據做正規化;
沒有考慮各個分量的分布(期望,方差等)可能是不同的;
各個維度必須是互相獨立的,也就是“正交”的。
綠色表示兩點之間歐氏距離,紅色、藍色和黃色代表等價的曼哈頓距離。
5. 標準化歐氏距離
標準化歐氏距離是針對簡單歐氏距離的缺點而作的一種改進方案。標準歐氏距離的思路:既然數據各維分量的分布不一樣,那么我先將各個分量都“標準化”到均值、方差相等。通過統計學知識,假設樣本集X的均值(mean)為m,標準差(standard deviation)為s,那么X的“標準化變量”表示為:
那么標準化歐式距離公式為:
如果將方差的倒數看成是一個權重,也可稱之為加權歐式距離。
python實現
import numpy as np
from scipy.spatial.distance import pdist
x=np.random.random(10)
y=np.random.random(10)
X=np.vstack([x,y])
sk=np.var(X,axis=0,ddof=1)
d1=np.sqrt(((x - y) ** 2 /sk).sum())
d2 = np.linalg.norm((x - y) /np.sqrt(sk), ord=2)
d3 = pdist(X, 'seuclidean',[0.5,1])
6. 馬氏距離
閔氏距離比較直觀,但是它與數據的分布無關,具有一定的局限性,標準化歐氏距離涉及到數據分布,但沒有考慮到數據的相關性,而馬氏距離在計算兩個樣本之間的距離時,考慮到了樣本所在分布造成的影響,主要是因為:
1)不同維度的方差不同,進而不同維度對距離的重要性不同。
2)不同維度可能存在相關性,影響距離的度量。
定義:假設有
個樣本向量
,協方差矩陣記為
,均值記為向量
,則其中樣本向量
到
的馬氏距離表示為:
其中,樣本向量
與
之間的馬氏距離定義為:
若協方差矩陣
是單位矩陣(各個樣本向量之間獨立同分布),則公式就成了:
即:歐氏距離
若協方差矩陣是對角矩陣,公式變成了標準化歐氏距離。
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
#馬氏距離要求樣本數要大于維數,否則無法求協方差矩陣
#此處進行轉置,表示10個樣本,每個樣本2維
X=np.vstack([x,y])
XT=X.T
#方法一:根據公式求解
S=np.cov(X) #兩個維度之間協方差矩陣
SI = np.linalg.inv(S) #協方差矩陣的逆矩陣
#馬氏距離計算兩個樣本之間的距離,此處共有10個樣本,兩兩組合,共有45個距離。
n=XT.shape[0]
d1=[]
for i in range(0,n):
for j in range(i+1,n):
delta=XT[i]-XT[j]
d=np.sqrt(np.dot(np.dot(delta,SI),delta.T))
d1.append(d)
#方法二:根據scipy庫求解
from scipy.spatial.distance import pdist
d2=pdist(XT,'mahalanobis')
7. 漢明距離
兩個等長字符串s1與s2之間的漢明距離定義為將其中一個變為另外一個所需要作的最小替換次數。
例如:
還可以用簡單的匹配系數來表示兩點之間的相似度,即:匹配字符數/總字符數。
python實現
import numpy as np
from scipy.spatial.distance import pdist
x=np.random.random(10)>0.5
y=np.random.random(10)>0.5
x=np.asarray(x,np.int32)
y=np.asarray(y,np.int32)
#方法一:根據公式求解
d1=np.mean(x!=y)
#方法二:根據scipy庫求解
X=np.vstack([x,y])
d2=pdist(X,'hamming')
8. 編輯距離
漢明距離可以度量兩個相同長度的字符串之間的相似度,如果比較的兩個字符串長度不同,則不僅要進行替換,還要進行插入與刪除的操作,這種情況下下,通常使用更加復雜的編輯距離進行相似度判斷,即通過字符編輯(插入、刪除或替換),將字符串A轉換成字符串B所需要的最少操作數。
python實現
import numpy as np
# 動態規劃
def edit_distance(str1, str2):
len1 = len(str1)
len2 = len(str2)
dp = np.zeros((len1 + 1, len2 + 1))
for i in range(len1 + 1):
dp[i][0] = i
for j in range(len2 + 1):
dp[0][j] = j
for i in range(1, len1 + 1):
for j in range(1, len2 + 1):
delta = 0 if str1[i - 1] == str2[j - 1] else 1
dp[i][j] = min(dp[i - 1][j - 1] + delta, min(dp[i - 1][j] + 1, dp[i][j - 1] + 1))
return dp[len1][len2]
9. DTW距離
DTW(Dynamic Time Warping,動態時間歸整)是一種衡量兩個長度不等的時間序列間相似度的方法,主要應用在語音識別領域,識別兩段語音是否表示同一個單詞。
大部分情況下,需要比較的兩個序列在整體上具有非常相似的形狀,但是這些形狀并不是對一一對應的。所以我們在比較他們的相似度之前,需要將其中一個(或者兩個)序列在時間軸下warping扭曲,以達到更好的對齊。而DTW就是實現這種warping扭曲的一種有效方法。DTW通過把時間序列進行延伸和縮短,來計算兩個時間序列性之間的相似性。
python實現
def cal_dtw_distance(X, Y): # dtw距離計算
sign_len_N, num_features = X.shape # 獲取T的行數features,和列數N
sign_len_M, num_features = Y.shape[1] # 獲取R的列數
eudist_matrix = np.zeros((sign_len_N, sign_len_M))
for i in range(num_features): # 生成原始距離矩陣
eudist_matrix += pow(np.transpose([X[i, :]])-Y[i, :], 2)
eudist_matrix = np.sqrt(eudist_matrix)
# 動態規劃
dtw_distance_matrix = np.zeros(np.shape(eudist_matrix))
dtw_distance_matrix[0, 0] = eudist_matrix[0, 0]
for n in range(1, sign_len_N):
dtw_distance_matrix[n, 0] = eudist_matrix[n, 0] + dtw_distance_matrix[n-1, 0]
for m in range(1, sign_len_M):
dtw_distance_matrix[0, m] = eudist_matrix[0, m] + dtw_distance_matrix[0, m-1]
# 三個方向最小
for n in range(1, sign_len_N):
for m in range(1, sign_len_M):
dtw_distance_matrix[n, m] = eudist_matrix[n, m] + \
min([dtw_distance_matrix[n-1, m], dtw_distance_matrix[n-1, m-1], dtw_distance_matrix[n, m-1]]) # 動態計算最短距離
n = sign_len_N-1
m = sign_len_M-1
k = 1
warping_path = [[sign_len_N-1, sign_len_M-1]]
while n+m != 0: # 匹配路徑過程
if n == 0:
m = m-1
elif m == 0:
n = n-1
else:
number = np.argmin([dtw_distance_matrix[n-1, m], dtw_distance_matrix[n-1, m-1], dtw_distance_matrix[n, m-1]])
if number == 0:
n = n-1
elif number == 1:
n = n-1
m = m-1
elif number == 2:
m = m-1
k = k+1
warping_path.append([n, m])
warping_path = np.array(warping_path)
dtw_distance = dtw_distance_matrix[-1, -1] # 序列距離
return dtw_distance, warping_path
10. 杰卡德相似系數
python實現
import numpy as np
from scipy.spatial.distance import pdist
x=np.random.random(10)>0.5
y=np.random.random(10)>0.5
x=np.asarray(x,np.int32)
y=np.asarray(y,np.int32)
#方法一:根據公式求解
up=np.double(np.bitwise_and((x != y),np.bitwise_or(x != 0, y != 0)).sum())
down=np.double(np.bitwise_or(x != 0, y != 0).sum())
d1=(up/down)
#方法二:根據scipy庫求解
X=np.vstack([x,y])
d2=pdist(X,'jaccard')
11. 余弦距離
余弦距離,也稱為余弦相似度,是用向量空間中兩個向量夾角的余弦值作為衡量兩個個體間差異的大小的度量方法。余弦值越接近1,就表明夾角越接近0度,也就表示兩個向量越相似。
余弦距離計算公式:
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
#方法一:根據公式求解
d1=np.dot(x,y)/(np.linalg.norm(x)*np.linalg.norm(y))
#方法二:根據scipy庫求解
from scipy.spatial.distance import pdist
X=np.vstack([x,y])
d2=1-pdist(X,'cosine')
12. 皮爾遜相關系數
皮爾遜相關系數(Pearson correlation),也叫相關系數,相比于余弦弦相似度只與向量方向有關,受向量的平移影響,皮爾遜相關系數具有平移不變性和尺度不變性,在夾角余弦公式中,如果將 x 平移到 x+1, 余弦值就會改變。皮爾遜相關系數值在-1.0到1.0之間,接近0的表示無相關性,接近1或者-1被稱為具有強相關性,負數表示負相關。
如果將夾角余弦公式寫成:
則皮爾遜相關系數則可表示為:
因此,皮爾遜相關系數可以看作中心化后變量的余弦距離。
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
#方法一:根據公式求解
x_=x-np.mean(x)
y_=y-np.mean(y)
d1=np.dot(x_,y_)/(np.linalg.norm(x_)*np.linalg.norm(y_))
#方法二:根據numpy庫求解
X=np.vstack([x,y])
d2=np.corrcoef(X)[0][1]
#方法三:利用pandas庫求解
import pandas as pd
X1 = pd.Series(x)
Y1 = pd.Series(y)
d3 = X1.corr(Y1, method="pearson")
d4 = X1.cov(Y1) / (X1.std() * Y1.std())
13. 斯皮爾曼相關性系數
python實現
import numpy as np
x=np.random.random(10)
y=np.random.random(10)
X1 = pd.Series(x)
Y1 = pd.Series(y)
n=x1.count()
x1.index=np.arange(n)
y1.index=np.arange(n)
#分部計算
d=(x1.sort_values().index-y1.sort_values().index)**2
dd=d.to_series().sum()
d1=1-n*dd/(n*(n**2-1))
d2 = X1.corr(y1,method='spearman')
14. 肯德爾相關性系數
python實現
import pandas as pd
import numpy as np
#原始數據
x= pd.Series([3,1,4,2,5,3])
y= pd.Series([1,2,3,2,1,1])
d = x.corr(y,method="kendall")
15. 布雷柯蒂斯距離(Bray Curtis Distance)
Bray Curtis距離主要用于生態學和環境科學,計算坐標之間的距離。該距離取值在[0,1]之間。它也可以用來計算樣本之間的差異。
python實現
import numpy as np
from scipy.spatial.distance import pdist
x=np.array([11,0,7,8,0])
y=np.array([24,37,5,18,1])
#方法一:根據公式求解
up=np.sum(np.abs(y-x))
down=np.sum(x)+np.sum(y)
d1=(up/down)
#方法二:根據scipy庫求解
X=np.vstack([x,y])
d2=pdist(X,'braycurtis')
16. 卡方檢驗
卡反應統計樣本的實際觀測值與理論推斷值之間的偏離程度,常用來檢驗某一種觀測分布是不是符合某一類典型的理論分布(如二項分布,正態分布等)。如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若兩個值完全相等時,卡方值就為0,表明理論值完全符合。
# -*- coding: utf-8 -*-
'''
卡方公式(o-e)^2 / e
期望值和收集到數據不能低于5,o(observed)觀察到的數據,e(expected)表示期望的數據
(o-e)平方,最后除以期望的數據e
'''
import numpy as np
from scipy.stats import chisquare
list_observe=np.array([30,14,34,45,57,20])
list_expect=np.array([20,20,30,40,60,30])
#方法一:根據公式求解(最后根據c1的值去查表判斷)
c1=np.sum(np.square(list_observe-list_expect)/list_expect)
#方法二:使用scipy庫來求解
c2,p=chisquare(f_obs=list_observe, f_exp=list_expect)
'''
返回NAN,無窮小
'''
if p>0.05 or p=="nan":
print("H0 win,there is no difference")
else:
print("H1 win,there is difference")
17. 信息熵
import numpy as np
import tensorflow as tf
fea=np.asarray([6.5,4.2,7.4,3.5],np.float32)
label=np.array([1,0,0,0])
#方法一:根據公式求解
def softmax(x):
return np.exp(x)/np.sum(np.exp(x),axis=0)
loss1=-np.sum(label*np.log(softmax(fea)))
#方法二:調用tensorflow深度學習框架求解
sess=tf.Session()
logits=tf.Variable(fea)
labels=tf.Variable(label)
sess.run(tf.global_variables_initializer())
loss2=sess.run(tf.losses.softmax_cross_entropy(labels,logits))
sess.close()
18. 相對熵(relative entropy)
又稱KL散度(Kullback–Leibler divergence,簡稱KLD),信息散度(information divergence),信息增益(information gain),相對熵是交叉熵與信息熵的差值。
python實現
import numpy as np
import scipy.stats
p=np.asarray([0.65,0.25,0.07,0.03])
q=np.array([0.6,0.25,0.1,0.05])
#方法一:根據公式求解
kl1=np.sum(p*np.log(p/q))
#方法二:調用scipy包求解
kl2=scipy.stats.entropy(p, q)
參考:距離度量以及python實現(一、二、三、四):距離度量以及python實現(一) - denny402 - 博客園?www.cnblogs.com
HMM學習筆記_1(從一個實例中學習DTW算法):HMM學習筆記_1(從一個實例中學習DTW算法) - tornadomeet - 博客園?www.cnblogs.com
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态