Mahalanobis Distance
Last updated
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Function to generate points on a plane
def generate_plane_points(mean, normal, n=20, noise_level=0.001):
# Generate random points
points = np.random.rand(n, 3)
# Adjust points to lie on a given plane
for i in range(n):
points[i] = points[i] - np.dot(points[i] - mean, normal) * normal
# Add some noise
points[i] += np.random.normal(scale=noise_level, size=3)
return points
# Function to calculate Mahalanobis distance
def mahalanobis_distance(mu1, mu2, sigma1, sigma2):
cov_inv = np.linalg.inv(sigma1 + sigma2)
delta = mu1 - mu2
return np.sqrt(np.dot(np.dot(delta.T, cov_inv), delta))
# Function to plot planes
def plot_planes(plane1, plane2, ax):
ax.scatter(plane1[:,0], plane1[:,1], plane1[:,2], color='blue', alpha=0.5)
ax.scatter(plane2[:,0], plane2[:,1], plane2[:,2], color='red', alpha=0.5)
# Define two planes
mean1 = np.array([0, 0, 0])
normal1 = np.array([1, 0, 0])
plane1 = generate_plane_points(mean1, normal1)
mean2 = np.array([1, 0, 0])
normal2 = np.array([-1, 0, 0])
plane2 = generate_plane_points(mean2, normal2)
# Calculate means and covariances
mu1 = np.mean(plane1, axis=0)
sigma1 = np.cov(plane1, rowvar=False)
mu2 = np.mean(plane2, axis=0)
sigma2 = np.cov(plane2, rowvar=False)
# Calculate Mahalanobis distance before transformation
distance_before = mahalanobis_distance(mu1, mu2, sigma1, sigma2)
print("Mahalanobis Distance Before Transformation:", distance_before)
# Apply transformation to second plane (e.g., rotation)
theta = np.radians(90) # Rotation angle around z axis
rotation_matrix = np.array([
[np.cos(theta), -np.sin(theta), 0],
[np.sin(theta), np.cos(theta), 0],
[0, 0, 1]
])
plane2_transformed = np.dot(plane2 - mu2, rotation_matrix) + mu2
# Recalculate mean and covariance for the transformed plane
mu2_transformed = np.mean(plane2_transformed, axis=0)
sigma2_transformed = np.cov(plane2_transformed, rowvar=False)
# Calculate Mahalanobis distance after transformation
distance_after = mahalanobis_distance(mu1, mu2_transformed, sigma1, sigma2_transformed)
print("Mahalanobis Distance After Transformation:", distance_after)
# Visualization
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
plot_planes(plane1, plane2_transformed, ax)
ax.set_title("Mahalanobis Distance Between Two Planes")
plt.show()