5 min read

Логистическая регрессия (Logistic Regression)

Логистическая регрессия (Logistic Regression)

Логистическая регрессия (LogReg) – это алгоритм классификации, используемый для отнесения наблюдений к дискретному набору классов. В отличие от Линейной регрессии (Linear Regression), которая выводит непрерывные числовые значения, LogReg преобразует свой вывод с помощью Сигмоида (Sigmoid), чтобы вернуть значение вероятности, которое затем может быть округлено в сторону одного из дискретных классов:

Сигмоидная функция (отмечена розовым) и дискретно классифицированные наблюдения (белые точки)

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

Натренируем Нейронную сеть (Neural Network), предсказывающую, согласится ли клиент банка взять кредит. Для начала импортируем необходимые библиотеки:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import BernoulliNB

Загрузим Датасет (Dataset):

scaled_data = pd.read_csv('https://www.dropbox.com/s/mlbceekfnkehd7p/scaled_bank_data.csv?dl=1')
scaled_data.head()

Подготовленный банковский набор данных выглядит следующим образом:

Все категориальные переменные, такие как «Работа», были закодированы, то есть каждому виду образования был присвоен числовой псевдоним. Для булевых признаков вроде «Ипотека» двум возможным значениям «Да» и «Нет» были присвоены значения 1 и 0. Числовые признаки, такие как «Возраст» были стандартизованы, дабы степень их воздействия на модель была адекватной.

Разделим данные на Тренировочную (Train Data) и Тестовую (Test Data) части. Чтобы оценить предсказательную способность модели, нам предстоит случайным образом отделить от основного массива двадцать процентов наблюдений на проверку. Признаков (Feature) у нас предостаточно, потому опускаем те из них, что обладают наименьшей Важностью признака (Feature Importance):

X = scaled_data.drop(['День', 'Месяц', 'Индекс потребительских цен', 'Займ', 'Ипотека', 'Колебание уровня безработицы', 'y'], axis = 1)

Целевую переменную (Target Variable) y мы тоже опустили в объекте X, потому что тут мы храним переменные, предсказывающие согласие клиента. Для y мы создадим отдельный одноименный объект, который будет представлять целевой признак:

y = scaled_data.y

Библиотека SkLearn поможет нам максимально быстро разделить датасет случайным образом на тренировочную и тестовую части в стандартной пропорции 80 на 20:

X_train, X_test, y_train, y_test = train_test_split(X, y,train_size = 0.8, random_state = 1)

Удостоверимся, что сплит прошел хорошо и уточним габариты полученных частей набора:

print("Разрешение тренировочного датасета на входе:", X_train.shape)
print("Разрешение тестового датасета на входе:", X_test.shape)
print("Разрешение тренировочного датасета на выходе:", y_train.shape)
print("Разрешение тестового датасета на выходе:", y_test.shape)

Пропорция 20 на 80 выдержана (7.113 на 28.448):

Разрешение тренировочного датасета на входе:  (28448, 15)
Разрешение тестового датасета на выходе:  (7113, 15)
Разрешение тренировочного датасета на входе:  (28448,)
Разрешение тестового датасета на выходе:  (7113,)

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

logreg_cv = LogisticRegression(random_state = 0)

сv здесь – это Кросс-валидация (Cross Validation), то есть перекрестная проверка. Мы оценим с ее помощью эффективность каждой нейросети. Попробуем также Дерево решений (Decision Tree), Метод k-ближайших соседей (kNN), Метод опорных векторов (SVM) и Наивный байесовский классификатор (Naive Bayes):

dt_cv = DecisionTreeClassifier()
knn_cv = KNeighborsClassifier()
svc_cv = SVC()
nb_cv = BernoulliNB()

В реальности дело зачастую обстоит так, что Дата-сайентист (Data Scientist) не знает наверняка, какая модель лучше справится с задачей, потому обучает несколько таковых или использует так называемый ансамбль.

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

cv_dict = {0: 'Логистическая регрессия', 1: 'Дерево решений', 2: 'Метод k ближайших соседей', 3: 'Метод опорных векторов', 4: 'Наивный байесовский классификатор’}

С этой же целью создадим список моделей:

cv_models = [logreg_cv, dt_cv, knn_cv, svc_cv, nb_cv]

И вот теперь мы отобразим с помощью цикла for, двойного счетчика i, model и функции enumerate() тестовые точности измерений каждой нейронной сети.

for i,model in enumerate(cv_models):
print("{} | Тестовая точность измерений: {}".format(cv_dict[i], cross_val_score(model, X, y, cv = 10, scoring = 'accuracy').mean()))

Нам нужно как-то сравнивать модели между собой и в целом улучшать результаты, потому вводится термин «Точность измерений» (Accuracy).

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

Давайте немного задержимся на этом моменте: мы запускаем обучение моделей таким необычным образом. Чтобы отобразить тестовую точность каждой из них, используем так называемую Интерполяцию (Interpolation) и метод format(). На месте каждой пары фигурных скобок будет тип модели и соответствующая точность.

Передим для перекрестной проверки все необходимые аргументы – список признаков X, целевой признак y. Параметр cv, например, отвечает за способ формирования тестовых данных. Мы избираем accuracy в качестве метода сравнения. Метод mean() усредняет результат десяти проверок каждой из моделей на точность.

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

Логистическая регрессия | Тестовая точность измерений: 0.8781237696356271
Дерево решений | Тестовая точность измерений: 0.6430000192905322
Метод k ближайших соседей | Тестовая точность измерений: 0.8746929484882704
Метод опорных векторов | Тестовая точность измерений: 0.9188718011316903
Наивный байесовский классификатор | Тестовая точность измерений: 0.8191811374646486

Лучшая, как мы видим, – это Метод опорных векторов, которая добилась наивысшей точности в 91 с лишним процента. Это замечательный результат. Теперь мы можем передавать ей любую новую запись о клиенте, например, такую:

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

К примеру, обнаружив обороты денежных средств (это тоже характеристика) на моей зарплатной карте, нейронная сеть Промсвязьбанка стала предлагать кредитный продукт определенного объема:

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

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

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

Посмотрим, как выглядит тюнинг нашей первой LogReg:

param_grid = {'C': np.logspace(-4, 4, 50),
'penalty': ['l1', ‘l2']}

C (C Regularization Parameter) – это параметр штрафования или неверной классификации. Оказывается, за каждую ошибку модель можно штрафовать (penalty), и это увеличит эффективность.

Создадим объект clf и с его помощью осуществим автопоиск лучших параметров модели. Делается это так:

clf = GridSearchCV(LogisticRegression(random_state = 0), param_grid, cv = 5, verbose = 0, n_jobs = -1)

verbose, равный 0, означает, что мы не хотим увидеть подробный отчет о поиске. n_jobs – это число одновременно запускаемых процессов поиска. -1 значит, что задействуется все процессоры. Теперь обучим нашу регрессионную модель с лучшими параметрами и определим новую точность:

best_model = clf.fit(X_train, y_train)
print(best_model.best_estimator_)
print("Средняя точность измерений:", best_model.score(X_test, y_test))

Скор улучшился и составляет теперь 92 с лишним процента:

Средняя точность измерений:  0.9247856038239842

Ноутбук, не требующий дополнительной настройки на момент написания статьи, можно скачать здесь.

Фото: @ninjason