Skip to content

Instantly share code, notes, and snippets.

@Quwarm
Created April 28, 2021 16:49
Show Gist options
  • Save Quwarm/979fb9af037da142895c9e5a5d2a59cd to your computer and use it in GitHub Desktop.
Save Quwarm/979fb9af037da142895c9e5a5d2a59cd to your computer and use it in GitHub Desktop.
Расстояние Махаланобиса между двумя классами
# Примечание: проверки на обратимость ковариационных матриц отсутствуют
import numpy as np
def mahalanobis(point_from, point_to, inverse_covariance_matrix):
delta = point_from - point_to
return max(np.float64(0), np.dot(np.dot(delta, inverse_covariance_matrix), delta)) ** 0.5
class_1 = np.array([[1., 1.], [2., 2.], [3., 3.], [4., 4.], [5., 5.]])
class_2 = np.array([[3., 1.], [4., 0.], [6., 0.], [6., 2.], [5., 3.]])
centroid_1 = class_1.mean(axis=0)
centroid_2 = class_2.mean(axis=0)
covariance_matrix_1 = np.cov(class_1, rowvar=False, ddof=1)
covariance_matrix_2 = np.cov(class_2, rowvar=False, ddof=1)
print("==================")
print("First variant, d_M")
inverse_covariance_matrix = np.linalg.inv(
(covariance_matrix_1 + covariance_matrix_2) / (class_1.shape[0] + class_2.shape[0] - 2))
min_ = np.inf
max_ = 0.
for point_from in class_1:
for point_to in class_2:
distance = mahalanobis(point_from, point_to, inverse_covariance_matrix)
print("d_M (", point_from, ", ", point_to, ", COV0^(-1)) = ", distance, sep='')
if distance < min_:
min_ = distance
if distance > max_:
max_ = distance
print("By centroids:", mahalanobis(centroid_1, centroid_2, inverse_covariance_matrix))
print("Min:", min_)
print("Max:", max_)
print("====================")
print("First variant, d_E-M")
inverse_covariance_matrix = np.linalg.inv(
(covariance_matrix_1 + covariance_matrix_2) / (class_1.shape[0] + class_2.shape[0] - 2)
+ np.identity(class_1.shape[1]))
min_ = np.inf
max_ = 0.
for point_from in class_1:
for point_to in class_2:
distance = mahalanobis(point_from, point_to, inverse_covariance_matrix)
print("d_E-M (", point_from, ", ", point_to, ", (COV0+E)^(-1)) = ", distance, sep='')
if distance < min_:
min_ = distance
if distance > max_:
max_ = distance
print("By centroids:", mahalanobis(centroid_1, centroid_2, inverse_covariance_matrix))
print("Min:", min_)
print("Max:", max_)
print("===================")
print("Second variant, d_M")
inverse_covariance_matrix = np.linalg.inv(covariance_matrix_1 + covariance_matrix_2)
min_ = np.inf
max_ = 0.
for point_from in class_1:
for point_to in class_2:
distance = mahalanobis(point_from, point_to, inverse_covariance_matrix)
print("d_M (", point_from, ", ", point_to, ", COV0^(-1)) = ", distance, sep='')
if distance < min_:
min_ = distance
if distance > max_:
max_ = distance
print("By centroids:", mahalanobis(centroid_1, centroid_2, inverse_covariance_matrix))
print("Min:", min_)
print("Max:", max_)
print("=====================")
print("Second variant, d_E-M")
inverse_covariance_matrix = np.linalg.inv(covariance_matrix_1 + covariance_matrix_2 + np.identity(class_1.shape[1]))
min_ = np.inf
max_ = 0.
for point_from in class_1:
for point_to in class_2:
distance = mahalanobis(point_from, point_to, inverse_covariance_matrix)
print("d_E-M (", point_from, ", ", point_to, ", (COV0+E)^(-1)) = ", distance, sep='')
if distance < min_:
min_ = distance
if distance > max_:
max_ = distance
print("By centroids:", mahalanobis(centroid_1, centroid_2, inverse_covariance_matrix))
print("Min:", min_)
print("Max:", max_)
# ==================
# First variant, d_M
# d_M ([1. 1.], [3. 1.], COV0^(-1)) = 3.7032803990902052
# d_M ([1. 1.], [4. 0.], COV0^(-1)) = 6.928203230275508
# d_M ([1. 1.], [6. 0.], COV0^(-1)) = 10.583005244258361
# d_M ([1. 1.], [6. 2.], COV0^(-1)) = 8.141603913585717
# d_M ([1. 1.], [5. 3.], COV0^(-1)) = 5.65685424949238
# d_M ([2. 2.], [3. 1.], COV0^(-1)) = 3.3806170189140654
# d_M ([2. 2.], [4. 0.], COV0^(-1)) = 6.761234037828131
# d_M ([2. 2.], [6. 0.], COV0^(-1)) = 10.25391911138649
# d_M ([2. 2.], [6. 2.], COV0^(-1)) = 7.4065607981804105
# d_M ([2. 2.], [5. 3.], COV0^(-1)) = 4.535573676110726
# d_M ([3. 3.], [3. 1.], COV0^(-1)) = 3.7032803990902052
# d_M ([3. 3.], [4. 0.], COV0^(-1)) = 6.928203230275508
# d_M ([3. 3.], [6. 0.], COV0^(-1)) = 10.141851056742198
# d_M ([3. 3.], [6. 2.], COV0^(-1)) = 6.928203230275508
# d_M ([3. 3.], [5. 3.], COV0^(-1)) = 3.7032803990902052
# d_M ([4. 4.], [3. 1.], COV0^(-1)) = 4.535573676110727
# d_M ([4. 4.], [4. 0.], COV0^(-1)) = 7.4065607981804105
# d_M ([4. 4.], [6. 0.], COV0^(-1)) = 10.25391911138649
# d_M ([4. 4.], [6. 2.], COV0^(-1)) = 6.761234037828131
# d_M ([4. 4.], [5. 3.], COV0^(-1)) = 3.3806170189140654
# d_M ([5. 5.], [3. 1.], COV0^(-1)) = 5.65685424949238
# d_M ([5. 5.], [4. 0.], COV0^(-1)) = 8.141603913585717
# d_M ([5. 5.], [6. 0.], COV0^(-1)) = 10.583005244258361
# d_M ([5. 5.], [6. 2.], COV0^(-1)) = 6.928203230275508
# d_M ([5. 5.], [5. 3.], COV0^(-1)) = 3.7032803990902052
# By centroids: 6.085110634045318
# Min: 3.3806170189140654
# Max: 10.583005244258361
# ====================
# First variant, d_E-M
# d_E-M ([1. 1.], [3. 1.], (COV0+E)^(-1)) = 1.6639694487102625
# d_E-M ([1. 1.], [4. 0.], (COV0+E)^(-1)) = 2.8062746310659863
# d_E-M ([1. 1.], [6. 0.], (COV0+E)^(-1)) = 4.425586469931062
# d_E-M ([1. 1.], [6. 2.], (COV0+E)^(-1)) = 4.050741986142523
# d_E-M ([1. 1.], [5. 3.], (COV0+E)^(-1)) = 3.361863718173964
# d_E-M ([2. 2.], [3. 1.], (COV0+E)^(-1)) = 1.3046561461068844
# d_E-M ([2. 2.], [4. 0.], (COV0+E)^(-1)) = 2.609312292213769
# d_E-M ([2. 2.], [6. 0.], (COV0+E)^(-1)) = 4.047939673813937
# d_E-M ([2. 2.], [6. 2.], (COV0+E)^(-1)) = 3.327938897420525
# d_E-M ([2. 2.], [5. 3.], (COV0+E)^(-1)) = 2.443111607405837
# d_E-M ([3. 3.], [3. 1.], (COV0+E)^(-1)) = 1.6639694487102625
# d_E-M ([3. 3.], [4. 0.], (COV0+E)^(-1)) = 2.8062746310659867
# d_E-M ([3. 3.], [6. 0.], (COV0+E)^(-1)) = 3.913968438320653
# d_E-M ([3. 3.], [6. 2.], (COV0+E)^(-1)) = 2.8062746310659863
# d_E-M ([3. 3.], [5. 3.], (COV0+E)^(-1)) = 1.6639694487102625
# d_E-M ([4. 4.], [3. 1.], (COV0+E)^(-1)) = 2.4431116074058377
# d_E-M ([4. 4.], [4. 0.], (COV0+E)^(-1)) = 3.327938897420525
# d_E-M ([4. 4.], [6. 0.], (COV0+E)^(-1)) = 4.047939673813937
# d_E-M ([4. 4.], [6. 2.], (COV0+E)^(-1)) = 2.609312292213769
# d_E-M ([4. 4.], [5. 3.], (COV0+E)^(-1)) = 1.3046561461068844
# d_E-M ([5. 5.], [3. 1.], (COV0+E)^(-1)) = 3.361863718173964
# d_E-M ([5. 5.], [4. 0.], (COV0+E)^(-1)) = 4.050741986142523
# d_E-M ([5. 5.], [6. 0.], (COV0+E)^(-1)) = 4.425586469931062
# d_E-M ([5. 5.], [6. 2.], (COV0+E)^(-1)) = 2.8062746310659867
# d_E-M ([5. 5.], [5. 3.], (COV0+E)^(-1)) = 1.6639694487102625
# By centroids: 2.348381062992392
# Min: 1.3046561461068844
# Max: 4.425586469931062
# ===================
# Second variant, d_M
# d_M ([1. 1.], [3. 1.], COV0^(-1)) = 1.3093073414159542
# d_M ([1. 1.], [4. 0.], COV0^(-1)) = 2.449489742783178
# d_M ([1. 1.], [6. 0.], COV0^(-1)) = 3.741657386773941
# d_M ([1. 1.], [6. 2.], COV0^(-1)) = 2.8784916685156974
# d_M ([1. 1.], [5. 3.], COV0^(-1)) = 1.9999999999999998
# d_M ([2. 2.], [3. 1.], COV0^(-1)) = 1.1952286093343933
# d_M ([2. 2.], [4. 0.], COV0^(-1)) = 2.3904572186687867
# d_M ([2. 2.], [6. 0.], COV0^(-1)) = 3.625307868699862
# d_M ([2. 2.], [6. 2.], COV0^(-1)) = 2.6186146828319083
# d_M ([2. 2.], [5. 3.], COV0^(-1)) = 1.6035674514745462
# d_M ([3. 3.], [3. 1.], COV0^(-1)) = 1.3093073414159542
# d_M ([3. 3.], [4. 0.], COV0^(-1)) = 2.449489742783178
# d_M ([3. 3.], [6. 0.], COV0^(-1)) = 3.58568582800318
# d_M ([3. 3.], [6. 2.], COV0^(-1)) = 2.449489742783178
# d_M ([3. 3.], [5. 3.], COV0^(-1)) = 1.3093073414159542
# d_M ([4. 4.], [3. 1.], COV0^(-1)) = 1.6035674514745462
# d_M ([4. 4.], [4. 0.], COV0^(-1)) = 2.6186146828319083
# d_M ([4. 4.], [6. 0.], COV0^(-1)) = 3.625307868699862
# d_M ([4. 4.], [6. 2.], COV0^(-1)) = 2.3904572186687867
# d_M ([4. 4.], [5. 3.], COV0^(-1)) = 1.1952286093343933
# d_M ([5. 5.], [3. 1.], COV0^(-1)) = 1.9999999999999998
# d_M ([5. 5.], [4. 0.], COV0^(-1)) = 2.8784916685156974
# d_M ([5. 5.], [6. 0.], COV0^(-1)) = 3.741657386773941
# d_M ([5. 5.], [6. 2.], COV0^(-1)) = 2.449489742783178
# d_M ([5. 5.], [5. 3.], COV0^(-1)) = 1.3093073414159542
# By centroids: 2.151411496801908
# Min: 1.1952286093343933
# Max: 3.741657386773941
# =====================
# Second variant, d_E-M
# d_E-M ([1. 1.], [3. 1.], (COV0+E)^(-1)) = 1.0408329997330663
# d_E-M ([1. 1.], [4. 0.], (COV0+E)^(-1)) = 1.892969448600091
# d_E-M ([1. 1.], [6. 0.], (COV0+E)^(-1)) = 2.91547594742265
# d_E-M ([1. 1.], [6. 2.], (COV0+E)^(-1)) = 2.362907813126304
# d_E-M ([1. 1.], [5. 3.], (COV0+E)^(-1)) = 1.755942292142123
# d_E-M ([2. 2.], [3. 1.], (COV0+E)^(-1)) = 0.9128709291752767
# d_E-M ([2. 2.], [4. 0.], (COV0+E)^(-1)) = 1.8257418583505534
# d_E-M ([2. 2.], [6. 0.], (COV0+E)^(-1)) = 2.7838821814150103
# d_E-M ([2. 2.], [6. 2.], (COV0+E)^(-1)) = 2.0816659994661326
# d_E-M ([2. 2.], [5. 3.], (COV0+E)^(-1)) = 1.35400640077266
# d_E-M ([3. 3.], [3. 1.], (COV0+E)^(-1)) = 1.0408329997330663
# d_E-M ([3. 3.], [4. 0.], (COV0+E)^(-1)) = 1.892969448600091
# d_E-M ([3. 3.], [6. 0.], (COV0+E)^(-1)) = 2.73861278752583
# d_E-M ([3. 3.], [6. 2.], (COV0+E)^(-1)) = 1.892969448600091
# d_E-M ([3. 3.], [5. 3.], (COV0+E)^(-1)) = 1.0408329997330663
# d_E-M ([4. 4.], [3. 1.], (COV0+E)^(-1)) = 1.35400640077266
# d_E-M ([4. 4.], [4. 0.], (COV0+E)^(-1)) = 2.0816659994661326
# d_E-M ([4. 4.], [6. 0.], (COV0+E)^(-1)) = 2.7838821814150103
# d_E-M ([4. 4.], [6. 2.], (COV0+E)^(-1)) = 1.8257418583505534
# d_E-M ([4. 4.], [5. 3.], (COV0+E)^(-1)) = 0.9128709291752767
# d_E-M ([5. 5.], [3. 1.], (COV0+E)^(-1)) = 1.755942292142123
# d_E-M ([5. 5.], [4. 0.], (COV0+E)^(-1)) = 2.362907813126304
# d_E-M ([5. 5.], [6. 0.], (COV0+E)^(-1)) = 2.9154759474226495
# d_E-M ([5. 5.], [6. 2.], (COV0+E)^(-1)) = 1.892969448600091
# d_E-M ([5. 5.], [5. 3.], (COV0+E)^(-1)) = 1.0408329997330663
# By centroids: 1.643167672515498
# Min: 0.9128709291752767
# Max: 2.91547594742265
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment