機械学習

距離尺度

ユークリッド・マンハッタン・コサインの測っているものを整理し、スケール、次元、Minkowski距離の p から距離尺度を選ぶノート。

  • B|標準
  • 機械学習

数式の記号で止まったら 記号の読み方 (∂・⊙・転置・上付き添字を、読み方から)

ひとことで言うと

距離尺度は、2つのベクトルを「どれだけ異なるか」という数に変換する規則です。ユークリッド距離は直線的な離れ方、マンハッタン距離は各軸の差の合計、コサイン類似度は大きさを捨てた向きの近さを測ります。したがって、同じデータでも尺度を変えると近い点の順序が変わります。

地図上の2地点を比べるとき、直線距離で測るか、碁盤目の道路を曲がりながら進む距離で測るかで答えが変わります。文書ベクトルのように「何個あるか」より「どの語の比率か」を見たい場合は、方角だけを比べるコンパスのようなコサインを使います。

なぜ必要か

距離は、特徴量を同じ「近さ」の軸に乗せるために必要です。たとえば年齢と年収をそのまま比較すると、数値の桁が大きい年収の差が結果を支配します。これはアルゴリズムの問題ではなく、距離に入力する座標系の問題です。標準化や正規化を先に行うと、各特徴量の寄与を意図した範囲に近づけられます。

選択の出発点は、何を同じとみなすかです。位置の差を全方向で素直に測るならユークリッド、各特徴の差を足し合わせたいならマンハッタン、ベクトルの長さより方向や比率を比べたいならコサインです。scikit-learn の pairwise_distances は、サンプル間または2つの配列間の距離行列を計算し、これらを指定できます。

確認すること距離の選択に与える影響
単位・桁大きい特徴量が差の計算を支配するため、前処理を先に検討する
比較したい意味位置の差か、軸ごとのずれか、ベクトルの向きかを決める
次元数成分ごとの差が積み上がるため、高次元では尺度と前処理の影響を再確認する

仕組み

ベクトル x,y∈Rd\mathbf{x},\mathbf{y}\in\mathbb{R}^d の各成分を xi,yix_i,y_i とします。Minkowski距離は

dp(x,y)=(∑i=1d∣xi−yi∣p)1/pd_p(\mathbf{x},\mathbf{y})=\left(\sum_{i=1}^{d}|x_i-y_i|^p\right)^{1/p}

で、pp は差をどのように集約するかを決める正のパラメータです。p=2p=2 がユークリッド距離、p=1p=1 がマンハッタン距離です。前者は差の二乗を強く効かせ、後者は各軸の差を均等に足します。pp を大きくすると最大の成分差に重心が移り、極限では Chebyshev 距離になります。

距離として扱うには、非負性 d(x,y)≥0d(\mathbf{x},\mathbf{y})\geq0、同一性(距離0と同じ点が同値)、対称性、三角不等式を満たす必要があります。コサイン類似度は

s(x,y)=xTy∥x∥2 ∥y∥2s(\mathbf{x},\mathbf{y})=\frac{\mathbf{x}^{\mathsf{T}}\mathbf{y}}{\lVert\mathbf{x}\rVert_2\,\lVert\mathbf{y}\rVert_2}

で、2本のベクトルの角度の余弦です。これは類似度であって距離そのものではありません。必要なら 1−s1-s を距離らしい値として使えますが、距離の4条件を自動的に満たすと決めつけないでください。

尺度主に測るもの選ぶ判断
ユークリッド直線的な位置の差スケールを揃え、差の大きさを素直に比較する
マンハッタン各軸の差の総和軸ごとのずれを足したい、極端な差の影響を弱めたい
コサインベクトルの向き文書など、長さより構成比を比較する

試験でどう問われるか

問われ方正解に寄る条件引っかけ
公式と尺度の対応p=2p=2 はユークリッド、p=1p=1 はマンハッタンコサインを Minkowski の一種とする
コサインの解釈ノルムで正規化した内積で、向きを比べる値の大きさや距離そのものを比べる
距離の公理非負・同一・対称・三角不等式を区別する「似ているほど距離が大きい」とする
前処理の影響単位とスケールを揃えてから距離を計算する特徴量の桁を無視して尺度だけ選ぶ

実装で確かめる

同じ2点でも、尺度が見ている差が違うことを NumPy で確認します。コサインは 1 から類似度を引いた値として別に表示します。

import numpy as np

x = np.array([3.0, 4.0])
y = np.array([0.0, 4.0])
diff = x - y
euclidean = np.linalg.norm(diff, ord=2)
manhattan = np.linalg.norm(diff, ord=1)
cosine = x @ y / (np.linalg.norm(x) * np.linalg.norm(y))
print(euclidean, manhattan, cosine, 1 - cosine)

出力は 3.0 3.0 0.8 0.19999999999999996 です。ここでは差が1軸だけなので2つの距離が一致しますが、一般には pp によって値も順位も変わります。ゼロベクトルではコサインの分母が0になるため、実装前に入力条件を確認します。

取り違えやすいもの

用語切り分け
距離小さいほど近い。4つの公理を満たすかが基準です
類似度大きいほど近い。コサインはこの側です
ユークリッド距離二乗和の平方根。大きな成分差を相対的に強く反映します
マンハッタン距離絶対値の和。各軸の差をそのまま積み上げます
正規化距離尺度ではなく、入力のスケールを整える前処理です

想起チェック

ユークリッド距離とマンハッタン距離を Minkowski 距離で対応づける

p=2p=2 がユークリッド距離、p=1p=1 がマンハッタン距離です。

コサイン類似度が距離ではない理由を説明する

コサインは正規化内積として定義された類似度で、値が大きいほど近いという別の向きを持ちます。距離の4公理を満たすかは別途確認が必要です。

距離計算の前にスケールを確認する理由を答える

特徴量の単位や桁が違うと、距離の合計を一部の特徴量が支配します。比較したい意味に合わせて標準化や正規化を検討します。

出典