Сценарист: Лука Брклячич

Оглавление

  1. Введение
  2. Регрессия
    а. Линейная регрессия
  3. Расширения регрессии
    а. Множественная регрессия
    б. Логистическая регрессия
  4. Примеры Python
    а. Линейная регрессия
    б. Множественная регрессия
    c. Логистическая регрессия

Введение

Добро пожаловать во вторую часть нашего обзора машинного обучения (часть 1 можно найти здесь)! В этом посте мы углубимся в механизмы машинного обучения, глубоко погрузившись в регрессию. Если в какой-то момент вы обнаружите, что перегружены, но хотите продолжать учиться, я настоятельно рекомендую проверить этот замечательный плейлист на YouTube о машинном обучении от StatQuest!

Регрессия

Регрессия — один из самых простых и легко расширяемых методов машинного обучения. Хотя существует множество различных типов регрессии — некоторые из них мы рассмотрим в этом посте — по своей сути регрессия — это просто способ использования некоторой переменной (или комбинации переменных) для прогнозирования другой переменной.

Линейная регрессия

Наиболее распространенным и знакомым применением регрессии является линейная регрессия, которую можно определить с помощью знакомой формулы y = mx + b, где:

  • y - зависимая переменная, которую нужно предсказать
  • м - уклон
  • x - независимая переменная, используемая для прогнозирования y
  • b - y-перехват

Пример. Вы биолог, изучаете вомбатов в дикой природе. Цель вашего исследования — определить, какие факторы влияют на размер вомбата. Ваша гипотеза состоит в том, что размер вомбата (y) можно точно предсказать по количеству травы, которую он съедает (x). Вы собираете данные о десяти вомбатах и ​​наносите их на линейный график:

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

  1. Определите линию тренда через данные, которые можно определить с помощью формулы y = mx + b
  2. Определите способ количественной оценки того, насколько хорошо эта линия соответствует нашим фактическим точкам данных.
  3. Определите статистическую значимость нашей меры согласия

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

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

Итак, чтобы получить нашу меру согласия, нам сначала нужно вычислить сумму квадратов вокруг среднего (SS_mean) и сумму квадратов вокруг подгонки (SS_fit). Хотя эти термины кажутся сложными, на самом деле мы всего лишь рассчитываем изменение размера вомбата с учетом поедания травы (SS_fit) и изменение размера вомбата отдельно (SS_mean). Затем мы просто делим их, чтобы получить отношение (), которое говорит нам, насколько хорошо наша линия регрессии соответствует данным.

По своей сути — это способ увидеть, насколько хорошо наша модель предсказывает данные. Чем ближе к 1,0, тем лучше наша модель предсказывает переменную y. Хотя предыдущее предложение верно, в этом утверждении есть много нюансов, поэтому обязательно прочитайте раздел Ограничения R²ниже, чтобы получить полное объяснение. Чтобы узнать больше, посмотрите это видео от StatQuest.

Расчет SS_mean

SS_mean – это мера необработанной вариации наших точек данных, в нашем случае Размер вомбата.

Вычислите расстояние от каждой точки до среднего значения всех точек, например:

  1. Рассчитайте расстояние от каждой точки до линии следующим образом:

2. Возведите каждое из этих значений в квадрат, чтобы удалить отрицательные значения.

3. Суммируйте все значения

Вычисление SS_fit

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

  1. Вычислите расстояние от каждой точки до линии, например:

2. Возведите каждое из этих значений в квадрат, чтобы удалить отрицательные значения.

3. Суммируйте все значения

Расчет R²

Теперь, когда у нас есть SS_fit и SS_mean, мы можем рассчитать нашу меру согласия, . В этом случае предположим, что наша случайная линия дала значение 0,51. Это означает, что при использовании нашей модели (линия регрессии, определяемая как y = mx + b) съеденная трава объясняет 51 % вариации размера вомбата. Еще один полезный способ представления — это следующее соотношение:

Промыть и повторить

Если бы мы делали это вручную, мы бы повторили описанный выше процесс — сгенерировали случайную линию, вычислили SS_fitи SS_mean, рассчитайте — много раз. В конце концов, мы найдем модель, оптимизирующую SS_fit, что даст нам нашу линию наилучшего соответствия (y = mx + b) и соответствующее ей R² значение. В нашем примере с вомбатом эти значения получаются следующими:

y = 0.815x + 43.69

SS_fit= 149,2

SS_mean= 359,6

Ограничения R²

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

Пример: представьте, что у нас есть две точки на графике, одна в (5, 10), а другая в (10, 20). Мы можем провести линию, точно соединяющую эти две точки, в результате чего SS_fit будет равен 0 (все наблюдаемые минус прогнозные значения равны нулю) и SS_mean из 50 ((20–15)² + (10–15)²) = 50). Подставив их в наше уравнение , мы получим = (50–0) / (50) = 100 %.

Это значение означает, что с помощью этой переменной x мы можем объяснить 100 % вариации переменной y. Но поскольку любые две случайные точки дадут вам 100 %, а наша цель — использовать нашу модель для прогнозирования будущих данных, нельзя использовать в вакууме. . Чтобы решить эту проблему, мы можем найти статистическую значимость значения , найдя его p-значение.

Нахождение p-значения R²

Прежде чем мы начнем, давайте убедимся, что мы понимаем, что такое p-value. По своей сути p-значение дает нам меру уверенности в результатах некоторого статистического анализа. Чем ближе p-value к 0, тем больше мы уверены в нашем результате. Это связано с тем, что p-значение можно интерпретировать как процент времени, в течение которого мы ожидаем увидеть неправильный результат с учетом некоторого эксперимента или анализа. Для более подробного объяснения p-значений посмотрите это видео от StatQuest.

Для начала мы начнем с выбора нашего уровня альфа, который представляет собой p-значение, которое мы будем использовать в качестве нашего предела. Мы устанавливаем это значение равным 0,05. Результирующее значение p-value, меньшее 0,05, будет означать, что наш значителен.

Напомним, что выше мы определили со следующим соотношением:

p-значение для определяется так называемой F-статистикой, которая определяется как:

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

Остальная часть уравнения связана с важным понятием, степенями свободы, которое выходит за рамки этой статьи. На данный момент мы можем просто заменить p_fitи p_meanколичеством параметров в вычислениях соответствия и среднего. p_fitотносится к количеству параметров, оцененных в нашей линии регрессии, определяемой как y = mx + b. Поскольку мы оцениваем два параметра — наклон и точку пересечения по оси Y, — p_fitравно 2. Для нашей средней линии нам нужно было использовать только параметр, точку пересечения по оси Y, потому что среднее значение y не имело наклона. Следовательно, p_mean равно 1. Наконец, n равно общему количеству точек данных, которое в нашем случай равен 10. Подставив все это в уравнение F, мы получим:

F распределение определяется двумя параметрами df_1 и df_2. Это два числа, которые мы использовали в наших расчетах, которые мы определили как (p_fit — P-mean) и (n — p_fit. >). Мы можем получить p-значение, используя один из многих калькуляторов F распределения, найденных в Интернете, с df_1 = (2–1) = 1, df_2= (10–2) = 8 и F = 11,3. Учитывая эти значения, вероятность наблюдения значения F, которое больше или равно 11,3, составляет 0,00991. Поскольку это p-значение меньше нашего альфа, равного 0,05, мы можем сказать, что наш значителен.

Расширения регрессии

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

Множественная регрессия

Напомним, что уравнение, используемое для линейной регрессии, имеет два параметра (наклон и точку пересечения с осью y) и определяется как y = mx+b. Для множественной регрессии мы просто добавляем больше переменных в наше уравнение. Поскольку мы также оцениваем каждую из этих дополнительных переменных, с ними будет связан наклон. Вот как выглядит уравнение множественной регрессии n-level:

1 независимая переменная: y = mx + b

2 независимые переменные: y = m_1x + m_2z + b

3 независимых переменных: y = m_1x + m_2z + m_3k + b

n Независимые переменные: y = m_1x + m_2z + m_3k … + m_n{var} + b

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

Теперь вместо 2D-графика у нас есть 3D-график, что также означает, что мы оцениваем три параметра: точку пересечения по оси y, наклон, связанный с переменной x, и наклон, связанный с переменной z (b, m_1, m_2 соответственно). . Теперь наше уравнение для определения размера вомбата выглядит следующим образом:

Размер вомбата = m_1(Поедание травы) + m_2(Возраст_вомбата) + b

Мы следуем тому же процессу, что и в разделе линейной регрессии:

  1. Определите плоскость через данные, которые могут быть определены нашим уравнением y = m_1x + m_2z + b
  2. Оцените, насколько хорошо эта плоскость соответствует нашим фактическим точкам данных, используя скорректированное R²
  3. Определите статистическую значимость и скорректированного R²

Скорректированный R²

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

Если мы уже знаем , легко рассчитать скорректированный R². В приведенном выше уравнении n — размер выборки, а k — количество независимых регрессоров (наклонов).

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

Логистическая регрессия

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

Чтобы понять логистическую регрессию, давайте продолжим наш пример с вомбатом; во-первых, мы должны изменить нашу переменную y. Зависимой переменной теперь будут две категории: Избыточный вес (OW) и Не избыточный вес (СЕЙЧАС).

Далее, вместо подгонки к нашим данным прямой линией, мы подгоняем к данным S-образную логистическую функцию. В отличие от линейной регрессии, наше предсказанное значение y может быть только между 0 и 1.

Общий случай (сигмовидная функция):

Наш пример (СЕЙЧАС = 1,0 и OW = 0,0):

Кривая представляет вероятность попадания в одну из категорий на основе значения независимой переменной x (в нашем случае Grass_Eaten). Мы можем создать правило, которое гласит: «Если вероятность того, что вомбат избыточный вес, составляет ≥ 50 %, классифицируйте этого вомбата как избыточный вес». Как и в примере с линейной регрессией, мы прогнозируем Weight_Class на основе Grass_Eaten. Однако, поскольку мы подгоняем кривую, а не прямую линию, мы не можем вычислить квадраты остатков и, следовательно, не можем вычислить . Вместо этого логистическая регрессия генерирует кривую с использованием максимальной вероятности.

Цель максимального правдоподобия состоит в том, чтобы подогнать оптимальную кривую к данным. Для этого нам нужно найти кривую, значения параметров которой (например, среднее значение и стандартное отклонение) максимизируют вероятность того, что, используя кривую, мы сможем наблюдать то, что на самом деле находится в наших данных. Короче говоря, мы хотим, чтобы наша аппроксимация (кривая) наиболее точно представляла наши данные. Детали максимальной вероятности выходят за рамки этого поста в блоге, но посмотрите это видео, если хотите узнать больше!

Логистическую регрессию, как и ее линейную родственницу, можно расширить, чтобы иметь любое количество независимых переменных. Однако, в отличие от линейной регрессии, мы не можем легко сравнивать простые и сложные модели. В разделе «Примеры Python» мы рассмотрим более подробный пример логистической регрессии.

Примеры Python

Линейная регрессия

Датасет: World Happiness Report 2015–2019 (информационная страница здесь)

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

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import seaborn as sns
import matplotlib.pyplot as plt
# Read in the 2019.csv file
df = pd.read_csv('/content/sample_data/2019.csv') # NOTE: adjust your path as needed

Мы начнем с просмотра и изучения данных. Всего у нас 156 строк и 9 столбцов со следующей разбивкой:

  • 8 числовых
  • 1 строка (страна или регион)

Ни в одном из наших столбцов нет значений NA или null; они все полные.

print(f'Rows: {df.shape[0]}')
print(f'Columns: {df.shape[1]}\n')
print(f'Data Types:\n{df.dtypes}\n')
print(f'Completeness % by column:\n{df.count() / df.shape[0] * 100}')

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

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

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

fig = plt.figure(figsize = (16, 9))
mask = np.triu(np.ones_like(df.corr(), dtype = bool)) # Mask the duplicate top half of the triangle
sns.heatmap(df.corr(), annot = True, mask = mask, vmin = -1, vmax = 1)

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

df = df.drop(['Overall rank'], axis = 1)

fig = plt.figure(figsize = (16, 9))
mask = np.triu(np.ones_like(df.corr(), dtype = bool)) # Mask the duplicate top half of the triangle
sns.heatmap(df.corr(), annot = True, mask = mask, vmin = -1, vmax = 1)

  • Оценка тесно связана с ВВП на душу населения, социальной поддержкой и ожидаемой продолжительностью здоровой жизни.
  • ВВП на душу населения тесно связан с продолжительностью здоровой жизни и социальной поддержкой.
  • Социальная поддержка тесно связана с ожидаемой продолжительностью здоровой жизни.

Логически эти выводы имеют смысл; люди с большим количеством денег, поддержкой и более высокой продолжительностью жизни, как правило, счастливее в целом.

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

# Linear Regression model for GDP Per Capita
gdp_lm = LinearRegression().fit(df[['GDP per capita']], df['Score'])
print(f"GDP per capita R2: {round(gdp_lm.score(df[['GDP per capita']], df['Score']), 2)}")
print(f"GDP per capita equation: Score = {round(gdp_lm.coef_[0], 2)} * (GDP per capita) + {round(gdp_lm.intercept_, 2)}\n")

# Linear Regression model for Social Support
social_lm = LinearRegression().fit(df[['Social support']], df['Score'])
print(f"Social support R2: {round(social_lm.score(df[['Social support']], df['Score']), 2)}")
print(f"Social support equation: Score = {round(social_lm.coef_[0], 2)} * (Social support) + {round(social_lm.intercept_, 2)}\n")

# Linear Regression model for Healthy Life Expectancy
life_lm = LinearRegression().fit(df[['Healthy life expectancy']], df['Score'])
print(f"Healthy life expectancy R2: {round(life_lm.score(df[['Healthy life expectancy']], df['Score']), 2)}")
print(f"Healthy life expectancy equation: Score = {round(life_lm.coef_[0], 2)} * (Healthy life expectancy) + {round(life_lm.intercept_, 2)}")

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

df['GDP_Predicted'] = gdp_lm.predict(df[['GDP per capita']])
df['Social_Predicted'] = social_lm.predict(df[['Social support']])
df['Life_Predicted'] = life_lm.predict(df[['Healthy life expectancy']])
fig, ax = plt.subplots(nrows = 1, ncols = 3, figsize=(25, 8))

fig, ax = plt.subplots(nrows = 1, ncols = 3, figsize=(25, 8))

sns.regplot(x = 'GDP per capita', y = 'GDP_Predicted', data = df, color = 'red', fit_reg = True, marker = "", ax = ax[0])
sns.regplot(x = 'GDP per capita', y = 'Score', data = df, color = 'red', fit_reg = False, ax = ax[0]).set(title = 'GDP Per Capita vs Score with LM Regression Line')

sns.regplot(x = 'Social support', y = 'Social_Predicted', data = df, color = 'green', fit_reg = True, marker = "", ax = ax[1])
sns.regplot(x = 'Social support', y = 'Score', data = df, color = 'green', fit_reg = False, ax = ax[1]).set(title = 'Social Support vs Score with LM Regression Line')

sns.regplot(x = 'Healthy life expectancy', y = 'Life_Predicted', data = df, color = 'blue', fit_reg = True, marker = "", ax = ax[2])
sns.regplot(x = 'Healthy life expectancy', y = 'Score', data = df, color = 'blue', fit_reg = False, ax = ax[2]).set(title = 'Healthy Life Expectancy vs Score with LM Regression Line')

Учитывая вышеизложенное, кажется, что все три наши переменные будут одинаково хорошо предсказывать будущие значения переменной Score. Однако нам все еще не хватает информации о значении R². Чтобы получить эту (и многое другое) полезную информацию, мы будем использовать пакет statsmodels . Хотя синтаксис для запуска кода будет другим, все внутренние вычисления такие же, как и те, что мы делали выше.

Для всего нашего дальнейшего анализа мы будем использовать альфауровень 0,05, который будет нашим порогом значимости. Напоминаем, что если мы получим значение p меньше, чем наша альфа, то этот результат можно считать значимым.

import statsmodels.api as sm

y = df['Score']

# Linear Regression model for GDP Per Capita
x = df[['GDP per capita']]
x = sm.add_constant(x)
gdp_lm_2 = sm.OLS(y, x).fit()
print(f'GDP Per Capita Model Summary:\n{gdp_lm_2.summary()}\n')

# Linear Regression model for Social Support
x = df[['Social support']]
x = sm.add_constant(x)
social_lm_2 = sm.OLS(y, x).fit()
print(f'Social Support Model Summary:\n{social_lm_2.summary()}\n')

# Linear Regression model for Healthy Life Expectancy
x = df[['Healthy life expectancy']]
x = sm.add_constant(x)
life_lm_2 = sm.OLS(y, x).fit()
print(f'Healthy life expectancy Model Summary:\n{life_lm_2.summary()}\n')

Краткое описание модели ВВП на душу населения:

Краткое описание модели социальной поддержки:

Краткое описание модели ожидаемой продолжительности здоровой жизни:

Сводная информация подтверждает наш первоначальный вывод: все три переменные одинаково хорошо предсказывают переменную результата, поскольку все три модели имеют очень низкие p-значения (P › |t| на приведенных выше снимках экрана). ), связанные с их R².

Множественная регрессия

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

Напоминание: уравнение нашей модели примет вид

где:

  • y = переменная Оценка
  • b₀ = y-пересечение
  • b₁ = наклон, связанный с ВВП на душу населения
  • x₁ = переменная ВВП на душу населения
  • b₂ = наклон, связанный с социальной поддержкой
  • x₂ = переменная Социальная поддержка
  • b₃ = наклон, связанный с ожидаемой продолжительностью здоровой жизни.
  • x₃ = ожидаемая продолжительность здоровой жизни
import statsmodels.api as sm

y = df['Score']

# Multiple Regression model for GDP Per Capita + Social Support + Healthy Life Expectancy
x = df[['GDP per capita', 'Social support', 'Healthy life expectancy']]
x = sm.add_constant(x)
mr_model = sm.OLS(y, x).fit()
print(mr_model.summary())

Учитывая результат, теперь мы можем составить уравнение, представляющее нашу модель:

Глядя на значения p (P › |t| на снимке экрана выше) для наших независимых переменных, все они меньше 0,05, поэтому мы можем сказать, что все они значимы и должны быть сохранены. . Эта модель также имеет скорректированное значение R², равное 0,721, что означает, что она лучше прогнозирует переменную Score, чем любая из наших предыдущих моделей.

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

y = df['Score']

# Multiple Regression model for GDP Per Capita + Social Support + Healthy Life Expectancy + Freedom to make life choices + Generosity + Perceptions of corruption
x = df[['GDP per capita', 'Social support', 'Healthy life expectancy', 'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']]
x = sm.add_constant(x)
mr_model2 = sm.OLS(y, x).fit()
print(mr_model2.summary())

Эта модель на самом деле лучше, чем наша предыдущая модель, с скорректированным R² равным 0,77! Однако, прежде чем двигаться дальше, обратите внимание, что сводка модели говорит нам, что с учетом этой модели Щедрость и Восприятие коррупции не являются значимыми предикторами при альфа. = 0,05. Итак, что произойдет, если мы повторим описанное выше, но удалим наименее значимый предиктор, Щедрость?

y = df['Score']

# Multiple Regression model for GDP Per Capita + Social Support + Healthy Life Expectancy + Freedom to make life choices + Perceptions of corruption
x = df[['GDP per capita', 'Social support', 'Healthy life expectancy', 'Freedom to make life choices', 'Perceptions of corruption']]
x = sm.add_constant(x)
mr_model2 = sm.OLS(y, x).fit()
print(mr_model2.summary())

На самом деле мы получаем столь же хорошую, но менее сложную модель! Обратите внимание, что когда мы убрали Щедрость в качестве предиктора и повторно запустили модель без нее, Восприятие коррупции стало значимым при альфа = 0,05. .

Поскольку все наши предикторы значимы, а скорректированное значение R², равное 0,77, является лучшим из всех использовавшихся нами моделей, мы наконец можем заявить, что следующая модель множественной регрессии лучше всего справляется с прогнозированием показателя:

Логистическая регрессия

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

Поскольку наш набор данных не содержит категориальных переменных, мы просто создадим их, разделив столбец Оценка на две категории: высокие и низкие. Оценки ниже среднего будут классифицироваться как «Низкие», а те, что выше среднего, будут классифицированы как «Высокие». Теперь цель нашей модели изменилась с прогнозирования точных значений Score на прогнозирование правильной Score Category.

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

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix

# Create the categorical variable, Score Category, by separating the Score column into High and Low categories
df['Score Category'] = pd.cut(df['Score'],  bins = [np.min(df['Score']), np.mean(df['Score']), np.max(df['Score'])], labels = ['Low', 'High'], include_lowest = True)

# Logistic Regression model for GDP Per Capita + Social Support + Healthy Life Expectancy + Freedom to make life choices + Generosity + Perceptions of corruption
x = df[['GDP per capita', 'Social support', 'Healthy life expectancy', 'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']]
y = df['Score Category']

lr_model = LogisticRegression().fit(x, y)

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

print(lr_model.predict_proba(x))

Вышеприведенный вывод представляет собой массив numpy, который можно прочитать следующим образом: «Модель предсказывает, что строка 1 нашего исходного фрейма данных переходит в категорию «Высокий» с вероятностью 93,4%». Эта вероятность дается для каждой строки в нашем исходном фрейме данных.

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

print(lr_model.predict(x))

А также общий показатель точности (количество правильно классифицированных наблюдений):

print(round(lr_model.score(x, y), 2))

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

print(confusion_matrix(y, lr_model.predict(x)))

# Confusion Matrix Heatmap
cm = confusion_matrix(y, lr_model.predict(x))

fig, ax = plt.subplots(figsize = (16, 9))
ax.imshow(cm)
ax.grid(False)
ax.xaxis.set(ticks = (0, 1), ticklabels = ('Predicted High', 'Predicted Low'))
ax.yaxis.set(ticks = (0, 1), ticklabels = ('Actual High', 'Actual Low'))
ax.set_ylim(1.5, -0.5)

for i in range(2):
    for j in range(2):
        ax.text(j, i, cm[i, j], ha = 'center', va = 'center', color = 'black', size = 50)
plt.show()

Оба вывода говорят нам одно и то же:

  • Было 67 строк, правильно классифицированных как High
  • Было 67 строк, правильно классифицированных как Низкий.
  • Было 12 строк, которые были неправильно классифицированы как высокие.
  • 10 строк были ошибочно классифицированы как низкие.

Обратите внимание, что это, по сути, разложение нашей общей меры точности 0,86, поскольку (67+67)/(67+67+10+12) = 0,86.

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

print(classification_report(y, lr_model.predict(x)))

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

Блог 3 (Дерева решений) — скоро!

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

Если вы хотите обсудить эту тему с нами, вы можете прокомментировать этот пост или связаться с нами в LinkedIn или Medium.