最近了解了幾個類似度分析相關的算法,整理一下。html
曼哈頓距離又叫城市街區距離,形象的理解一下就是你要從城市的一個地方到另外一個地方,怎麼計算你行駛的距離。以下圖,想象一下,兩個點之間是無數的高樓大廈。。。算法
那麼怎麼計算這兩個點的距離呢?segmentfault
放在座標系裏,咱們很快就能算出這兩個點的曼哈頓距離:(如下代碼均爲 Haskell 風格的僞代碼)ide
-- 假設:A (x1, y1), B (x2, y2) d = abs(x1 - x2) + abs(y1 - y2)
這是二維平面上兩個點的計算方式,咱們再擴展一下到 N 維世界:idea
-- 假設:A (x1, x2, ..., xn), B (y1, y2, ..., yn), A/B 的座標集用列表表示 d = sum $ zipWith (\x y -> abs(x - y)) A B
這個距離若是放在二維世界來看的話,說的就是兩點之間的直線距離:spa
至於這個距離的計算,都已經算是常識了:code
-- A (x1, y1), B (x2, y2) d = sqrt ((x1 - x2)^2 + (y1 - y2)^2)
脫離二維到 N 維:htm
-- A (x1, x2, ..., xn), B (y1, y2, ..., yn), A/B 的座標集用列表表示 d = sqrt $ sum $ zipWith (\x y -> (x - y)^2) A B
餘弦類似度,是指經過夾角的餘弦大小來判斷兩個數據集的差別程度blog
(41, 43), B (82, 86) -> 向量 l (x1, y1)ip
(43, 41), D (86, 82) -> 向量 m (x2, y2)
-- l 和 m 的夾角餘弦計算 cosLM = (x1 * x2 + y1 * y2) / (sqrt (x1^2 + y1^2) * sqrt (x2^2 + y2^2))
升級到 N 維空間後:
-- l (x1, x2, ..., xn), m (y1, y2, ..., yn), l/m 用列表表示 cosLM = (sum $ zipWith (*) l m) / ((sqrt $ sum $ zipWith (*) l l) * (sqrt $ sum $ zipWith (*) m m))
餘弦值的取值範圍是 [-1, 1],該值越大,表示兩個向量的夾角越小,數據越類似。兩個向量方向重合時,值爲1,相反時值爲 -1。
不少人用餘弦類似度來比較文本是否類似,好比:
http://www.ruanyifeng.com/blo...
https://segmentfault.com/q/10...
https://www.zhihu.com/questio...
看完上面兩個連接裏面的回答,我再說說個人理解。
皮爾遜相關係數,是要在作餘弦類似度計算以前,先把數據進行一次「中心化」
與上面的餘弦類似度的計算對比一下,發現分子分母都多剪了一個平均值。
爲何要減這個平均值呢?
當咱們在大量數據中挖掘信息時,不少數據可能在不一樣維度上會有不一樣狀況的缺失,那咱們在計算類似度時怎麼處理這些缺失呢?皮爾遜相關係數的方式是,把這些缺失都當作 0 ,而後讓全部其餘維度減去該向量個維度的平均值
pearson xs ys = (n * sumXY - sumX * sumY) / sqrt ( (n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY) ) where n = fromIntegral (length xs) sumX = sum xs sumY = sum ys sumX2 = sum $ zipWith (*) xs xs sumY2 = sum $ zipWith (*) ys ys sumXY = sum $ zipWith (*) xs ys
類似度算法太多了,先簡單介紹一下這幾個。如今有了這幾個錘子,我要去項目裏找找有沒有合適的釘子了 ? ? ?