Полиномиальная логистическая регрессия

говоря о концепции логистической регрессии и реализации логистической функции для реальной простой задачи классификации

Привет народ!

В этой статье речь пойдет об одной из самых полезных регрессионных моделей для задач классификации.

Прежде чем углубляться в понятия, давайте начнем с обычного вопроса!

Представьте, что вы решили пойти на пикник, и первый вопрос, который вы зададите себе, это как погода, потому что, если она будет неподходящей, это сделает для вас ужасный день!
Итак, ваш ответ может быть "Солнечно", "Ветрено", "Дождь" и т. д., но мы знаем, что это не настоящее число и не может быть бесконечностью.
Но как вы ответили? Вы будете использовать множество параметров, таких как скорость ветра, влажность, сезон и ваш прошлогодний опыт работы в этом месте, чтобы ответить!

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

Теперь вы играете роль модели машинного обучения для предсказания погоды! Но как научить Машину такому стилю мышления! Ничто не может сделать это, кроме логистической регрессии.

Во-первых, давайте внимательно посмотрим на концепцию.

Что такое логистическая регрессия?

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

Что отличается? Почему бы не использовать линейную?
Линейная регрессия свободно наносит все данные на график и сопоставляет каждый X с соответствующим Y, и это дает бесконечный результат! Но, как вы видели, у нас нет бесконечных состояний! Логистическая регрессия дает механизм для окружающего результата между двумя допустимыми значениями, 1 и 0; эти значения являются парой Да и Нет

Логистическая регрессия использует функцию Sigmoid, чтобы сжать значения в этом диапазоне и, наконец, построить S-образный график.

Что такое сигмовидная функция?

сигмоид — одна из известных функций в статистике и машинном обучении, которая отображает значения действительных чисел в 0 и 1 или -1 и 1. Студенты, изучающие статистику, знают ее как обратную функцию логита.

вывод для каждого отдельного ввода показывает, что если x равен +ꝏ, то мы получили 1, а если он эквивалентен -ꝏ, он даст 0 вывод.

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

Реализация логистической регрессии

Для реализации я буду использовать Python и блокнот Jupiter.
Прежде всего, мы должны взглянуть на набор данных; это доступно отсюда

DataSet выглядит как на изображении ниже:

Мы понимаем некоторые советы с первого взгляда:

  • набор данных имеет 14 столбцов, содержащих 13 функций.
  • в последнем столбце показаны три метки, и мы знаем, что это полиномиальная задача
  • значения характеристик не в одном масштабе и нуждаются в настройке

Извлечение данных из набора данных и анализ в Dataframe
в этом проекте мы используем две известные библиотеки, Pandas и NumPy.

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

Разделение данных

Теперь нам нужно разделить данные на наборы для обучения и тестирования, потому что модель будет обучать и настраивать свои параметры (тета), учитывая функции и метки для каждой записи, и, наконец, использовать набор для обучения (содержащий невидимые данные) для оценки точности. Согласно этому описанию, мы должны использовать 70% набора данных для этапа обучения и 30% для тестового набора!

Обычно используются следующие коэффициенты: 70 % для обучения, 30 % для тестирования. 80 % обучение, 20 % тестирование

для реализации этой функции сплиттера я использовал простой способ:

Во второй строке счетчик всех записей данных будет получен из набора данных и рассчитан на 70% размера данных, и это будет около 144/0,7 ~ 101 запись.

Затем в третьей строке мы создаем массив, содержащий значения True и False в размере целых записей данных, но мы различаем его, генерируя True для обучающего набора и False для тестового набора. Теперь у нас есть массив, содержащий 70% значений True и 30% False.

Данные должны разбиваться случайным образом, и мы не знаем, упорядочен ли текущий набор данных определенным образом или нет! Итак, давайте разобьем его и перемешаем сгенерированный массив True/False, чтобы убедиться, что он будет собираться случайным образом.
Поэтому я сделал это с помощью функции перемешивания.

Затем попробуйте заархивировать каждое значение True и False, чтобы оно соответствовало индексу в наборе данных, и соедините их вместе.

Наконец, отфильтровав парные данные, мы могли бы иметь два разделенных списка: обучающие и тестовые наборы.

Извлечение объектов и меток из наборов

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

тогда тренировочный набор будет таким:

Масштабировать значение объектов до нужного размера

как мы упоминали в советах по набору данных, значение функций должно быть в одном масштабе, и мы могли бы сделать это, применив к нему нормализацию и быстро установив значения между 0 и 1 :)

в соответствии с правильной формулой для реализации нам нужно использовать две функции в Numpy, Numpy.mean() и Numpy.std(), которые используются для вычисления среднего значения каждого отдельного элемента в наборе функций.

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

Затем я сделал это масштабирование как для тренировочного набора, так и для функций тестового набора.

как показано в верхней таблице; все значения сжаты между 0 и 1.

Каждой тета нужна соответствующая функция

если вы помните функцию гипотезы линейной регрессии, мы представляем xₒ
равным 1, чтобы сделать расчет матриц более удобным.

поэтому у нас есть то же самое здесь, но с немного другой формулой гипотезы:

Нам нужно вставить столбец единиц в качестве первого индекса в функциях.

Прикоснуться к сути

Теперь пришло время поговорить об основной части процесса!
Прежде чем перейти к реализации, давайте поговорим о концепции и поймем, что вокруг нее происходит.

Мы помним, что в линейной регрессии мы использовали функцию стоимости (функцию потерь) J(θ) для представления цели оптимизации с использованием градиентного спуска для минимизации.

К счастью, у нас такой же подход в логистической регрессии! Но вы можете спросить, почему мы не используем функцию стоимости линейной регрессии для этих задач, и ответ — много локальных минимумов!

как видно из графика, у нас много локальных минимумов, и это не выпуклый граф! это создает сложные обстоятельства, чтобы найти лучший, потому что, когда вы думаете, что находитесь в точке глобального минимума, вы можете существовать немного лучше, но вы застряли в своем ограниченном видении :)

поэтому для решения этой проблемы мы должны использовать другую функцию стоимости, связанную с логистической регрессией, и это не что иное, как:

и если мы сожмем эти функции в одну, то будет вот так:

Что ж, теперь пришло время использовать градиентный спуск для минимизации функции стоимости:

есть α непосредственно перед производной частью, и это не что иное, как скорость обучения, и я ожидаю, что вы знаете это раньше

как видите, нам нужна функция производной стоимости, и она будет вычисляться следующим образом:

наконец, мы имеем:

теоретически миссия выполнена успешно, теперь запачкаем руки:

нет сигмоидной функции перед сборкой, и мы видели это чаще всего
поэтому первая функция, которую нужно написать, это сигмоид, и мы говорили о ней раньше

вторая часто встречающаяся функция — это функция гипотезы в логистической регрессии:

Хорошо, теперь пришло время для градиентного спуска:

Вау, это много сложного кода по сравнению с другими! 🤯
давайте максимально упростим построчное описание

входные параметры:

  • x: Элементы Train Set в виде 2D-матрицы
  • y: соответствующая метка класса для набора функций
  • альфа: скорость обучения
  • iter: количество итераций, используемое для остановки алгоритма.

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

затем в третьей строке мы создали пустой массив для тета в будущем.

первый цикл — это разные точки между полиномиальной и бинарной логистической регрессией. чтобы было легче понять, давайте проверим это:

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

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

Мы знаем, что логистическая регрессия инстинктивно работает с двоичной системой, поэтому мы должны изменить задачу в соответствии со стилем работы! Нам нужно сгруппировать классы в бинарный режим и сделать треугольники одним классом, а все остальные типы — одним другим классом; при таком подходе у нас есть бинарная проблема, но следует учитывать, что ее необходимо повторить для каждого класса. т. е. на следующем шаге квадрат будет одного класса, а два других — другого класса.

По этому методу теперь мы знаем причину первого шлейфа! Он пытается выполнить группировку для каждого типа и настроить тэты для этого конкретного типа класса!
Кроме того, он создает начальные тета для этого конкретного типа, а затем различает этот индексированный Y и другие
Опы! есть небольшая функция, о которой раньше не упоминалось:

И это отличается от приведенной выше функции и фильтра Y только для определенной метки класса: т. Е. Фильтрация выполняется путем присвоения выбранному типу значения 1, а другого - 0.

теперь все как в бинарной логистической регрессии

выше функция точно является реализацией:

В конце функции мы возвращаем теты и метки классов для следующего шага.

Давайте запустим нашу логистическую регрессию:

Оцените свой поезд

после всех этих шагов давайте возьмем последний и оценим точность предсказания модели; мы сначала попробуем это на обучающих данных!
ожидайте, что будет 100%:

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

98% — это высокая точность для модели, и это звучит неплохо.

Но что такое функция predict()?

как вы видите, мы использовали функцию predict для применения X (признаков) к функции гипотезы, предоставляя тета-тета, и predict выглядит следующим образом:

примечание: оператор @ — это операция скалярного произведения двух матриц

После применения аргументов в функции гипотезы логистической регрессии используйте argmax, чтобы определить, какой вывод является максимальным, чтобы назначить его определенной метке класса.

Не стесняйтесь, если вам нужно связаться:

Электронная почта: [email protected]

Github: www.github.com/sinadalvand