Привет мир! Это снова Джаред с другим постом в блоге. На этот раз я пишу об алгоритме кластеризации K-средних.

Основной обзор:

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

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

Преимущества и недостатки кластеризации k-средних:

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

Некоторые из недостатков кластеризации k-средних включают: евклидово расстояние не является идеальным во многих приложениях; производительность не конкурентоспособна с лучшими методами кластеризации; небольшие вариации данных могут привести к совершенно другим кластерам (высокая дисперсия); Предполагается, что кластеры имеют сферическую форму и одинаковый размер.

Как работает алгоритм кластеризации k-средних?

Алгоритм кластеризации k-средних работает путем итеративного уточнения для получения окончательных результатов. Сначала специалист по данным должен выбрать оптимальное значение для k, чтобы получить наилучшую классификацию. Если выбрано неправильное значение для k, классификация будет неверной. Существуют разные методы нахождения оптимального значения k, которые мы обсудим позже. После выбора значения для k нам нужно построить k количество центроидов в случайных позициях на графике. Назовем следующий шаг шагом присваивания данных. На этапе назначения данных каждая точка данных назначается ближайшему центроиду на основе квадрата евклидова расстояния. Dist(c[i], x)² ниже представляет квадрат евклидова расстояния от центроида C[i] до каждой точки в массиве X , который содержит все значения для точек в нашем наборе данных. Мы проверяем евклидово расстояние от каждой точки до каждого центроида на нашем графике. Но нам нужно только место в нашем массиве минимального расстояния, поэтому ему предшествует argmin.

После шага назначения данных переходим к шагу обновления Centroid. На этапе обновления центроида центроиды пересчитываются, взяв среднее значение всех точек данных, назначенных этому центроиду. Затем мы назначаем эти средние значения в качестве новых местоположений соответствующих центроидов.

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

Выбор оптимального значения k и «локтевой точки»

Как упоминалось ранее, как специалист по данным, мы должны иметь возможность определить наиболее оптимальное значение для k. Увеличение k (количество центроидов) всегда будет уменьшать расстояние до точек данных, но если наше значение для k слишком велико, мы рискуем иметь слишком много кластеров для нашего конкретного набора данных. Например, у нас может быть 3 очевидных кластера в нашем наборе данных (каждый из которых представляет функцию), но если k = 5, то у нас будет 5 кластеров для набора данных, который реально имеет только 3 кластера. Это разрушит классификацию и даст нам неправильный вывод для наших данных. Мы также можем дойти до крайности, когда среднее расстояние равно нулю, если наше значение для k равно количеству точек данных. Вместо этого на график наносится среднее расстояние до центроида как функция K, и для грубого определения k можно использовать «точку локтя», где скорость уменьшения резко меняется.

Метод локтя — это метод интерпретации и проверки непротиворечивости в рамках кластерного анализа, разработанный для того, чтобы помочь найти соответствующее количество кластеров в наборе данных. См. график выше. Ось Y представляет собой сумму квадратов ошибок среднего расстояния от k числа центроидов до каждой точки в соответствующих кластерах. По оси X указано количество кластеров k. Если мы построим всю сумму квадратов ошибок среднего расстояния для каждого значения k, мы получим график, подобный приведенному выше.

Наша цель — выбрать маленькое значение k с малой суммой квадратов ошибок прямо перед тем, как остальные значения k начнут давать убывающую отдачу. Обычно это происходит в «локтевой точке» графика, где изменение угла может привести к значительному изменению суммы квадратов ошибок. Другими словами, если бы мы увеличили значение k с 3, сумма квадратов ошибок была бы существенно больше. И если бы мы уменьшили значение k с 3, сумма квадратов ошибок уменьшилась бы, но за счет уменьшения отдачи. Это потому, что мы могли установитьk = 10 и получить наименьшую сумму квадратов ошибок. Но это было бы неэффективно с вычислительной точки зрения, потому что нам пришлось бы сделать 10 итераций для небольшого улучшения ошибки.

Метод локтя не всегда работает; особенно если данные не очень кластеризованы. Не беспокойтесь, потому что существует ряд других методов проверки k, включая перекрестную проверку, информационные критерии, метод теоретико-информационного перехода, метод силуэта и алгоритм G-средних.

Как закодировать алгоритм k-средних в Python?

Чтобы визуализировать график точечной диаграммы, нам понадобится блокнот Jupyter. Поэтому, если он у вас не установлен, погуглите его и скачайте. Мы также будем использовать библиотеки NumPy, Pandas и MatPlotLib для написания этого кода.

Настройка библиотек и чтение данных из файла .csv

Первое, что мы делаем, это импортируем библиотеки, которые будем использовать. Мы импортируем библиотеку NumPy, которая предоставляет нам поддержку математических функций для работы с многомерными массивами и матрицами. Затем мы импортируем библиотеку Pandas для обработки и анализа данных. И последнее, но не менее важное: мы импортируем matplotlib.pyplot для интерактивных графиков и программного создания графиков. %matplotlib inline — это волшебная функция в IPython, которая устанавливает бэкэнд matplotlib на «встроенный» бэкенд. Эта волшебная функция работает только в IPython, поэтому мы используем блокнот Jupyter.

Затем мы просто читаем данные из нашего CSV-файла с помощью следующей функции pd.read_csv('xclara.csv'), затем мы назначаем прочитанные данные нашей переменной data. Позже мы можем манипулировать переменной data и создавать массивы для точек данных V1 и V2.

Создание массива списков для наших данных и построение точек

В этой следующей части нашего кода все, что нам нужно сделать, это переместить все значения V1 и V2 в наши переменные f1 и f2 соответственно. f1 = data['V1'].values возвращает пустое представление всех значений в этом DataFrame, игнорируя метку V1 . Затем мы объединяем функции f1 и f2 и создаем пустой массив списков (т.е. 2D-массив). Мы будем использовать этот массив списка позже, чтобы вычислить евклидово расстояние от каждого центроида до каждой точки. Мы print(X) чтобы дать нам представление о том, как наши точки хранятся в массиве.

Функция matplotlib.scatter возьмет массив значений x и массив значений y и создаст график точечной диаграммы со всеми точками значений. Мы также можем назначить color и size, которыми мы хотим видеть точки. Ниже приведен результат оператора plt.scatter(f1, f2, color = 'black', s = 7), который отображает все точки в нашем наборе данных размером 7 и черным цветом.

Функция евклидова расстояния и инициализация наших центроидов

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

Мы также определяем функцию расстояния def dist(a, b, ax = 1): . Эта функция принимает два вектора в качестве параметров и вычисляет евклидово расстояние, используя другую функцию np.linalg.norm(a — b, axis = ax) . Эта функция является частью модуля линейной алгебры numpy, функция нормы в этом модуле принимает вектор в качестве входных данных и возвращает скалярное значение (например, евклидово расстояние), которое можно интерпретировать как «размер», «длина» или «величина» этого вектора. В нашем случае мы используем разницу между двумя векторами a-b в качестве параметра для нахождения евклидова расстояния между двумя точками. Это также известно как норма L², но функцию нормы также можно использовать для нахождения максимальной нормы, нормы Манхэттена и т. д. Но для наших целей нам нужно только знать, как использовать ее для нормы L² (евклидово расстояние). .

После определения нашей функции расстояния мы используем функцию np.random.randint(0, np.max(X)-20, size = k) для создания случайного числа для значений центроидов x и y соответственно. Прототипом этой функции является numpy.random.randint(low, high, size, dtype). Это означает, что функция в нашем коде создает случайное число от 0 до np.max(X) — 20 (максимальное число в нашем массиве списков X минус 20). Размер size = k означает, что функция создаст k случайных чисел и вернет их в виде массива. Итак, C_x и C_y — это массивы из 3 случайных целых чисел. На следующем шаге мы объединяем два массива вместе и сохраняем их в C как массив списков (т.е. 2D-массив). Затем мы снова разбросаем точки в нашем наборе данных, а также нанесем случайно сгенерированные центроиды (зеленые звезды).

Этап назначения данных, этап обновления Centroid и доработка алгоритма

В этой последней части нашего кода мы создаем этап назначения данных и этап обновления центроида для завершения алгоритма. Сначала мы создаем массив C_old, который представляет собой массив, заполненный нулями и имеющий ту же форму, что и C. Затем мы инициализируем другой массив clusters, который заполнен нулями и имеет ту же длину, что и X, то есть количество точек в нашем наборе данных. Затем мы вычисляем error, находя расстояние от C_old до C.

Мы входим в цикл while, который будет выполняться до тех пор, пока error, которое мы вычислили ранее, не станет равным 0. Затем мы входим в цикл for for i in range(len(X)), который проходит через всю длину массива X. В цикле for мы вычисляем расстояние от точки X[i] до каждого центроида в массиве C и сохраняем его как массив длины 3 в distance. Например, distance[0] содержит расстояние от X[i] до центроида C[0]. Следующая строка min_distance = np.argmin(distance) возвращает место минимального расстояния в массиве distance. Затем мы сохраняем это значение в clusters[i], чтобы позже мы знали, для каких значений в массиве X нужно вычислить среднее значение.

Затем мы копируем значения текущих кластеров в C в массив C_old, а затем повторно вычисляем новые значения центроидов, чтобы мы могли сохранить их в C. Мы должны создать еще один цикл for for i in range(k), который будет вычислять новую позицию для центроида. Мы используем понимание списка, чтобы вернуть список значений, присвоенных каждому кластеру (т. е. вернуть список всех значений в кластере). Это делается с помощью следующей строки кода points = [X[j] for j in range(len(X)) if (clusters[j] == i)]. Затем мы вычисляем среднее значение этих точек с помощью функции np.mean(points, axis = 0) и присваиваем это скалярное значение центроиду C[i] на этой конкретной итерации. После того, как мы вычислим значения для всех новых центроидов, мы снова вычислим ошибку между C_old и C. Если все еще есть ошибка, мы продолжаем цикл while до тех пор, пока не error = 0 (т.е. центроиды не перестанут двигаться).

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

Разработка функций

Feature Engineering имеет основополагающее значение для применения машинного обучения. Функция — это атрибут или свойство, совместно используемое всеми независимыми единицами, для которых должен выполняться анализ или прогноз. Любой атрибут может быть функцией, если он полезен для модели. Процесс разработки признаков использует знания предметной области, чтобы выбрать, какие показатели данных вводить в качестве признаков в алгоритм машинного обучения.

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

Вывод

Спасибо, за то что прочитали эту статью. Я надеюсь, что вы узнали столько же, сколько я, об алгоритме кластеризации k-средних, поскольку я все еще изучаю эти темы. Если есть что-то, что я мог бы улучшить, или если в сообщении есть ошибка, пожалуйста, дайте мне знать. Спасибо!

Цитаты: