Получите более глубокое понимание, заглянув за пределы ваших библиотек машинного обучения.

В наши дни применение машинного обучения (ML) означает установку лучшей библиотеки для работы и экспериментов, а не самостоятельное кодирование алгоритмов. И когда у нас есть такие библиотеки, как scikit-learn, поддерживаемые 2484 участниками, или tensorflow, поддерживаемые 3196 участниками, почему бы и вам? Ответ на поставленный выше вопрос — и причина существования этой серии статей — заключается в лучшем понимании фундаментальных концепций! Я проведу вас через многие из наиболее важных концепций машинного обучения, рассмотрев эти основные алгоритмы. Уделяя большое внимание визуализации вместе с базовым кодом алгоритмов, вы закончите эту серию статей с большей уверенностью в области машинного обучения. Чтобы было интереснее, я буду делать это только с использованием python и numpy, избавляясь от своей зависимости от очевидных библиотек ML.

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

Алгоритмы (модели машинного обучения) и концепции в этой статье

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

  • k-NN (k-ближайших соседей)
  • к-средних

В этом путешествии нас проведут три наших друга-пингвина, изображенные на рисунке 1. Эти три вида пингвинов взяты из набора данных Данные о пингвинах архипелага Палмер (Антарктида), который является (субъективно) более привлекательной альтернативой набору данных о цветках ириса. Он создан для работы как с классификацией, так и с задачами регрессии. На рисунке ниже вы можете увидеть краткий пример данных, и в этом посте мы сосредоточимся на особенностях стебля (клюва) вместе с видами. Для более подробного изучения набора данных ознакомьтесь с этой записной книжкой. Давайте погрузимся в это!

k-NN (k-ближайшие соседи)

Наша первая цель будет состоять в том, чтобы построить модель, которая может предсказать правильную маркировку вида пингвина, используя только особенности стебля. Такая постановка задачи называется контролируемой классификацией. Используя ранее известные точки данных (наблюдения за пингвинами и измерения), мы строим модель, которая может предсказывать невидимые точки данных. Для начала давайте построим распределение точек данных о видах пингвинов, используя culmen_width_mm в качестве оси X и culmen_depth_mm в качестве оси Y:

На рисунке выше мы видим, что существует довольно четкое разделение между видами, использующими особенности стебля. Тем не менее, есть еще некоторые перекрытия вокруг центра. k-NN работает, просматривая уже классифицированные точки данных — как вы уже догадались — соседи. Прежде чем мы сможем это сделать, нам нужно определить, что такое сосед. Это достигается путем выбора предпочтительной метрики расстояния.

Метрики расстояния

Первым строительным блоком алгоритмов, с которыми мы будем работать в этой статье, является метрика евклидова расстояния. В двух словах евклидово расстояние — это кратчайшее расстояние между двумя точками, вычисляемое по теореме Пифагора. Помимо евклидова расстояния, двумя другими часто используемыми метриками расстояния являются манхэттенское (городской квартал) и косинусное расстояние. Манхэттенское расстояние проходит параллельно любой из пространственных плоскостей. Манхэттенское расстояние обычно предпочтительнее при работе с большим количеством признаков (измерений), так как оно меньше страдает от проклятия размерности. Косинусное расстояние учитывает угол между двумя точками в N-мерном пространстве (начиная с [0, 1], где 0 означает отсутствие разницы в углах). Косинусное расстояние — это когда сходство (распределение) значений признаков более важно, чем фактические значения. На рисунке ниже показаны эти три различных показателя расстояния вместе с их расстоянием в скобках легенды.

Реализация метрики евклидова расстояния на Python может принимать разные формы. Но для немного более чистого кода и для соответствия алгоритму k-NN мы в этой статье рассчитаем евклидово расстояние по принципу «один против всех»:

Если бы мы добавили новую точку в позицию [3, 2] на рисунке 3, первый шаг евклидова вычисления (строка кода 3) выглядел бы так:

Построение модели

В отличие от большинства алгоритмов машинного обучения, k-NN не требует обучения. Вместо этого алгоритм сохраняет все точки данных в модели и использует их для прогнозирования класса новых точек данных. k-NN можно резюмировать следующим образом: Для ранее невидимой точки данных найти k ближайших соседей. Затем вычислите наиболее часто встречающийся класс среди этих соседей и назначьте этот класс новой точке данных. В Python это выглядит так:

Осталось только выбрать тезку алгоритма, наш гиперпараметр k. Выбор правильного k для k-NN не совсем тривиален. На рисунке ниже мы выбрали точку (отмеченную черным ромбом) и пытаемся предсказать ее класс, используя приведенный выше алгоритм k-NN. Взглянув на название анимированной фигуры, мы видим, что выбор k›6 меняет наш предсказанный класс с Chinstrap (фиолетовый) на Adélie (оранжевый).

Самый простой подход к выбору k – это перебор диапазона возможных значений k с использованием каждого k для прогнозирования классов для всех точек данных. Затем мы можем сравнить точность каждого k в исходном наборе данных. Это выполняется путем последовательного просмотра всех точек данных в наборе данных, их временного удаления и попытки предсказать их первоначальный класс. Кроме того, обычно плохой практикой является выбор четных значений для k, так как это оставляет возможность иметь равное количество различных классов среди соседей. На рисунке ниже мы видим, что наилучшее возможное k, которое мы можем выбрать для классификации на основе характеристик размера стебля, равно k=5 или k=11. Следуя бритве Оккама, мы должны выбрать k равным 5.

Подводя итог, мы построили алгоритм k-NN на основе евклидовой метрики расстояния. k-NN — это контролируемый алгоритм классификации, поскольку мы используем предыдущие знания о классах существующих точек данных для прогнозирования класса ранее невиданных точек данных. Мы выбрали для нашего k значение 5, так как оно имело самую высокую точность, но при этом имело меньшее количество соседей, чем k=11, которое имело ту же точность, что и 5.

k-значит

Используя строительные блоки, созданные для алгоритма k-NN, и добавив еще несколько, мы можем получить еще один очень популярный алгоритм машинного обучения: k-means. Несмотря на то, что они имеют одинаковое название и схожий математический подход, варианты их использования сильно различаются. k-means — это алгоритм кластеризации, т. е. мы пытаемся разделить точки данных на разные классы на основе атрибутов (функций), помимо метки. Алгоритмы кластеризации используются, когда мы ожидаем несколько групп сущностей (точек данных), но они еще не разделены существующими метками. В нашем случае у нас есть это разделение через уже введенную функцию species. Однако для целей этой статьи мы сделаем вид, что это не так. Эти свойства k-средних классифицируют алгоритм как неконтролируемый алгоритм, в отличие от k-NN. Общий префикс k в двух алгоритмах относится к их основному гиперпараметру. Что касается k-средних, k относится к тому, сколько кластеров мы ожидаем включить в набор данных. В нашем случае мы знаем, что ожидаем три разных скопления, поскольку есть три разных вида пингвинов. В псевдокоде k-means можно резюмировать следующим образом:

randomly assign each data point a cluster label [0, k]
for n iterations:
    calculate the cluster center points
    change each data point to the closest cluster center's label
    if the cluster centers did not move we have converged
        

Мы продолжаем этот цикл до тех пор, пока не закончатся шаги итерации или пока мы не сойдемся. Сходимость в этой реализации k-средних означает, что после пересчета центров кластеров они больше не отличаются от предыдущей итерации. Центр кластера зависит от выбора метрики расстояния, пока мы будем придерживаться евклидовой метрики расстояния. Тогда положение центров кластеров (или средних кластеров) — это просто среднее (среднее) положений каждого кластера по осям x и y. На рисунке ниже мы начинаем со случайного присвоения каждой точке данных метки кластера, обозначенной ее цветом. После этого мы добавляем первоначально рассчитанные центральные точки кластера. После этого мы итеративно присваиваем новые кластеры всем точкам данных, копируя класс (метку) ближайшего центра кластера. Для целей визуализации (не являющихся частью алгоритма) мы также рассчитали границы решений, обозначенные как области, заполненные цветом. Это продолжается до тех пор, пока мы не сойдемся с окончательной настройкой кластера или пока не будет достигнуто максимальное количество итераций. Последний кадр анимации возвращает каждой точке ее истинный цвет класса.

Как видно из последнего кадра анимации, итоговые кластеры не идеальны. Кажется, мы можем отделить оранжевый класс (Adélie) от остальных, но зеленые (Gentoo) и фиолетовые (Chinstrap) классы имеют слишком похожие размеры стебля, чтобы их можно было правильно разделить с помощью k-средних. Глядя на распределение видов на рис. 4, потенциальным улучшением может быть расчет кластеров с использованием метрики косинусного расстояния вместо евклидовой.

Ниже приведен код окончательной реализации алгоритма k-средних, каждый шаг которого объясняется в комментариях.

Заключение

В этом посте мы проанализировали набор данных о пингвинах Палмера, используя контролируемую классификациюалгоритм k-NN и неконтролируемую кластеризациюалгоритм k- означает. Оба этих алгоритма были реализованы с использованием метрики евклидова расстояния. С помощью алгоритма k-NN нам удалось достичь точности 92 % при гиперпараметре k=5. В попытке k-средних мы достигли сходимости после трех итераций. Однако мы также обнаружили, что с учетом выбранных признаков и евклидовой метрики расстояния мы не можем достаточно разделить все три вида. Потенциальным улучшением может быть добавление дополнительных функций или изменение метрики расстояния на косинусное сходство.

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