В нашей повседневной жизни мы сталкиваемся с понятием расстояния в различных формах и контекстах. Независимо от того, путешествуем ли мы по оживленному городу, исследуем просторы вселенной или даже созерцаем эмоциональное пространство между собой и другими, расстояние играет фундаментальную роль в формировании нашего опыта и понимания мира. Но знаете ли вы, что расстояние можно воспринимать и измерять множеством способов, каждый из которых предлагает уникальное понимание отношений между объектами, идеями и людьми?

Я объясню и дам код от простого к сложному в зависимости от моих предпочтений 🙂

Евклидово расстояние. Евклидово расстояние — это широко используемый показатель расстояния, который измеряет расстояние по прямой между двумя точками в многомерном пространстве. В двумерном пространстве евклидово расстояние представляет собой длину прямой линии, соединяющей две точки на декартовой плоскости. В трехмерном пространстве он измеряет расстояние между двумя точками в трехмерной системе координат. Формула евклидова расстояния получена из теоремы Пифагора.

import numpy as np

def euclidean_distance(point1, point2):
    """Calculate the Euclidean distance between two points."""
    return np.sqrt(np.sum((point1 - point2) ** 2))

Косинусное расстояние. Косинусное расстояние — это метрика сходства, используемая для количественной оценки угла между двумя векторами в многомерном пространстве. Он измеряет косинус угла между векторами, показывая, насколько они похожи или различны. он превосходен в разреженных данных, интенсивных величинах, текстовых данных, неявной обратной связи (системы рекомендаций). 1- косинусное сходство есть косинусное расстояние.

import numpy as np

def cosine_distance(point1, point2):
    """Calculate the cosine distance between two points."""
    return 1 - np.dot(point1, point2) / (np.sqrt(np.dot(point1, point1)) * np.sqrt(np.dot(point2, point2)))

Манхэттенское расстояние. Манхэттенское расстояние — это показатель расстояния, который вычисляет расстояние между двумя точками в прямолинейном пространстве, похожем на сетку. Математически манхэттенское расстояние представляет собой сумму абсолютных разностей между координатами двух точек. по сравнению с манхэттенским расстоянием, евклидово расстояние рассчитывает расстояние по прямой между двумя точками с учетом как горизонтальных, так и вертикальных перемещений, в то время как манхэттенское расстояние измеряет расстояние в пространстве, похожем на сетку, с учетом только горизонтальных и вертикальных перемещений. Манхэттенское расстояние менее чувствительно к многомерным данным, поскольку оно суммирует абсолютные различия, а не возводит их в квадрат, как евклидово расстояние. Кроме того, манхэттенское расстояние более интерпретируемо, представляя общее количество блоков, которые нужно пройти в пространстве, похожем на сетку, чтобы добраться до места назначения. Выбор между двумя показателями требует компромиссов; Евклидово расстояние одинаково обрабатывает все направления, что делает его подходящим для случаев с диагональными движениями, в то время как манхэттенское расстояние более эффективно с точки зрения вычислений и лучше подходит для сценариев с сетчатыми движениями или многомерными данными.

import numpy as np

def manhattan_distance(point1, point2):
    """Calculate the Manhattan distance between two points."""
    return np.sum(np.abs(point1 - point2))

Сходство Жаккара. Расстояние Жаккара – это показатель расстояния, который количественно определяет различие между двумя наборами на основе уникальности их элементов. Он рассчитывается как 1 минус подобие Жаккара, которое представляет собой размер пересечения множеств, деленный на размер их объединения. Расстояние Жаккара напрямую связано со сходством наборов, поскольку измеряет, насколько наборы отличаются от идентичных. Эта метрика расстояния находит широкое применение при анализе данных с категориальными признаками или бинарными данными, где наличие или отсутствие элементов имеет большее значение, чем их фактические значения. Например, он используется при анализе текста для схожести документов, где документы представлены в виде наборов слов. В рекомендательных системах расстояние Жаккара помогает идентифицировать похожих пользователей или элементы на основе их общих предпочтений или характеристик. Это больше подходит, чем другие показатели, при работе с данными, которые могут быть эффективно представлены в виде наборов, особенно когда данные не имеют непрерывного характера.

def jaccard_distance(set1, set2):
    intersection = len(set1.intersection(set2))
    union = len(set1.union(set2))
    return 1 - (intersection / union)

Расстояние по гаверсинусу. Расстояние по гаверсинусу — это формула, используемая для расчета кратчайшего расстояния между двумя точками на поверхности Земли, если предположить, что Земля представляет собой идеальную сферу. Он специально разработан для измерения расстояний по дуге большого круга, что делает его пригодным для географических приложений и систем GPS. В отличие от других показателей расстояния, расстояние Хаверсуса учитывает кривизну Земли, что делает его более точным для больших расстояний и вблизи полюсов. Он преодолевает проблемы, связанные с простыми вычислениями евклидова расстояния на плоских поверхностях, которые могут привести к значительным ошибкам применительно к искривленной поверхности Земли. Таким образом, расстояние по гаверсинусу является важным инструментом для точной оценки расстояний в географических расчетах и ​​навигационных системах, предполагающих дальние путешествия.

from math import radians, sin, cos, sqrt, atan2

def haversine_distance(lat1, lon1, lat2, lon2):
    """Calculate the haversine distance given latitude and longitude"""
    R = 6371.0  # Earth radius in kilometers

    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])

    dlat = lat2 - lat1
    dlon = lon2 - lon1

    a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))

    return R * c

Расстояние Хэмминга. Расстояние Хэмминга — это метрика, используемая для измерения различий между двумя строками одинаковой длины путем подсчета количества позиций, в которых различаются соответствующие символы. Его простота и эффективность делают его ценным инструментом в различных областях, где преобладают двоичные данные, включая телекоммуникации, анализ последовательности ДНК и устойчивые к ошибкам алгоритмы сопоставления. Например, на картинке ниже, считая слева, различия в двух двоичных кодах встречаются 3 раза.

def hamming_distance(str1, str2):
    return sum(c1 != c2 for c1, c2 in zip(str1, str2))

Расстояние Минковского.Расстояние Минковского — это метрика расстояния, которая обобщает как евклидово, так и манхэттенское расстояния. Он измеряет расстояние между двумя точками в многомерном пространстве по следующей формуле:

где 𝑥𝑖 и 𝑦𝑖 — координаты двух точек, а 𝑝 — параметр, определяющий поведение расстояния. Когда 𝑝=2, оно становится евклидовым расстоянием, а когда 𝑝=1 — манхэттенским расстоянием. Значение 𝑝 определяет «порядок» расстояния Минковского. Для 𝑝›1 расстояние подчеркивает большие различия между координатами, что делает его чувствительным к выбросам. Для 𝑝‹1 он подчеркивает небольшие различия, делая его устойчивым к выбросам. Таким образом, расстояние Минковского можно адаптировать к различным распределениям данных, регулируя значение 𝑝, что позволяет использовать различные поведения расстояния, соответствующие конкретным характеристикам данных и требованиям анализа.

import numpy as np

def minkowski_distance(x, y, p):
    return np.sum(np.abs(x - y) ** p) ** (1 / p)

Расстояние Чебышева. Расстояние Чебышева, также называемое нормой L∞, представляет собой метрику расстояния, которая измеряет максимальную разницу по любому измерению между двумя точками. Представьте, что вы идете по шахматной доске, где вы можете двигаться по горизонтали, вертикали или диагонали на один шаг. Расстояние Чебышева говорит нам максимальное количество шагов, которое нам нужно, чтобы добраться до места назначения. Это полезно в таких сценариях, как поиск кратчайшего пути на шахматной доске или обнаружение выбросов в данных, когда мы хотим определить экстремальные значения, которые наиболее далеки от остальных. Таким образом, расстояние Чебышева помогает нам найти наибольшую разницу и полезно в играх, анализе сеток и обнаружении необычных вещей в данных.

В шахматах все три дистанции используются следующим образом; расстояние между клетками на шахматной доске для ладей измеряется манхэттенским расстоянием. Короли и ферзи используют расстояние Чебышева. Слоны используют манхэттенское расстояние (между клетками одного цвета) на шахматной доске, повернутой на 45 градусов, т. е. с ее диагоналями в качестве координатных осей. Чтобы добраться с одного поля на другое, только королям требуется количество ходов, равное расстоянию (евклидову расстоянию), ладьям, ферзям и слонам требуется один или два хода. ("источник")

import numpy as np

def chebyshev_distance(x, y):
    return np.max(np.abs(x - y))

Расстояние Серенсена-Дайса. Расстояние Серенсена, также известное как коэффициент Серенсена-Дайса, представляет собой меру сходства между наборами. Он вычисляет несходство между двумя наборами на основе доли общих элементов по отношению к общему количеству элементов в обоих наборах. Это особенно полезно в задачах сегментации и кластеризации изображений, где помогает выявить сходство между областями или объектами на изображениях.

Представьте, что у вас есть два набора игрушек. Расстояние Серенсена, или коэффициент Серенсена-Дайса, поможет вам выяснить, насколько похожи два набора. Он подсчитывает, сколько игрушек одинаковы в обоих наборах, а затем делит это число на общее количество игрушек в обоих наборах. Результат показывает, насколько похожи или различны два набора.

Разница между расстоянием Соренсена и сходством Жаккара заключается в том, как они измеряют сходство. Оба используют количество общих игрушек между наборами, но расстояние Соренсена также учитывает общее количество игрушек в каждом наборе, тогда как сходство Жаккара рассматривает только пропорцию общих игрушек. Таким образом, они похожи, но имеют небольшую разницу в том, как они измеряют сходство между наборами.

def sorensen_distance(set1, set2):
    intersection = len(set1.intersection(set2))
    return 1 - (2 * intersection) / (len(set1) + len(set2))