Косинусное сходство и кластеризация k-means на Python
Обучение без учителя находит структуру в данных без меток. Косинусное сходство измеряет, насколько похожи два вектора, а k-means группирует точки в кластеры вокруг центров, которые находит сам.
Суть простыми словами
Обучение без учителя находит структуру в данных без меток. Косинусное сходство измеряет, насколько похожи два вектора, а k-means группирует точки в кластеры вокруг центров, которые находит сам.
Измерьте, насколько похожи два вектора, с помощью косинусного сходства и сгруппируйте неразмеченные данные методом k-means.
Главные идеи
- Косинусное сходство игнорирует длину и сравнивает только направление, что подходит для текстов и эмбеддингов.
- Для k-means нужно заранее знать число кластеров k.
- Начальные центры могут изменить результат, поэтому k-means часто запускают несколько раз.
- Кластеры находятся только по данным; метки не нужны.
Когда это использовать?
- Понять, что происходит внутри нейронных сетей и библиотек ИИ.
- Разобраться в идее до того, как реализовать её в соответствующих задачах.
- Подготовиться к курсам по машинному обучению, собеседованиям и проектам.
Посмотрите в действии
Нажимайте Шаг, чтобы чередовать два шага k-means, или Запуск, чтобы повторять их, пока ничего не изменится. Поворачивайте векторы справа, чтобы менять их косинусное сходство.
Пример кода
import math
# Cosine similarity compares directions: 1 = same direction, 0 = unrelated.
def cosine(a, b):
dot = sum(x * y for x, y in zip(a, b))
return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
print("cos(doc1, doc2):", round(cosine([1, 2, 0], [2, 4, 0]), 3))
print("cos(doc1, doc3):", round(cosine([1, 2, 0], [0, 0, 3]), 3))
# k-means: assign points to the nearest centre, then move each centre to its points' mean.
points = [1, 2, 3, 10, 11, 12]
centres = [1.0, 2.0]
for step in range(1, 4):
groups = [[], []]
for p in points:
nearest = min(range(len(centres)), key=lambda i: abs(p - centres[i]))
groups[nearest].append(p)
centres = [sum(g) / len(g) for g in groups]
print(f"step {step}: centres={[round(c, 2) for c in centres]} groups={groups}")
Ожидаемый результат
cos(doc1, doc2): 1.0
cos(doc1, doc3): 0.0
step 1: centres=[1.0, 7.6] groups=[[1], [2, 3, 10, 11, 12]]
step 2: centres=[2.0, 11.0] groups=[[1, 2, 3], [10, 11, 12]]
step 3: centres=[2.0, 11.0] groups=[[1, 2, 3], [10, 11, 12]]
Как это работает
cosine() делит скалярное произведение на длины обоих векторов, поэтому doc2 (то же направление, что у doc1) получает 1, а doc3 (нет общих слов) - 0. k-means повторяет два шага, относит каждую точку к ближайшему центру и сдвигает каждый центр в среднее его точек. После шага 2 ничего не меняется, значит, алгоритм сошёлся.
Измените значения и запустите программу в онлайн-компиляторе Python CodeUtility без локальной установки Python.
Практические задания
Изменяйте входные данные и проверяйте граничные случаи перед работой с большими наборами.
- Измените входные данные или веса и предскажите результат до запуска.
- Выводите промежуточные значения, чтобы проследить каждый шаг вычислений.
- Решите задачи по ссылкам ниже, чтобы самостоятельно реализовать идею.
Попрактикуйтесь на задаче
Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.
- Косинусное сходство Измерьте сходство двух векторов по углу между ними, как это делают поисковые системы с эмбеддингами. Легко
- Кластеризация k-means Разбейте точки на k кластеров, многократно назначая их ближайшему центроиду и сдвигая центроиды. Средне