Как вычислить евклидово расстояние (L2 норму) между векторами в NumPy?

Что такое Евклидово расстояние? Геометрическая интерпретация

Евклидово расстояние, также известное как L2 расстояние, представляет собой длину прямой линии между двумя точками в евклидовом пространстве. В двумерном пространстве (на плоскости) это соответствует теореме Пифагора: расстояние равно квадратному корню из суммы квадратов разностей координат. Геометрически, это наиболее интуитивный способ измерения расстояния «как мы видим его».

Определение L2 нормы вектора

L2 норма (или евклидова норма) вектора — это длина этого вектора, рассматриваемого как направленный отрезок, выходящий из начала координат. Формально, L2 норма вектора v = (v₁, v₂, …, vn) вычисляется как квадратный корень из суммы квадратов его компонент: ||v||₂ = √(v₁² + v₂² + … + vn²).

Связь между Евклидовым расстоянием и L2 нормой

Евклидово расстояние между двумя векторами a и b равно L2 норме разности этих векторов: distance(a, b) = ||ab||₂. Другими словами, чтобы найти расстояние между двумя точками, мы вычисляем вектор, соединяющий эти точки (разность векторов), а затем находим длину этого вектора (L2 норму).

Вычисление Евклидова расстояния между векторами в NumPy

Подготовка векторов: создание NumPy массивов

Для вычислений с векторами в Python удобно использовать библиотеку NumPy. Начнем с создания NumPy массивов, представляющих наши векторы.

import numpy as np

# Пример векторов
a: np.ndarray = np.array([1, 2, 3])
b: np.ndarray = np.array([4, 5, 6])

print(f'{a=}')
print(f'{b=}')

Реализация вычисления Евклидова расстояния вручную (с использованием NumPy операций)

Можно вычислить Евклидово расстояние вручную, используя базовые операции NumPy. Это полезно для понимания процесса.

import numpy as np


def euclidean_distance_manual(a: np.ndarray, b: np.ndarray) -> float:
    """Вычисляет евклидово расстояние между двумя векторами вручную.

    Args:
        a: Первый вектор (NumPy массив).
        b: Второй вектор (NumPy массив).

    Returns:
        Евклидово расстояние между a и b.
    """
    squared_difference: np.ndarray = (a - b) ** 2
    sum_of_squares: float = np.sum(squared_difference)
    distance: float = np.sqrt(sum_of_squares)
    return distance


a: np.ndarray = np.array([1, 2, 3])
b: np.ndarray = np.array([4, 5, 6])

distance: float = euclidean_distance_manual(a, b)
print(f'{distance=}')

Использование NumPy для эффективного расчета: np.linalg.norm

NumPy предоставляет встроенную функцию np.linalg.norm для вычисления нормы вектора, что делает код более лаконичным и эффективным.

import numpy as np


def euclidean_distance_numpy(a: np.ndarray, b: np.ndarray) -> float:
    """Вычисляет евклидово расстояние между двумя векторами, используя np.linalg.norm.

    Args:
        a: Первый вектор (NumPy массив).
        b: Второй вектор (NumPy массив).

    Returns:
        Евклидово расстояние между a и b.
    """
    distance: float = np.linalg.norm(a - b)
    return distance


a: np.ndarray = np.array([1, 2, 3])
b: np.ndarray = np.array([4, 5, 6])

distance: float = euclidean_distance_numpy(a, b)
print(f'{distance=}')
Реклама

Примеры вычисления Евклидова расстояния в NumPy

Пример 1: Расстояние между двумя векторами в 2D пространстве

import numpy as np

vector1: np.ndarray = np.array([1, 2])
vector2: np.ndarray = np.array([4, 6])
distance: float = np.linalg.norm(vector1 - vector2)
print(f'{distance=}')

Пример 2: Расстояние между векторами в многомерном пространстве (3D и выше)

import numpy as np

vector1: np.ndarray = np.array([1, 2, 3, 4])
vector2: np.ndarray = np.array([5, 6, 7, 8])
distance: float = np.linalg.norm(vector1 - vector2)
print(f'{distance=}')

Пример 3: Вычисление расстояния между набором векторов и одним вектором (broadcast)

Используя broadcasting, можно эффективно вычислить расстояния от одного вектора до нескольких других.

import numpy as np

vectors: np.ndarray = np.array([[1, 2], [3, 4], [5, 6]])
point: np.ndarray = np.array([0, 0])

distances: np.ndarray = np.linalg.norm(vectors - point, axis=1)
print(f'{distances=}')

Оптимизация вычислений Евклидова расстояния для больших данных

Векторизация и избежание циклов: почему это важно?

Векторизация операций NumPy позволяет избежать явных циклов, что значительно ускоряет вычисления, особенно для больших наборов данных. NumPy использует оптимизированные библиотеки (например, BLAS, LAPACK) для выполнения векторных и матричных операций.

Использование np.linalg.norm с указанием оси (axis) для пакетной обработки

Как показано в примере 3, указание аргумента axis в np.linalg.norm позволяет вычислить нормы для каждой строки (или столбца) в многомерном массиве, что эквивалентно пакетной обработке.

Рассмотрение альтернативных библиотек (SciPy) для специфических случаев

Для очень больших наборов данных и специфических требований к производительности стоит рассмотреть библиотеку SciPy, которая предоставляет дополнительные оптимизированные функции для линейной алгебры и вычислений расстояний.

Заключение

Краткое резюме методов вычисления Евклидова расстояния в NumPy

Мы рассмотрели ручной метод вычисления Евклидова расстояния, а также более эффективный способ с использованием np.linalg.norm. Оба метода приводят к одинаковому результату, но np.linalg.norm предпочтительнее из-за его скорости и лаконичности.

Области применения Евклидова расстояния (кластеризация, машинное обучение)

Евклидово расстояние широко используется в различных областях, включая:

  • Кластеризацию (например, k-means)
  • Машинное обучение (например, k-ближайших соседей)
  • Поиск похожих объектов
  • Рекомендательные системы

Дополнительные ресурсы и ссылки для дальнейшего изучения


Добавить комментарий