はじめに
先日、Xでこのようなポストを見かけた。
データサイエンスをする上で見かける距離や類似度などをJuliaで算出するためのコードを練習したからまとめようと思う。
コード内容
まずは必要なパッケージを追加する。
using Distances, Statistics, StringDistances
データは適当に用意。
x = [1,2,3]
y = [4,5,6]
今回、算出する距離やらは以下の通り。
- ユークリッド距離
- マンハッタン距離
- キャンベラ距離
- チェビシェフ距離
- ミンコフスキー距離
- コサイン類似度
- ピアソン相関
- スピアマン相関
- マラノビス距離
- 標準化ユークリッド距離
- カイ二乗距離
- ジェンセン―シャノン距離
- レーベンシュタイン距離
- ハミング距離
- ジャッカード係数
- ダイス係数
ではいってみよう~!
ユークリッド距離
euclidean_distance = euclidean(x,y)
マンハッタン距離
manhattan_distance = cityblock(x,y)
キャンベラ距離
function calculate_canberra_distance(x, y)
return sum(abs.(x - y) ./ (abs.(x) + abs.(y)))
end
canberra_distance = calculate_canberra_distance(x, y)
チェビシェフ距離
chebyshev_distance = chebyshev(x,y)
ミンコフスキー距離
p = 3
minkowski_distance = minkowski(x,y,p)
コサイン類似度
cosine_similarity = 1 - cosine_dist(x,y)
ピアソン相関
pearson_correlation = cor(x,y)
スピアマン相関
function rank_data(data)
sorted = sortperm(data)
ranks = similar(sorted)
for (i, ix) in enumerate(sorted)
ranks[ix] = i
end
return ranks
end
function spearman_correlation(x, y)
rx = rank_data(x)
ry = rank_data(y)
return cor(rx, ry)
end
spearman_corr = spearman_correlation(x, y)
追記
スピアマン相関を算出する方法として、上記関数内の算出方法に少し誤りがあり、データによっては同順位データの順位付けのアルゴリズムが異なるため、結果が変わってしまうので、以下のコードで算出する方がよさそうです(コメントありがとうございました!)。
using StatsBase
corspearman(x, y)
または
cor(tiedrank(x), tiedrank(y))
マラノビス距離
Σ = cov([x y], dims=2)
mahalanobis_distance = mahalanobis(x,y,Σ)
標準化ユークリッド距離
std_euclidean_distance = sqeuclidean(x,y) / length(x)
カイ二乗距離
chi_squared_distance = sum((x-y).^2 ./ (x+y))
ジェンセン―シャノン距離
function kl_divergence(x, y)
result = 0.0
for i in 1:length(x)
if x[i] != 0 && y[i] != 0
result += x[i] * log(x[i] / y[i])
end
end
return result
end
function my_js_divergence(x, y)
m = 0.5 * (x + y)
return 0.5 * (kl_divergence(x, m) + kl_divergence(y, m))
end
function js_distance(x, y)
return sqrt(my_js_divergence(x,y))
end
distance = js_distance(x, y)
レーベンシュタイン距離
levenshtein_distance = evaluate(Levenshtein(), "string1", "string2")
ハミング距離
function calculate_hamming_distance(x, y)
if length(x) == length(y)
return evaluate(Hamming(), x, y)
end
end
hamming_distance = calculate_hamming_distance(x, y)
ハミング距離の算出では、Distances.jl
とStringDistances.jl
どちらでもHamming関数
を呼び出すため、どちらか一方のみをインポートしてから算出すること。
ジャッカード係数
jaccard_index = 1 - jaccard(x,y)
ダイス係数
dice_coefficient = 2 * sum(min.(x,y)) / sum(x+y)
いくつかはパッケージを使用しても算出できなかったので、自作関数で算出してまふ。
まとめ
他に簡単な算出方法あれば教えていただけると助かります~(・ω・)ノ
それでは!!!