Введение в логистическую регрессию в Python с помощью statsmodels и scikit-learn

Вступление

Многие проблемы, с которыми сталкиваются специалисты по обработке данных, статистики и другие специалисты по работе с данными, требуют определения того, принадлежат ли интересующие наблюдения к той или иной категории по тому или иному результату. Примеры включают оценку кредитоспособности (например, будет ли потенциальный заемщик дефолт по своему долгу?), Пометку покупок по кредитной карте, которые могут быть мошенническими, и классификацию объектов (например, является ли это растение ирисовой сетосой или нет?). Хотя технически возможно рассчитать вероятность принадлежности к одной категории по сравнению с другой с использованием модели линейной регрессии, более подходящим методом регрессии является логистическая регрессия. В этом посте, который является продолжением предыдущей статьи под названием Введение в регрессию в Python с помощью статистических моделей и scikit-learn, рассматриваются примеры простых моделей логистической регрессии, прогнозирующих диагноз диабета с использованием statsmodels и scikit-learn.

Почему бы просто не использовать линейную регрессию?

Допустим, у нас есть интересующий результат, Y, который имеет два дискретных значения: 0 и 1. Мы хотим спрогнозировать вероятность того, что точка данных имеет значение 1 на Y по сравнению со значением 0 с использованием переменной-предиктора x. Ниже представлена ​​диаграмма рассеяния гипотетических данных со значениями Y, построенными против x.

Как показано на этом графике, данная точка данных может принимать значение 0 или 1 на Y. Если мы запустим модель линейной регрессии на этих данных, мы получим эту линию прогноза.

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

В этом случае мы хотим, чтобы наши прогнозы ограничивались диапазоном от 0 до 1. Нам нужна изогнутая s-образная линия, подходящая к данным, а не прямая линия.

Эта изогнутая линия на изображении выше показывает вероятность каждой точки данных иметь значение 1 на Y с учетом значения точки данных на x. Эти предсказанные вероятности были получены путем подгонки модели логистической регрессии к данным. Теперь давайте рассмотрим детали модели логистической регрессии более подробно.

Анатомия модели логистической регрессии

В то время как модель линейной регрессии предназначена для предсказания значений фактического результата, Y, модель логистической регрессии предсказывает логарифмические шансы Y .

Итак, что такое логарифмические шансы? Давайте разберемся с этой концепцией. Шансы рассчитываются путем деления вероятности события (обозначенного здесь p) на его дополнение (1- p). Термин, заключенный в круглые скобки в левой части приведенного выше уравнения, представляет собой шансы. Чтобы получить логарифм шансов, мы просто берем натуральный логарифм (Ln) шансов (логарифм шансов также известен как логит). Обратите внимание, что нижний индекс i в приведенном выше уравнении означает просто отдельную точку данных. В нашем уравнении, например, буква p с нижним индексом i представляет вероятность того, что отдельная точка данных будет иметь значение 1 на Y . Справа от знака равенства 𝛼 представляет точку пересечения (логарифмические шансы, когда предикторная переменная x имеет значение 0), а 𝛽 - вес регрессии (изменение логарифмических шансов для увеличение на единицу в x).

Теперь вы можете спросить, что же такого особенного в логарифмических шансах? Разве нас не интересуют вероятности или, что еще лучше, предсказание дискретного значения 0 или 1 для точки данных? В конечном итоге ответ - «да», но прогнозирование логарифмических шансов - важный шаг, который мы должны сделать в первую очередь. В отличие от вероятностей или дискретных значений дихотомической переменной, логарифмические шансы измеряются по непрерывной шкале. Для иллюстрации ниже представлен график зависимости между x и логарифмическими шансами Y = 1.

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

Когда мы наносим прогнозируемые вероятности на график значений x, мы получаем s-образную кривую, которая выравнивается при значениях 0 и 1, но как нам понять смысл такого графика? Рассмотрим изображение ниже, которое вносит некоторые изменения в предыдущий график прогнозируемых вероятностей в зависимости от x.

В этом примере горизонтальная пунктирная линия обозначает значение 0,5 для прогнозируемой вероятности того, что Y равно 1. Кривая прогнозируемой вероятности пересекает эту горизонтальную линию при значении x. 1,95; эта точка отмечена вертикальной пунктирной линией. Таким образом, в этом простом случае с одним предиктором любая точка данных со значением x не ниже 1,95 будет иметь прогнозируемую вероятность, превышающую или равную 0,5, и будет классифицироваться как 1. И наоборот, данные точки со значениями x ниже 1,95 будут классифицированы как 0.

Как показано на изображении выше, большинство точек данных со значениями x равными или выше 1,95 имеют фактическое значение Y, равное 1, и, таким образом, правильно классифицированы. Эти точки данных, которые имеют как фактическое, так и прогнозируемое значение Y, равное 1, называются истинно положительными. Аналогичным образом, большинство точек данных со значениями x менее 1,95 имеют фактические значения Y, равные 0, и также правильно классифицированы; это истинное отрицание. Конечно, мы также получаем некоторые точки данных, в которых фактическое значение Y не совпадает с прогнозируемым значением Y; эти точки данных представлены красными знаками «+» . Точки данных с фактическим значением 1, которые неправильно классифицированы как 0, называются ложноотрицательными, тогда как точки данных с фактическими значениями 0, которые неправильно классифицируются как 1, являются ложными срабатываниями. Теперь давайте посмотрим, как на самом деле реализовать и использовать логистическую регрессию в Python.

Данные

В следующих примерах мы будем использовать данные Диабет индейцев пима. Данные и сопутствующую информацию можно найти здесь. Начнем с импорта панд, загрузки данных и выбора столбцов, представляющих интерес для этого упражнения: Glucose (концентрация глюкозы в плазме) и Outcome (1 = диабетик, 0 = в противном случае). Наблюдения, которые имеют значение 0 в столбце Глюкоза, обрабатываются как отсутствующие данные и исключаются из анализа (менее 1% наблюдений отбрасываются из-за значения 0 для уровня глюкозы). Как только набор данных загружен и ограничен желаемыми столбцами и строками, мы можем взглянуть на распределение наших столбцов с помощью diab.describe().

Обратите внимание, что минимальное значение для нашего предиктора, глюкозы, равно 44. Напомним, что член перехвата в модели логистической регрессии представляет предсказанные логарифмические шансы, когда предиктор имеет значение 0. Таким образом, я рекомендую «минимальное центрирование» глюкозы. путем вычитания минимального значения 44 из каждого отдельного значения в столбце Глюкоза.

diab["Glucose"] = diab["Glucose"] - diab["Glucose"].min()

Обратите внимание, что наш регрессионный вес и метрики для соответствия модели будут одинаковыми независимо от того, центрируем ли мы прогнозирующий фактор. Однако центрирование будет иметь значение для значения точки пересечения. Без минимального центрирования точка пересечения будет представлять предсказанные логарифмические шансы, когда точка данных имеет значение глюкозы, равное 0 в наборе данных, где минимальное значение глюкозы равно 44. При минимальном центрировании глюкозы точка пересечения вместо этого будет представлять предсказанный логарифм. вероятность диабета для наблюдений с самым низким уровнем концентрации глюкозы, наблюдаемым в наборе данных. Хорошо, теперь, когда наши данные настроены, давайте перейдем к анализу, начав с моделирования логистической регрессии в statsmodels.

статмодели

statsmodels - это «модуль Python, который предоставляет классы и функции для оценки множества различных статистических моделей, а также для проведения статистических тестов и исследования статистических данных». ¹ Если мы заинтересованы в проведении формальной статистической проверки гипотез о влиянии глюкозы на диабет, statsmodels полезен, потому что он может легко предоставить выводимые статистические показатели, такие как стандартные ошибки, доверительные интервалы и p-значения. , для весов регрессии.

На самом деле существует два разных «вкуса» statsmodels. Первый - это стандартный пакет statsmodels, который использовался в предыдущем разделе «Введение в регрессию в Python с помощью statsmodels и scikit-learn». Второй - statsmodels.formula, который позволяет пользователю определять модели, используя формулы R-стиля, содержащиеся в строках. Помимо возможности записать формулу для своей модели в строку, еще одним преимуществом использования statsmodels.formula является то, что по умолчанию включен перехват. Итак, давайте воспользуемся statsmodels.formula в следующем упражнении.

Приведенный ниже код импортирует statsmodels.formula, присваивает модели логистической регрессии, прогнозирующей диабет с использованием концентрации глюкозы, m1, а затем использует m1.summary() для вывода таблицы результатов модели. Имейте в виду, что m1 - это имя, определяемое пользователем. Я выбрал m1, потому что, на мой взгляд, он означает «модель 1», но вам не нужно быть привязанными к моим соглашениям об именах.

Разберем код модели (строки 3–6) более подробно. Строка 3 вызывает logit из statsmodels.formula, который начинает процесс подгонки модели логистической регрессии к данным. Строка 4 определяет модель со строкой Outcome ~ Glucose. Имя столбца слева от ~ является результатом, а столбец справа - предиктором (если вы хотите включить более одного предиктора, необходимо поместить + между именами столбцов для каждого предиктора). Строка 5 определяет данные, которым соответствует модель, а строка 6 указывает, что она действительно соответствует модели логистической регрессии.

Вот таблица результатов m1.

Обратите внимание, что значение Method в верхней левой части вывода равно MLE. Это означает оценку максимального правдоподобия; помните об этом термине. Теперь обратите внимание на правую часть вывода, которая читается как Log-Likelihood. Функцию правдоподобия можно резюмировать как вероятность того, что наблюдаемые данные были сгенерированы заданным набором значений параметров (т. Е. Значений весовых коэффициентов пересечения и регрессии). Здесь наша цель - найти значения параметров, которые максимизируют функцию правдоподобия, отсюда и термин «максимальное правдоподобие».

На практике предпочтительно вычислять натуральный логарифм правдоподобия, то есть логарифм правдоподобия, поскольку логарифм правдоподобия проще дифференцировать по сравнению с правдоподобием. Где p представляет собой прогнозируемую вероятность принадлежности к классу интереса в дихотомическом исходе (например, класс 1 в отличие от 0) для данного наблюдения, i и y представляет собой фактическое значение наблюдения для дихотомического результата, логарифм правдоподобия можно записать следующим образом.

Логарифмическая вероятность нашей модели составляет -393,28. Нулевая модель, которая является моделью с перехватом в качестве единственного параметра, имеет логарифмическую вероятность -493,35, как показано в выходных данных LL-Null под Log-Likelihood. LLR p-value предоставляет p-значение из критерий отношения правдоподобия рассматриваемой модели по сравнению с нулевой моделью. Если это значение p соответствует установленному порогу статистической значимости, то мы можем сделать вывод, что модель лучше соответствует данным, чем нулевая модель. В этом случае результаты теста отношения правдоподобия показывают, что включение концентрации глюкозы в качестве предиктора диабета значительно улучшает соответствие модели по сравнению с нулевой моделью только с перехватом.

Теперь давайте сосредоточимся на результатах перехвата и регрессионного веса в нижней части таблицы. Под столбцом coef строка Intercept имеет значение -3,9272. Это означает, что, когда глюкоза имеет значение 0, прогнозируемые логарифмические шансы иметь значение 1 для результата (то есть быть классифицированным как диабет) равны -3,9272. Значение 0,0406 для Glucose в столбце coef означает, что для каждой единицы увеличения значения глюкозы логарифмический шансы быть классифицированным как диабетик увеличивается на значение 0,0406. Логарифмические шансы не очень интуитивно понятны, поэтому мы хотим в конечном итоге предсказать вероятности на основе нашей модели. Тем не менее, мы можем интерпретировать результаты этой модели как показывающие, что более высокие концентрации глюкозы положительно связаны с диагнозом диабета, что имеет смысл.

Значение 0,000 в столбце P>|z| для строки Glucose показывает, что влияние глюкозы на результат статистически значимо на обычных уровнях значимости. Таким образом, мы можем быть уверены, что связь между концентрацией глюкозы и диабетом, наблюдаемая в этом наборе данных, вряд ли может быть связана исключительно с ошибкой выборки. Значения в столбцах [0.025 и 0.075] обеспечивают 95% доверительный интервал для веса пересечения и регрессии для глюкозы, соответственно. Тот факт, что 95% доверительный интервал для глюкозы не пересекает значение 0, также говорит нам о том, что влияние глюкозы на диабет в этой модели является статистически значимым на уровне значимости 5%.

Теперь давайте рассмотрим пример получения предсказанных вероятностей при заданном значении глюкозы из наших результатов. Допустим, мы хотим получить прогнозируемую вероятность быть классифицированным как диабетик при значении концентрации глюкозы 54. Основываясь на результатах нашей модели выше, мы получаем прогнозируемое значение логарифма шансов -3,5212.

-3.5212 = -3.9272 + (54–44)*0.0406

Чтобы преобразовать предсказанные логарифмические шансы в предсказанную вероятность, нам нужно возвести в степень (exp) логарифмические шансы и разделить на значение 1 плюс возведенные в степень логарифмы шансов.

ехр (-3,5212) / (1 + ехр (-3,5212)) = 0,0296 / 1,0296 = 0,0287

Таким образом, вероятность быть классифицированным как диабетик при концентрации глюкозы 54 составляет около 0,03 или 3% в пересчете на процент.

Если бы мы хотели получить прогноз для отдельного значения с помощью нашей модели statsmodels, нам сначала нужно было бы создать фрейм данных pandas с одним столбцом и одной строкой. В приведенном ниже коде я создал фрейм данных newpred со столбцом с именемGlucose и одной строкой со значением 10. Затем я просто применил m1.predict к newpred.

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

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

scikit-learn

scikit-learn предоставляет удобные и полезные инструменты для прогнозного моделирования. Логистическая регрессия - один из таких инструментов, который можно реализовать с помощью класса theLogisticRegression. Однако перед тем, как перейти к LogisticRegression, давайте создадим измененный массив NumPy, который будет содержать значения концентрации глюкозы, чтобы гарантировать, что наш массив значений предикторов содержит как строки, так и столбцы.

X = diab["Glucose"].to_numpy().reshape(-1, 1)

Зачем нужен этот приведенный выше код? Класс LogisticRegression ожидает, что массив значений предикторов будет содержать как строки, так и столбцы. Однако размеры серии pandas diab["Glucose"] в наших данных содержат 763 строки и ни одного столбца.

И наоборот, размеры нашего вновь созданного массива X имеют 763 строки и один столбец.

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

Теперь обсудим базовую структуру синтаксиса scikit-learn для подбора модели. В строке 3 мы начинаем с вызова класса LogisticRegression и последующего добавления метода fit к этому классу. Затем предиктор (то есть X в этом примере) и значения результата (то есть diab["Outcome"]here) передаются в качестве параметров в fit. Когда модель логистической регрессии соответствует данным и присвоена m2, мы можем просмотреть вес пересечения и регрессии с помощью m2.intercept_ и m2.coef_ соответственно.

Эти результаты согласуются с выводом statsmodels. Тем не менее, за кулисами происходит несколько вещей, которые делают реализацию логистической регрессии в scikit-learn немного отличной от statsmodels, которые стоит упомянуть здесь. Во-первых, LogisticRegression scikit-learn минимизирует потерю журнала, а не максимизирует функцию правдоподобия. Тем не менее, функция log-loss - это просто логарифмическая вероятность, умноженная на -1, так что на самом деле это не сильно отличается от того, что происходит в statsmodels. Мы можем вывести потери журнала, используя log_loss из sklearn.metrics.

Обратите внимание, что для normalize установлено значение False в log_loss, что выводит сумму потерь по наблюдениям в наших данных (в соответствии с расчетом логарифмической вероятности в statsmodels), а не среднюю потерю.

Лог-потеря составляет 393,28, что равно значению логарифма правдоподобия из statsmodels, умноженному на -1.

Помимо минимизации потерь журнала, LogisticRegression по умолчанию выполняет регуляризацию (используя штраф l2 в качестве штрафа по умолчанию). Хотя подробное обсуждение регуляризации выходит за рамки этого поста, необходимо дать краткое описание. Короче говоря, регуляризация помогает предотвратить мультиколлинеарность и переоснащение за счет снижения веса регрессии. Таким образом, более сильная регуляризация уменьшит величину весов регрессии. Здесь - более подробное объяснение регуляризации, которое может оказаться полезным, если вы не знакомы с концепцией.

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

Матрица путаницы

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

Здесь наблюдение классифицируется со значением 1 на исходе (т. Е. Диагностированным диабетом), если прогнозируемая вероятность этого наблюдения из модели логистической регрессии больше или равна 0,5. На основе нашей модели, которую мы использовали с scikit-learn, когда минимально центрированное значение глюкозы составляет около 96,66 или выше, наблюдение будет классифицировано как 1 (диабетик) и 0 (недиабетик) в противном случае. . Это значение 96,66 было получено с помощью кода, показанного ниже. Обратите внимание, что для получения прогнозируемых вероятностей из scikit-learn мы должны использовать predict_proba, поскольку predict вернет прогнозируемую классификацию (то есть 1 или 0 в данном случае) для набора наблюдений.

Далее показан код для вывода матрицы неточностей. Первый параметр в confusion_matrix, diab["Outcome"] определяет фактические метки для интересующего результата. Второй параметр, m2.predict(X), предоставляет предсказанные метки из нашей модели логистической регрессии.

А вот и выведенная матрица путаницы.

В верхнем левом углу мы видим, что 437 наших наблюдений являются истинно отрицательными; эти наблюдения имеют фактическое и прогнозируемое значение 0 на исходе. Переходя к нижнему правому углу, мы имеем 132 истинных положительных результата; эти наблюдения имеют фактическое и прогнозируемое значение 1 на исходе. Таким образом, наша модель правильно классифицировала 569 из 763 наблюдений, что дало точность 75%.

Теперь о неверно классифицированных наблюдениях. В правом верхнем углу мы видим, что у нас есть 60 наблюдений с фактическим значением 0 и прогнозируемым значением 1 для результата. Это наши ложные срабатывания. Наконец, в нижнем левом углу у нас 134 ложных отрицания - наблюдения с фактическим значением 1 и прогнозируемым значением 0.

Для чего это стоит, мы могли бы также вывести матрицу путаницы с statsmodels, используя pred_table.

Как видите, вывод pred_table совпадает с выводом confusion_matrix scikit-learn.

Заключение

Как в этом посте, так и в предыдущем посте «Введение в регрессию в Python с помощью statsmodels и scikit-learn» я уделил много внимания основам регрессии по двум причинам. Во-первых, полезными методами моделирования являются линейная и логистическая регрессия. При правильной обработке соответствующих предикторов линейная и логистическая регрессия являются мощными инструментами моделирования, которые также могут обеспечить интерпретируемые результаты. Во-вторых, твердое понимание линейной и логистической регрессии необходимо для понимания множества других методов регрессии и классификации.

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

¹ Введение-Statsmodels. (нет данных). Получено 1 марта 2020 г. с сайта https://www.statsmodels.org/stable/index.html.