Зачем искать похожие объекты?
При работе с моделями машинного обучения часто возникает задача: найти в данных объект, наиболее похожий на заданный. Это полезно для:
✅ Валидации предсказаний — сравнить прогноз с реальными похожими случаями
✅ Рекомендательных систем — найти похожие товары, фильмы, недвижимость
✅ Анализа выбросов — понять, насколько объект уникален
✅ Объяснения модели — показать на примере похожего объекта
Практический пример:
Вы хотите оценить квартиру 65 м², 2 комнаты, 5 этаж. Модель предсказывает 45 тыс. руб. Но насколько надежен прогноз?
Решение: Найти в данных похожую квартиру и сравнить:
- Если похожая квартира стоит 44 тыс. руб. → предсказание хорошее ✅
- Если похожая квартира стоит 60 тыс. руб. → возможно, модель ошиблась ⚠️
Концепция расстояния между объектами
Визуальная интуиция:
Представьте, что каждый объект — это точка в многомерном пространстве.
2D пространство (2 признака):
Площадь (м²)
↑
100 | • Квартира B (90, 3)
|
50 | • Квартира A (50, 1)
|
0 └────────────────────→ Комнаты
0 1 2 3
Расстояние — это то, насколько далеко объекты находятся друг от друга.
В 2D (теорема Пифагора):
# Квартира A: (50 м², 1 комната)
# Квартира B: (90 м², 3 комнаты)
Δarea = 90 - 50 = 40
Δrooms = 3 - 1 = 2
distance = √(40² + 2²) = √(1600 + 4) = √1604 ≈ 40.05
В многомерном пространстве (N измерений):
# Квартира: [площадь, комнаты, этаж, расстояние до метро]
A = [50, 1, 3, 0.5]
B = [90, 3, 5, 1.2]
distance = √[(90-50)² + (3-1)² + (5-3)² + (1.2-0.5)²]
= √[40² + 2² + 2² + 0.7²]
= √[1600 + 4 + 4 + 0.49]
= √1608.49
≈ 40.11
Это называется евклидово расстояние (Euclidean distance).
Евклидово расстояние
Формула:
Для двух объектов A и B с признаками [x₁, x₂, ..., xₙ]:
distance(A, B) = √Σ(Aᵢ - Bᵢ)²
Где:
- Σ — сумма
- Aᵢ — i-й признак объекта A
- Bᵢ — i-й признак объекта B
Пошаговое вычисление:
Шаг 1: Найти разности по каждому признаку
Δ₁ = A₁ - B₁
Δ₂ = A₂ - B₂
...
Шаг 2: Возвести в квадрат
Δ₁², Δ₂², ...
Шаг 3: Суммировать
sum = Δ₁² + Δ₂² + ...
Шаг 4: Извлечь корень
distance = √sum
Реализация в NumPy
Способ 1: Пошагово (для понимания)
import numpy as np
# Два объекта
A = np.array([50, 1, 3, 0.5])
B = np.array([90, 3, 5, 1.2])
# Шаг 1: Разности
differences = A - B
print(f"Разности: {differences}")
# [-40. -2. -2. -0.7]
# Шаг 2: Квадраты
squared = differences ** 2
print(f"Квадраты: {squared}")
# [1600. 4. 4. 0.49]
# Шаг 3: Сумма
sum_squared = squared.sum()
print(f"Сумма квадратов: {sum_squared}")
# 1608.49
# Шаг 4: Корень
distance = np.sqrt(sum_squared)
print(f"Расстояние: {distance:.2f}")
# 40.11
Способ 2: Компактно
distance = np.sqrt(((A - B)**2).sum())
print(f"Расстояние: {distance:.2f}")
Способ 3: Векторизованно (для многих объектов)
# Новый дом
new_house = np.array([65, 2, 5, 0.8])
# Массив других домов
other_houses = np.array([
[50, 1, 3, 0.5],
[90, 3, 5, 1.2],
[70, 2, 7, 0.9],
[60, 2, 4, 0.7]
])
# Вычисление расстояний до всех домов СРАЗУ
distances = np.sqrt(((other_houses - new_house)**2).sum(axis=1))
print(f"Расстояния: {distances}")
# [15.52 25.31 2.24 5.10]
# Самый близкий дом
closest_idx = distances.argmin()
print(f"Индекс ближайшего: {closest_idx}") # 2
print(f"Ближайший дом: {other_houses[closest_idx]}")
# [70 2 7 0.9]