yuns
Mahalanobis 거리 구하기(직접 구현/scipy모듈 활용) 본문
반응형
Mahalanobis 거리 직접 계산 vs. scipy로 계산하기
데이터 간의 거리를 측정할 때 유클리디안 거리(Euclidean distance)가 가장 많이 쓰이지만, 데이터의 분포를 고려해야 할 땐 Mahalanobis 거리(Mahalanobis distance)가 훨씬 더 적합합니다.
이번 글에서는 두 가지 방식으로 Mahalanobis 거리를 계산해 보겠습니다:
- np.matmul을 이용한 수식 구현
- scipy.spatial.distance.cdist를 이용한 간단한 계산
📌 Mahalanobis 거리란?
Mahalanobis 거리는 다음과 같은 수식으로 정의됩니다:
$$
D_M(x, \mu) = \sqrt{(x - \mu)^T S^{-1} (x - \mu)}
$$
- $x$: 샘플 벡터
- $\mu$: 평균 벡터 (또는 기준 벡터)
- $S$: 공분산 행렬
- $S^{-1}$: 공분산 행렬의 역행렬
1️⃣ np.matmul을 사용한 Mahalanobis 거리 계산
import numpy as np
# 예제 데이터
x = np.array([2, 3])
mu = np.array([0, 0])
X = np.array([
[1, 2],
[2, 1],
[3, 5],
])
# 공분산 행렬 계산 및 역행렬
S = np.cov(X.T)
S_inv = np.linalg.inv(S)
# Mahalanobis 거리 수식 직접 계산
diff = x - mu
d = np.sqrt(np.matmul(np.matmul(diff.T, S_inv), diff))
print(f"Mahalanobis Distance (manual): {d}")
✅ np.matmul(A, B)은 $A\cdot B$와 동일한 행렬 곱입니다. 중첩 사용해서 수식 그대로 구현 가능합니다.
2️⃣ scipy.spatial.distance.cdist를 활용한 계산
더 간편하게 여러 벡터 간의 Mahalanobis 거리를 계산하고 싶다면, cdist 함수가 제격입니다
from scipy.spatial import distance
# X: 여러 샘플, y: 하나의 기준 벡터
X = np.array([
[1, 2],
[2, 1],
[3, 5],
])
y = np.array([[2, 3]])
# 공분산 행렬의 역행렬
VI = np.linalg.inv(np.cov(X.T))
# cdist를 이용해 Mahalanobis 거리 계산
dists = distance.cdist(X, y, metric='mahalanobis', VI=VI)
print(f"Mahalanobis Distance (cdist): \n{dists}")
## 코드로 비교
import numpy as np
import pandas as pd
# 데이터 생성
df1 = np.random.rand(100, 20)
df2 = np.random.rand(5, 20)
def mahalanobis_distance_matrix(df1, df2, cov):
"""
df1: (n, d) numpy 배열
df2: (m, d) numpy 배열
cov: (d, d) 공분산 행렬
반환값: (n, m) 거리 행렬
"""
cov_inv = np.linalg.inv(cov)
# 두 배열의 점들 간 차이 벡터 생성
diff = df1[:, np.newaxis, :] - df2[np.newaxis, :, :] # (n, m, d)
# (x - μ) @ Σ^-1
left = np.matmul(diff, cov_inv) # (n, m, d)
# (x - μ) @ Σ^-1 @ (x - μ)^T = element-wise 곱 후 축 계산
dist_sq = np.sum(left * diff, axis=2) # (n, m)
return np.sqrt(dist_sq)
# 직접 구현
cov = np.cov(np.vstack([df1, df2]).T)
print("직접 구현\t", mahalanobis_distance_matrix(df1, df2, cov))
# scipy 모듈 활용
from scipy.spatial.distance import cdist
print("scipy 모듈 활용\t", cdist(df1, df2, metric='mahalanobis'))
반응형
'머신러닝' 카테고리의 다른 글
4. 머신러닝 모델 개발 과정 - 성능평가 및 하이퍼파라미터 튜닝 (0) | 2025.03.17 |
---|---|
4. 머신러닝 모델 개발 과정 - 모델 선택 및 학습 (0) | 2025.03.16 |
4. 머신러닝 모델 개발 과정 - Feature Selection (0) | 2025.03.16 |
4. 머신러닝 모델 개발 과정 - 데이터 수집 및 전처리 (0) | 2025.03.15 |
3. 머신러닝의 주요 알고리즘 - k-최근접 이웃(KNN) (0) | 2025.03.15 |
Comments