Набор в университетский городок: проблема классификации с логистической регрессией

Набор в университетский городок: проблема классификации с логистической регрессией

Исходный узел: 1996810

Введение

В этом проекте мы сосредоточимся на данных из Индии. И наша цель – создать прогнозная модель, таких как логистическая регрессия и т. д., чтобы, когда мы даем характеристики кандидата, модель могла предсказать, примут ли они на работу.

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

Проблема науки о данных с логистической регрессией

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

Эта статья была опубликована в рамках Блогатон по Data Science.

Содержание

  1. Шаги, необходимые для решения проблемы
  2. Подготовить данные
  3. Создайте модель логистической регрессии
  4. Результаты модели логистической регрессии
  5. Заключение

Шаги, необходимые для решения проблемы

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

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

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

Вторая цель — создать модель логистической регрессии для прогнозирования пополнения. И наша третья цель — объяснить предсказания нашей модели с помощью отношения шансов.

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

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

Наконец, прежде чем погрузиться в работу, давайте познакомимся с библиотеками, которые мы будем использовать в проекте. Сначала мы импортируем наши данные из блокнота Google Colabe в библиотеку io. Затем, поскольку мы будем использовать модель логистической регрессии, мы импортируем ее из scikit-learn. После этого также из scikit учиться, мы импортируем наши метрики производительности, показатель точности и разбивку между тестами и поездами.

Мы будем использовать Матплотлиб и seaborn для нашей визуализации, и NumPy  будет просто для небольшой математики.
Нам нужно панд для управления нашими данными, labelencoder для кодирования наших категориальных переменных и стандартного масштабатора для нормализации данных. Это будут библиотеки, которые нам нужны.

Приступим к подготовке данных.

#import libraries
import io
import warnings import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler warnings.simplefilter(action="ignore", category=FutureWarning)

Подготовить данные

Импортировать

Чтобы начать подготовку данных, давайте приступим к нашей важной работе. Сначала мы загружаем наш файл данных, а затем нам нужно поместить их в DataFrame `df`.

from google.colab import files
uploaded = files.upload()
# Read CSV file
df = pd.read_csv(io.BytesIO(uploaded["Placement_Data_Full_Class.csv"]))
print(df.shape)
df.head()
Набор данных для логистической регрессии

Мы видим наш красивый DataFrame, и у нас есть 215 записей и 15 столбцов, которые включают атрибут «status», нашу цель. Это описание всех функций.

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

Исследуйте

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

# Inspect DataFrame
df.info() <class 'pandas.core.frame.DataFrame'>
RangeIndex: 215 entries, 0 to 214
Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 sl_no 215 non-null int64 1 gender 215 non-null object 2 ssc_p 215 non-null float64 3 ssc_b 215 non-null object 4 hsc_p 215 non-null float64 5 hsc_b 215 non-null object 6 hsc_s 215 non-null object 7 degree_p 215 non-null float64 8 degree_t 215 non-null object 9 workex 215 non-null object 10 etest_p 215 non-null float64 11 specialisation 215 non-null object 12 mba_p 215 non-null float64 13 status 215 non-null object 14 salary 148 non-null float64
dtypes: float64(6), int64(1), object(8)
memory usage: 25.3+ KB

Теперь, когда мы смотрим на информацию `df`, есть пара вещей, которые мы ищем, у нас есть 215 строк в нашем фрейме данных, и вопрос, который мы хотим задать себе, заключается в том, есть ли какие-то недостающие данные? И если мы посмотрим сюда, кажется, что у нас нет недостающих данных, кроме столбца зарплаты, как и ожидалось, из-за кандидатов, которые не были приняты на работу.

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

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

df.drop(columns="salary", inplace=True)

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

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

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Дисбаланс классов для логистической регрессии

Наш положительный класс «размещено» составляет более 65% наших наблюдений, а наш отрицательный класс «не размещено» составляет около 30%. Теперь, если бы они были супер несбалансированными, например, если бы их было около 80 или даже больше, я бы сказал, что это несбалансированные классы. И нам нужно проделать некоторую работу, чтобы убедиться, что наша модель будет работать правильно. Но это нормальный баланс.

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

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

fig,ax=plt.subplots(5,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("number").drop(columns="sl_no")): plt.suptitle("Visualizing Distribution of Numerical Columns Indivualy and by Class",size=20) sns.histplot(data=df, x=i, kde=True, ax=ax[index,0]) sns.boxplot(data=df, x='status', y=i, ax=ax[index,1]);
"Логистическая регрессия

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

Во втором столбце у нас есть двойная диаграмма с классом «Размещено» справа, а затем классом «Не размещено» слева. Для функций etest_p и mba_p в этих двух дистрибутивах нет большой разницы с точки зрения построения модели. Существует значительное перекрытие в распределении по классам, поэтому эти функции не будут хорошим предиктором нашей цели. Что касается остальных признаков, то они достаточно различны, чтобы считать их потенциальными хорошими предикторами нашей цели. Перейдем к категориальным признакам. И чтобы исследовать их, мы будем использовать график подсчета.

fig,ax=plt.subplots(7,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("object").drop(columns="status")): plt.suptitle("Visualizing Count of Categorical Columns",size=20) sns.countplot(data=df,x=i,ax=ax[index,0]) sns.countplot(data=df,x=i,ax=ax[index,1],hue="status")
"Логистическая регрессия

Глядя на график, мы видим, что у нас больше кандидатов-мужчин, чем женщин. И у большинства наших кандидатов нет опыта работы, но таких кандидатов наняли больше, чем тех, у кого он был. У нас есть кандидаты, изучавшие коммерцию в качестве курса «высшей школы», и, помимо студентов, кандидаты с научным образованием занимают второе место в обоих случаях.

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

corr = df.select_dtypes("number").corr()
# Plot heatmap of `correlation`
plt.title('Correlation Matrix')
sns.heatmap(corr, vmax=1, square=True, annot=True, cmap='GnBu');
корреляционная матрица

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

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

# Check for high- and low-cardinality categorical features
df.select_dtypes("object").nunique() gender 2
ssc_b 2
hsc_b 2
hsc_s 3
degree_t 3
workex 2
specialisation 2
status 2
dtype: int64

Я не вижу столбцов, в которых количество уникальных значений равно единице или чему-то сверхвысокому. Но я думаю, что здесь не хватает одного столбца категориального типа. И причина в том, что он закодирован не как объект, а как целое число. Столбец sl_no не является целым числом в известном нам смысле. Эти кандидаты ранжируются в определенном порядке. Просто уникальный тег имени, а название похоже на категорию, верно? Итак, это категориальная переменная. И у него нет никакой информации, поэтому нам нужно его удалить.

df.drop(columns="sl_no", inplace=True)

Особенности кодирования

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

lb = LabelEncoder () cat_data = ['gender', 'ssc_b', 'hsc_b', 'hsc_s', 'degree_t', 'workex', 'specialisation', 'status']
for i in cat_data: df[i] = lb.fit_transform(df[i]) df.head()
вывод кода

Split

Мы импортировали и очистили наши данные. Мы провели небольшой исследовательский анализ данных, и теперь нам нужно разделить наши данные. У нас есть два типа разделения: вертикальное разделение или функции-цель и горизонтальное разделение или обучающие тестовые наборы. Начнем с вертикального. Мы создадим нашу матрицу признаков «X» и целевой вектор «y». Наша цель — «статус». Нашими функциями должны быть все столбцы, оставшиеся в 'df.'

#vertical split
target = "status"
X = df.drop(columns = target)
y = df[target]

Модели обычно работают лучше, когда у них есть нормализованные данные для обучения, так что же такое нормализация? Нормализация преобразует значения нескольких переменных в аналогичный диапазон. Наша цель — нормализовать наши переменные. Таким образом, диапазон их значений будет от 0 до 1. Давайте сделаем это, и я буду использовать «StandardScaler».

scaler = StandardScaler()
X = scaler.fit_transform(X)

Теперь давайте сделаем горизонтальный сплит или тренировочные тесты. Нам нужно разделить наши данные (X и y) на обучающие и тестовые наборы, используя рандомизированное разделение обучения и тестирования. наш тестовый набор должен составлять 20% наших общих данных. И мы не забываем установить random_state для воспроизводимости.

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.2, random_state = 42 ) print("X_train shape:", X_train.shape)
print("y_train shape:", y_train.shape)
print("X_test shape:", X_test.shape)
print("y_test shape:", y_test.shape) X_train shape: (172, 12)
y_train shape: (172,)
X_test shape: (43, 12)
y_test shape: (43,)

Создайте модель логистической регрессии

Базовая линия

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

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

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

Мы можем использовать метод value_counts с аргументом normalize = True для вычисления базовой точности:

acc_baseline = y_train.value_counts(normalize=True).max()
print("Baseline Accuracy:", round(acc_baseline, 2)) Baseline Accuracy: 0.68

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

повторять

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

Допустим, вдоль оси x у меня есть p_степени кандидатов в нашем наборе данных. И по мере того, как я двигаюсь справа налево, градусы становятся все выше и выше, а затем по оси Y у меня есть возможные классы для размещения: ноль и один.

график для логистической регрессии

Итак, если бы нам нужно было построить наши точки данных, как бы это выглядело? Наш анализ показывает, что кандидат с высоким показателем «p_степень» будет принят на работу с большей вероятностью. Таким образом, это, вероятно, будет выглядеть примерно так, где кандидат с маленькой `p_степенью` будет равен нулю. И кандидат с высоким `p_степенью` будет на единицу.

p-степень для логистической регрессии

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

повторять

Не совсем. Что произойдет, так это то, что независимо от p_степени кандидата мы всегда будем получать какое-то значение. И это нам не поможет, потому что цифры в данном контексте ничего не значат. Эта проблема классификации должна быть равна нулю или единице. Таким образом, это не сработает.

С другой стороны, поскольку это линия, что, если у нас есть кандидат с очень низким p_степенью? Внезапно наша оценка оказалась отрицательной. И опять же, это не имеет никакого смысла. Нет отрицательного числа, оно должно быть либо нулем, либо единицей. И точно так же, если у нас есть кандидат с очень высоким p_степенью, у меня может быть положительный результат, что-то выше единицы. И опять же, это не имеет никакого смысла. Нам нужен либо ноль, либо единица.

прогноз

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

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

IMG

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

функция для логистической регрессии

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

функция для логистической регрессии

Что происходит, так это то, что вместо прямой линии мы получаем линию, которая выглядит примерно так. Он застрял на одном. Он входит и качается вниз. Потом зависает на нуле.

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

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

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

Что я имею в виду? Это означает, что когда я делаю прогноз, я получаю некоторое значение с плавающей запятой от 0 до 1. И что я буду делать, так это рассматривать его как вероятность того, что мой прогноз принадлежит к положительному классу.

Таким образом, я получаю значение до 0.9999. Я скажу, что вероятность того, что этот кандидат принадлежит к нашему положительному, размещенному классу, составляет 99%. Так что я почти уверен, что он принадлежит к положительному классу. И наоборот, если он упадет до отметки 0.001 или около того, я скажу, что это число низкое. Вероятность того, что это конкретное наблюдение относится к положительному, размещенному классу, практически равна нулю. Итак, я собираюсь сказать, что он принадлежит к нулевому классу.

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

р-степень

Итак, теперь у меня есть функция, которая дает мне прогноз между нулем и единицей, и я рассматриваю это как вероятность. И если эта вероятность выше 0.5 или 50%, я говорю, хорошо, положительный класс один. И если он ниже 50%, я говорю, что это отрицательный класс, ноль. Так работает логистическая регрессия. И теперь мы это понимаем, давайте закодируем и подгоним. Я установлю для гиперпараметра «max_iter» значение 1000. Этот параметр относится к максимальному количеству итераций для сходимости решателей.

# Build model
model = LogisticRegression(max_iter=1000) # Fit model to training data
model.fit(X_train, y_train) LogisticRegression(max_iter=1000)

Оценивать

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

acc_train = accuracy_score(y_train, model.predict(X_train))
acc_test = model.score(X_test, y_test) print("Training Accuracy:", round(acc_train, 2))
print("Test Accuracy:", round(acc_test, 2)) Training Accuracy: 0.9
Test Accuracy: 0.88

Мы видим, что наша точность обучения составляет 90%. Он превосходит базовый уровень. Точность нашего теста была немного ниже — 88%. Он также превзошел базовый уровень и был очень близок к нашей тренировочной точности. Так что это хорошая новость, потому что это означает, что наша модель не переоснащается или что-то в этом роде.

Результаты модели логистической регрессии

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

model.predict(X_train)[:5] array([0, 1, 1, 1, 1])

Таковы были окончательные прогнозы, но каковы вероятности, стоящие за ними? Чтобы получить их, нам нужно сделать немного другой код. Вместо использования метода `predict` с нашей моделью я буду использовать `predict_proba` с нашими обучающими данными.

y_train_pred_proba = model.predict_proba(X_train)
print(y_train_pred_proba[:5]) [[0.92003219 0.07996781] [0.03202019 0.96797981] [0.00678421 0.99321579] [0.03889446 0.96110554] [0.00245525 0.99754475]]

Мы видим своего рода вложенный список с двумя разными столбцами в нем. Столбец слева представляет вероятность того, что кандидат не будет размещен, или наш отрицательный класс «Не размещен». Другой столбец представляет положительный класс «Размещено» или вероятность того, что кандидат будет размещен. Мы сосредоточимся на втором столбце. Если мы посмотрим на первую оценку вероятности правильно, то увидим, что она равна 0.07. Итак, поскольку это меньше 50%, говорит наша модель, мой прогноз равен нулю. И для следующих прогнозов мы видим, что все они выше 0.5, и поэтому наша модель в конце концов предсказала один.

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

# Features names
features = ['gender', 'ssc_p', 'ssc_b', 'hsc_p', 'hsc_b', 'hsc_s', 'degree_p' ,'degree_t', 'workex', 'etest_p', 'specialisation', 'mba_p']
# Get importances
importances = model.coef_[0]
# Put importances into a Series
odds_ratios = pd.Series(np.exp(importances), index= features).sort_values()
# Review odds_ratios.head() mba_p 0.406590
degree_t 0.706021
specialisation 0.850301
hsc_b 0.876864
etest_p 0.877831
dtype: float64

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

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Горизонтальная гистограмма, пять самых больших коэффициентовods_ratios.tail().plot(kind=

Теперь я хочу, чтобы вы представили себе вертикальную линию прямо в точке 5, и я хочу начать с того, что посмотрю на нее. Давайте поговорим о каждом из них в отдельности или только о первой паре. Итак, давайте начнем с «ssc_p», который относится к «проценту среднего образования — 10-й класс». И мы видим, что отношение шансов равно 30. Что это значит? Это означает, что если у кандидата высокий «ssc_p», шансы на его размещение в шесть раз выше, чем у других кандидатов, при прочих равных условиях. Таким образом, другой способ думать об этом - когда у кандидата есть `ssc_p`, вероятность вербовки кандидата увеличивается в шесть раз.

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

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
функция низкой важности

Первое, что нам нужно здесь увидеть, это то, что по оси x все равно единице или ниже. Что это значит? Итак, давайте посмотрим на наше наименьшее отношение шансов. Это mba_p, который относится к проценту MBA. Мы видим, что он готов примерно через 0.45. Что это значит? Ну, разница между 0.45 и 1 составляет 0.55. Все в порядке? И что означает это число? Кандидаты со степенью MBA имеют меньше шансов быть принятыми на работу на 55% при прочих равных условиях. Все в порядке? Таким образом, это уменьшило шансы на вербовку в 0.55 раза или на 55%. И это справедливо для всего здесь.

Заключение

Итак, что мы узнали? Во-первых, на этапе подготовки данных мы узнали, что работаем с классификацией, в частности с бинарной классификацией, с использованием логистической регрессии. С точки зрения изучения данных, мы сделали массу вещей, но с точки зрения основных моментов мы рассмотрели баланс классов, верно? Соотношение наших положительных и отрицательных классов. Затем мы разделяем наши данные.

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

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

Исходный код проекта: https://github.com/SawsanYusuf/Campus-Recruitment.git

Материалы, показанные в этой статье, не принадлежат Analytics Vidhya и используются по усмотрению Автора. 

Отметка времени:

Больше от Аналитика Видхья