DEV Community

Cover image for Расстояния и сходство в машинном обучении
Samuel Akopyan
Samuel Akopyan

Posted on

Расстояния и сходство в машинном обучении

Как только мы представили данные в виде чисел и векторов, возникает естественный вопрос: как понять, что два объекта похожи или, наоборот, сильно отличаются? Машинное обучение почти всегда сводится к сравнению. Этот текст ближе к тому или к этому, этот пользователь похож на другого или нет, это изображение относится к классу A или B и т.д.

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

В этой главе мы разберем три ключевых инструмента: евклидово расстояние, скалярное произведение (dot product) и косинусное сходство (cosine similarity). Они лежат в основе k-NN, линейных моделей, рекомендательных систем, поиска по текстам и эмбеддингов.

Евклидово расстояние – "обычная" геометрия

Евклидово расстояние – это расстояние "по линейке" между двумя точками в пространстве.

Если у нас есть два вектора

x=(x1,x2,,xn) x = (x_1, x_2, \dots, x_n)

y=(y1,y2,,yn) y = (y_1, y_2, \dots, y_n)

то евклидово расстояние между ними определяется формулой:

d(x,y)=i=1n(xiyi)2 d(x, y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2}

Если n=1n = 1 , это расстояние между точками на прямой, если n=2n = 2 , то это расстояние между точками на плоскости, при n=3n = 3 – уже в трёхмерном пространстве и т.д. Если n=100n = 100 или, например, 768768 , то по сути геометрия остается той же самой, просто ее уже нельзя нарисовать напрямую, так как человек не в состоянии воспринимать изображения в пространстве, имеющем больше, чем 3 измерения.


Рис. 1. Евклидово расстояние в 2D

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

Как вы наверняка запомнили из предыдущей главы – евклидово расстояние чувствительно к масштабу и поэтому перед использованием такого расстояния данные часто нормализуют или стандартизируют, если признаки имеют разные масштабы.

Интуитивно: два объекта похожи, если расстояние между их векторами маленькое.

PHP-пример

function euclideanDistance(array $a, array $b): float {
    $n = count($a);

    if ($n !== count($b)) {
        throw new InvalidArgumentException('Vectors must have the same length');
    }

    $sum = 0.0;

    for ($i = 0; $i < $n; $i++) {
        $diff = $a[$i] - $b[$i];
        $sum += $diff ** 2;
    }

    return sqrt($sum);
}
Enter fullscreen mode Exit fullscreen mode

Пример:

$a = [1, 2, 3];
$b = [4, 6, 3];

$distance = euclideanDistance($a, $b);
echo $distance;

// Результат: 5
// Объяснение: √((1 - 4)^2 + (2 - 6)^2 + (3 - 3)^2) = √(9 + 16 + 0) = √(25) = 5
Enter fullscreen mode Exit fullscreen mode

Этот код уже можно использовать в простейшем k-NN классификаторе: мы просто ищем объекты с минимальным расстоянием среди имеющейся выборки.

Скалярное произведение (dot product) – мера согласованности

Скалярное произведение двух векторов определяется как:

xy=i=1nxiyi x \cdot y = \sum_{i=1}^{n} x_i y_i

На первый взгляд это просто сумма произведений соответствующих координат и выглядит всего лишь как удобный способ перемножить два набора чисел. Однако у скалярного произведения есть и геометрический смысл:

xy=xycos(θ) x \cdot y = |x| |y| \cos(\theta)

где θ\theta – угол между векторами, а длина (модуль) вектора, определяется как:

x=xx |x| = \sqrt{x \cdot x}


Рис. 1.3-2. Два вектора и угол между ними

Скалярное произведение становится больше, когда одновременно выполняются два условия:

  1. Векторы смотрят почти в одну сторону\ Если угол θθ между ними маленький, их направления совпадают – вклад направления максимален ( cosθ1cosθ≈1 ).
  2. Векторы длинные\ Чем больше длины векторов, тем больше итоговое значение (произведение модулей xy|x| |y| велико), даже при фиксированном направлении.

Проще говоря:

скалярное произведение = насколько направления совпадают × насколько векторы "крупные"

Это ключевой момент: скалярное произведение учитывает и направление, и масштаб. Из-за этого скалярное произведение смешивает два разных эффекта:

  • направление (похожи ли векторы)
  • масштаб (насколько они большие)

Поэтому его нельзя считать "чистой" мерой сходства. Два вектора могут быть идеально сонаправлены, но если один из них в 10 раз длиннее, скалярное произведение вырастет в 10 раз – хотя направление осталось тем же.

В машинном обучении это используется осознанно. В линейных моделях большое скалярное произведение означает сильную активацию. В нейросетях и attention-механизмах оно интерпретируется как мера важности или связи.


Рис. 1.3-3. Скалярное произведение как проекция одного вектора на другой

Если представить xyx \cdot y геометрически, то это можно интерпретировать как длину проекции одного вектора на направление другого, умноженную на длину второго вектора.

PHP-пример

function dotProduct(array $a, array $b): float {
    $n = count($a);

    if ($n !== count($b)) {
        throw new InvalidArgumentException('Vectors must have the same length');
    }

    $sum = 0.0;

    for ($i = 0; $i < $n; $i++) {
        $sum += $a[$i] * $b[$i];
    }

    return $sum;
}
Enter fullscreen mode Exit fullscreen mode

Пример:

$a = [1, 2, 3];
$b = [4, 5, 6];

$result = dotProduct($a, $b);
echo $result;

// Результат: 32
// Объяснение: (1 * 4) + (2 * 5) + (3 * 6) = 4 + 10 + 18 = 32
Enter fullscreen mode Exit fullscreen mode

Косинусное сходство – сравнение направлений

Как мы уже упоминали в прошлой главе - косинусное сходство отвечает на вопрос: насколько векторы направлены в одну сторону, независимо от их длины.

Оно определяется следующей формулой (нетрудно заметить, что она выводится из формулы скалярного произведения векторов):

ParseError: KaTeX parse error: Expected 'EOF', got '_' at position 14: \text{cosine_̲sim}(x, y) = \f…

Результат лежит в диапазоне от -1 до 1, и хотя в практических задачах NLP и эмбеддингов отрицательные значения встречаются редко, но математически они возможны:

  • 1 – одинаковое направление
  • 0 – ортогональные векторы
  • -1 – противоположные направления


Рис. 1.3-4. Один и тот же угол, разные длины векторов

На этой картинке важно увидеть: длины разные, но угол одинаковый – значит, косинусное сходство одинаковое.

Это делает косинусное сходство идеальной мерой для текстов и эмбеддингов, где длина вектора часто отражает не смысл, а масштаб (длина текста, частота слов).

PHP-пример

function cosineSimilarity(array $a, array $b): float {
    $dot = dotProduct($a, $b);
    $normA = sqrt(dotProduct($a, $a));
    $normB = sqrt(dotProduct($b, $b));

    if ($normA == 0 || $normB == 0) {
       throw new InvalidArgumentException('Zero vector');
    }

    return $dot / ($normA * $normB);
}
Enter fullscreen mode Exit fullscreen mode

Пример:

$a = [1, 2];
$b = [2, 1];

$similarity = cosineSimilarity($a, $b);
echo $similarity;

// Результат: 0.8
// Объяснение: 
// dot = 1 * 2 + 2 * 1 = 4
// normA = sqrt(1 * 1 + 2 * 2) = sqrt(5)
// normB = sqrt(2 * 2 + 1 * 1) = sqrt(5)
// cosine = 4 / (sqrt(5) * sqrt(5)) = 4 / 5 = 0.8
Enter fullscreen mode Exit fullscreen mode

В данном случае результат 0.8 означает, что векторы довольно похожи по направлению, но не совпадают полностью.


Ресурсы

Адаптированный материал из книги "Искусственный интеллект для PHP-разработчиков":
https://apphp.gitbook.io/ai-for-php-developers

Online Demo:
https://aiwithphp.org/books/ai-for-php-developers/examples/part-1/distances-and-similarity

Top comments (0)