Menu
CoddyTech

Оценки силуэта

Часть раздела Обучение без учителя путешествия по Machine Learning на Coddy. Урок 8 из 51.

Инерция всегда улучшается с увеличением k, поэтому здесь нужно искать локоть. Силуэт задаёт каждой точке более справедливый вопрос: я ближе к своей группе, чем к следующей?

Чёрная точка, соединённая сплошными линиями с 8 точками своей группы, средняя длина a = 1.3, и пунктирными линиями с 8 точками ближайшей другой группы, средняя длина b = 3.4. Её силуэт равен 0.62

Оценка точки рассчитывается как (b - a) / max(a, b): значение, близкое к 1, означает, что точка плотно прилегает к своей группе; близкое к 0 — что она находится на границе; ниже 0 — что она находится не в той группе. Среднее значение оценивает кластеризацию:

from sklearn.metrics import silhouette_score
for k in [2, 3, 4]:
    km = KMeans(n_clusters=k, n_init=10, random_state=0)
    km.fit(X)
    print(k, f"{silhouette_score(X, km.labels_):.3f}")

Для яблок это выводит:

2 0.534
3 0.657
4 0.545

Он достигает максимума при оптимальном k, здесь это 3, когда точки чувствуют себя наиболее комфортно.

challenge icon

Задание

Легко

Два синоптика не могут прийти к согласию, сколько видов штормов обрушивается на их побережье. В заготовке содержатся данные о 150 штормах, максимальной скорости ветра и осадках; сначала вводится k Аны, затем — Бена.

  1. Вычисли силуэтную оценку для каждого k с точностью до 3 знаков после запятой.
  2. Выведи, чьё значение k подходит лучше.
  3. Выведи лучшее значение k от 2 до 8 вместе с его оценкой.

Для другого побережья:

Ana, k = 2: 0.512
Ben, k = 3: 0.574
Ben's k fits better
Best from 2 to 8: k = 3 (0.574)

Попробуйте сами

import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# Не меняйте строки ниже
rng = np.random.default_rng(6)
# Четыре типа штормов: характерные скорость ветра и количество осадков, а также число штормов каждого типа
kinds = [(30, 8, 40), (12, 34, 35), (21, 21, 30), (11, 9, 45)]
parts = []
for w, r, n in kinds:
    parts.append(np.column_stack([rng.normal(w, 2.5, n), rng.normal(r, 3, n)]))
# 150 штормов на одном побережье, по одной строке на каждый: максимальная скорость ветра (м/с) и количество осадков (мм в час)
storms = np.round(np.concatenate(parts), 1)

# Число типов штормов по оценке каждого из двух синоптиков
k_ana = int(input())
k_ben = int(input())

# Напишите свой код ниже
quiz iconПроверьте себя

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

Все уроки раздела Обучение без учителя

Потренируйтесь самостоятельно: Онлайн-компилятор Python