机器学习中有哪些距离度量方式
點擊標題下「AI搞事情」可快速關注
本文涉及到的距離度量方法:
歐氏距離
曼哈頓距離
閔氏距離
切比雪夫距離
標準化歐氏距離
馬氏距離
漢明距離
編輯距離
DTW距離
杰卡德相似系數
余弦距離
皮爾遜相關系數
斯皮爾曼相關系數?
肯德爾相關性系數
布雷柯蒂斯距離
卡方檢驗
交叉熵
相對熵
Ⅰ
歐式距離
歐式距離歐氏距離是最常見也是最常用的一種距離計算方式,也叫歐幾里得距離、距離。函數形式如下:
表示兩個維向量,為兩個維向量的歐式距離。
python實現
import numpy as npx = 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 pdistX = 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_distancesfrom scipy.spatial import distance_matrixfrom scipy.spatial.distance import cdistd1 = 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少,建議使用Ⅱ
曼哈頓距離
曼哈頓距離也稱為城市街區距離、距離,顧名思義,假設在曼哈頓街區從P點到Q點,我們不能直接穿過高樓大廈走直線的距離,而是表示走過的街道的距離。在二維坐標上的表示,即兩個點在標準坐標系上的絕對軸距之和。具體公式表示:
表示兩個維向量,為兩個維向量的曼哈頓距離。
python實現
import numpy as npx = 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 pdistX=np.vstack([x,y])d3=pdist(X,'cityblock')Ⅲ
閔氏距離
閔氏距離,全名閔可夫斯基距離,它不是一種距離,而是一組距離的定義,是對多個距離度量公式的概括性的表述。函數表達:
p取1或2時的閔氏距離是最為常用的:
p = 2即為歐氏距離。
p = 1時則為曼哈頓距離。
當p取無窮時的極限情況下,可以得到切比雪夫距離。
P為不同值時,等距離組成的形狀:
python實現
import numpy as npx=np.random.random(10)y=np.random.random(10)#方法一:根據公式求解,p=2d1=np.sqrt(np.sum(np.square(x-y)))d2 = np.linalg.norm(x-y, ord=2)from scipy.spatial.distance import pdistX=np.vstack([x,y])d3=pdist(X,'minkowski',p=2)Ⅳ
切比雪夫距離
切比雪夫距離,也叫度量,在國際象棋中,國王可以直行、橫行、斜行,所以國王走一步可以移動到相鄰的8個方格中的任意一個。國王從格子(x1,y1)走到格子(x2,y2)最少需要多少步,這個距離就叫切比雪夫距離。表示為:
python實現
import numpy as npx=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 pdistX=np.vstack([x,y])d3=pdist(X,'chebyshev')閔氏距離,包括曼哈頓距離、歐氏距離和切比雪夫距離都存在明顯的缺點:
將各個分量的量綱(scale),也就是“單位”當作相同的看待,量綱不同時,通常需要對數據做正規化;
沒有考慮各個分量的分布(期望,方差等)可能是不同的;
各個維度必須是互相獨立的,也就是“正交”的。
綠色表示兩點之間歐氏距離,紅色、藍色和黃色代表等價的曼哈頓距離。
Ⅴ
標準化歐氏距離
標準化歐氏距離是針對簡單歐氏距離的缺點而作的一種改進方案。標準歐氏距離的思路:既然數據各維分量的分布不一樣,那么我先將各個分量都“標準化”到均值、方差相等。通過統計學知識,假設樣本集X的均值(mean)為m,標準差(standard deviation)為s,那么X的“標準化變量”表示為:
那么標準化歐式距離公式為:
如果將方差的倒數看成是一個權重,也可稱之為加權歐式距離。
python實現
import numpy as npfrom scipy.spatial.distance import pdistx=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])Ⅵ
馬氏距離
閔氏距離比較直觀,但是它與數據的分布無關,具有一定的局限性,標準化歐氏距離涉及到數據分布,但沒有考慮到數據的相關性,而馬氏距離在計算兩個樣本之間的距離時,考慮到了樣本所在分布造成的影響,主要是因為:
1)不同維度的方差不同,進而不同維度對距離的重要性不同。
2)不同維度可能存在相關性,影響距離的度量。
定義:假設有個樣本向量,協方差矩陣記為,均值記為向量,則其中樣本向量到的馬氏距離表示為:
其中,樣本向量與之間的馬氏距離定義為:
若協方差矩陣是單位矩陣(各個樣本向量之間獨立同分布),則公式就成了:
即:歐氏距離
若協方差矩陣是對角矩陣,公式變成了標準化歐氏距離。
python實現
import numpy as npx=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 pdistd2=pdist(XT,'mahalanobis')Ⅶ
漢明距離
兩個等長字符串s1與s2之間的漢明距離定義為將其中一個變為另外一個所需要作的最小替換次數。
例如:
還可以用簡單的匹配系數來表示兩點之間的相似度,即:匹配字符數/總字符數。
python實現
import numpy as npfrom scipy.spatial.distance import pdistx=np.random.random(10)>0.5y=np.random.random(10)>0.5x=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')Ⅷ
編輯距離
漢明距離可以度量兩個相同長度的字符串之間的相似度,如果比較的兩個字符串長度不同,則不僅要進行替換,還要進行插入與刪除的操作,這種情況下下,通常使用更加復雜的編輯距離進行相似度判斷,即通過字符編輯(插入、刪除或替換),將字符串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]Ⅸ
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Ⅹ
杰卡德相似系數
杰卡德相似性系數主要用于計算符號度量或布爾值度量的樣本間的相似度,等于樣本集交集個數和樣本集并集個數的比值。
python實現
import numpy as npfrom scipy.spatial.distance import pdistx=np.random.random(10)>0.5y=np.random.random(10)>0.5x=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')XI
余弦距離
余弦距離,也稱為余弦相似度,是用向量空間中兩個向量夾角的余弦值作為衡量兩個個體間差異的大小的度量方法。余弦值越接近1,就表明夾角越接近0度,也就表示兩個向量越相似。
余弦距離計算公式:
python實現
import numpy as npx=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 pdistX=np.vstack([x,y])d2=1-pdist(X,'cosine')Ⅻ
皮爾遜相關系數
皮爾遜相關系數(Pearson correlation),也叫相關系數,相比于余弦弦相似度只與向量方向有關,受向量的平移影響,皮爾遜相關系數具有平移不變性和尺度不變性,在夾角余弦公式中,如果將 x 平移到 x+1, 余弦值就會改變。皮爾遜相關系數值在-1.0到1.0之間,接近0的表示無相關性,接近1或者-1被稱為具有強相關性,負數表示負相關,不過皮爾遜相關系數只能衡量兩個隨機變量間的線性相關性。
如果將夾角余弦公式寫成:
則皮爾遜相關系數則可表示為:
因此,皮爾遜相關系數可以看作中心化后變量的余弦距離。
python實現
import numpy as npx=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 pdX1 = pd.Series(x)Y1 = pd.Series(y)d3 = X1.corr(Y1, method="pearson") d4 = X1.cov(Y1) / (X1.std() * Y1.std())XIII
斯皮爾曼相關系數
斯皮爾曼相關系數又稱斯皮爾曼秩相關系數,是利用兩變量的秩次大小作線性相關分析,是根據原始數據的排序位置進行求解,對原始變量的分布不作要求,屬于非參數統計方法,適用范圍要廣些。
計算過程:先對兩個變量(X, Y)的數據進行排序,然后記下排序以后的位置(X’, Y’),(X’, Y’)的值就稱為秩次,秩次的差值就是上面公式中的di,n是變量中數據的個數。
python實現
import numpy as npx=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)**2dd=d.to_series().sum()d1=1-n*dd/(n*(n**2-1))d2 = X1.corr(y1,method='spearman') ?XIV
肯德爾相關性系數
肯德爾相關性系數又稱肯德爾秩相關系數,它所計算的對象是分類變量,因此它需要的數據集必須是分類變量。
Nc表示主客觀評價值中一致的值的個數,Nd則表示了主觀評估值和客觀評估值不一樣的個數。
適用案例:評委對選手的評分(優、中、差等),我們想看兩個(或者多個)評委對幾位選手的評價標準是否一致;或者醫院的尿糖化驗報告,想檢驗各個醫院對尿糖的化驗結果是否一致。
python實現
import pandas as pdimport 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") ?XV
布雷柯蒂斯距離
布雷柯蒂斯距離(Bray Curtis Distance)主要用于生態學和環境科學,計算坐標之間的距離。該距離取值在[0,1]之間。它也可以用來計算樣本之間的差異。
python實現
import numpy as npfrom scipy.spatial.distance import pdistx=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')XVI
卡方檢驗
卡方檢驗應用統計樣本的實際觀測值與理論推斷值之間的偏離程度,常用來檢驗某一種觀測分布是不是符合某一類典型的理論分布(如二項分布,正態分布等)。如果卡方值越大,二者偏差程度越大;反之,二者偏差越小;若兩個值完全相等時,卡方值就為0,表明理論值完全符合。
python實現
# -*- coding: utf-8 -*-'''卡方公式(o-e)^2 / e期望值和收集到數據不能低于5,o(observed)觀察到的數據,e(expected)表示期望的數據(o-e)平方,最后除以期望的數據e'''import numpy as npfrom 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")XVII
交叉熵
如果一個隨機變量X 服從 p(x)分布,q(x)用于近似p(x)的概率分布,那么隨機變量和模型q之間的交叉熵定義為:
交叉熵在CNN分類中經常用到,用來作為預測值和真實標簽值的距離度量。經過卷積操作后,最后一層出來的特征經過softmax函數后會變成一個概率向量,我們可以看作為是概率分布q, 而真實標簽我們可以看作是概率分布p, 因此真實分布p和預測分布q的交叉熵就是我們要求的loss損失值。
python實現
import numpy as npimport tensorflow as tffea=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()XVIII
相對熵
又稱KL散度(Kullback–Leibler divergence,簡稱KLD),信息散度(information divergence),信息增益(information gain),相對熵是交叉熵與信息熵的差值。
python實現
import numpy as npimport scipy.statsp=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實現(一、二、三、四): https://www.cnblogs.com/denny402/p/7027954.html
從一個實例中學習DTW算法
聊聊統計學三大相關性系數
長按二維碼關注我們
有趣的靈魂在等你
留言
總結
以上是生活随笔為你收集整理的机器学习中有哪些距离度量方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【opencv系列02】OpenCV4.
- 下一篇: 【opencv系列01】OpenCV4.