You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/ru/2-Regression/4-Logistic/README.md

35 KiB

Логистическая регрессия для предсказания категорий

Инфографика: логистическая vs линейная регрессия

Тест перед лекцией

Этот урок доступен на языке R!

Введение

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

В этом уроке вы узнаете:

  • Новую библиотеку для визуализации данных
  • Техники логистической регрессии

Углубите свои знания о работе с этим типом регрессии в модуле обучения

Предварительные знания

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

Давайте построим модель логистической регрессии, чтобы предсказать, какого цвета, вероятно, будет данная тыква (оранжевая 🎃 или белая 👻), основываясь на некоторых переменных.

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

Определение вопроса

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

🎃 Забавный факт: белые тыквы иногда называют "тыквами-призраками". Их сложно вырезать, поэтому они не так популярны, как оранжевые, но выглядят они круто! Таким образом, мы могли бы также переформулировать наш вопрос как: "Призрак" или "Не призрак". 👻

О логистической регрессии

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

Машинное обучение для начинающих - Понимание логистической регрессии для классификации

🎥 Нажмите на изображение выше, чтобы посмотреть короткое видео о логистической регрессии.

Бинарная классификация

Логистическая регрессия не предлагает тех же возможностей, что и линейная регрессия. Первая позволяет предсказывать бинарные категории ("белая или не белая"), тогда как вторая способна предсказывать непрерывные значения, например, исходя из происхождения тыквы и времени сбора урожая, насколько вырастет ее цена.

Модель классификации тыкв

Инфографика от Dasani Madipalli

Другие классификации

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

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

Мультиномиальная vs порядковая регрессия

Переменные НЕ обязаны коррелировать

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

Вам нужно много чистых данных

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

Машинное обучение для начинающих - Анализ и подготовка данных для логистической регрессии

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

Подумайте о типах данных, которые хорошо подходят для логистической регрессии.

Упражнение - очистка данных

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

  1. Добавьте следующий код:

    
    columns_to_select = ['City Name','Package','Variety', 'Origin','Item Size', 'Color']
    pumpkins = full_pumpkins.loc[:, columns_to_select]
    
    pumpkins.dropna(inplace=True)
    

    Вы всегда можете заглянуть в ваш новый датафрейм:

    pumpkins.info
    

Визуализация - категориальный график

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

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

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

    import seaborn as sns
    
    palette = {
    'ORANGE': 'orange',
    'WHITE': 'wheat',
    }
    
    sns.catplot(
    data=pumpkins, y="Variety", hue="Color", kind="count",
    palette=palette, 
    )
    

    Сетка визуализированных данных

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

    Учитывая этот категориальный график, какие интересные исследования вы можете себе представить?

Предварительная обработка данных: кодирование признаков и меток

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

Для кодирования признаков существуют два основных типа кодировщиков:

  1. Ordinal encoder: подходит для порядковых переменных, которые являются категориальными переменными, где их данные следуют логическому порядку, например, столбец Item Size в нашем наборе данных. Он создает отображение, при котором каждая категория представлена числом, соответствующим порядку категории в столбце.

    from sklearn.preprocessing import OrdinalEncoder
    
    item_size_categories = [['sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo']]
    ordinal_features = ['Item Size']
    ordinal_encoder = OrdinalEncoder(categories=item_size_categories)
    
  2. Categorical encoder: подходит для номинальных переменных, которые являются категориальными переменными, где их данные не следуют логическому порядку, например, все признаки, отличные от Item Size в нашем наборе данных. Это кодирование с помощью "одного горячего", что означает, что каждая категория представлена бинарным столбцом: закодированная переменная равна 1, если тыква принадлежит этому сорту, и 0 в противном случае.

    from sklearn.preprocessing import OneHotEncoder
    
    categorical_features = ['City Name', 'Package', 'Variety', 'Origin']
    categorical_encoder = OneHotEncoder(sparse_output=False)
    

Затем ColumnTransformer используется для объединения нескольких кодировщиков в один шаг и их применения к соответствующим столбцам.

    from sklearn.compose import ColumnTransformer
    
    ct = ColumnTransformer(transformers=[
        ('ord', ordinal_encoder, ordinal_features),
        ('cat', categorical_encoder, categorical_features)
        ])
    
    ct.set_output(transform='pandas')
    encoded_features = ct.fit_transform(pumpkins)

С другой стороны, для кодирования метки мы используем класс LabelEncoder из scikit-learn, который является утилитой для нормализации меток, чтобы они содержали только значения между 0 и n_classes-1 (здесь, 0 и 1).

    from sklearn.preprocessing import LabelEncoder

    label_encoder = LabelEncoder()
    encoded_label = label_encoder.fit_transform(pumpkins['Color'])

После того как мы закодировали признаки и метку, мы можем объединить их в новый датафрейм encoded_pumpkins.

    encoded_pumpkins = encoded_features.assign(Color=encoded_label)

Каковы преимущества использования порядкового кодировщика для столбца Item Size?

Анализ отношений между переменными

Теперь, когда мы предварительно обработали наши данные, мы можем проанализировать отношения между признаками и меткой, чтобы понять, насколько хорошо модель сможет предсказывать метку, основываясь на признаках. Лучший способ выполнить такой анализ — это построить графики данных. Мы снова будем использовать функцию catplot из Seaborn, чтобы визуализировать отношения между Item Size, Variety и Color в категориальном графике. Для лучшей визуализации данных мы будем использовать закодированный столбец Item Size и некодированный столбец Variety.

    palette = {
    'ORANGE': 'orange',
    'WHITE': 'wheat',
    }
    pumpkins['Item Size'] = encoded_pumpkins['ord__Item Size']

    g = sns.catplot(
        data=pumpkins,
        x="Item Size", y="Color", row='Variety',
        kind="box", orient="h",
        sharex=False, margin_titles=True,
        height=1.8, aspect=4, palette=palette,
    )
    g.set(xlabel="Item Size", ylabel="").set(xlim=(0,6))
    g.set_titles(row_template="{row_name}")

Категориальный график визуализированных данных

Использование swarm plot

Поскольку Color является бинарной категорией (Белая или Не белая), для ее визуализации требуется 'специализированный подход'. Существуют другие способы визуализации отношений этой категории с другими переменными.

Вы можете визуализировать переменные бок о бок с помощью графиков Seaborn.

  1. Попробуйте использовать график 'swarm', чтобы показать распределение значений:

    palette = {
    0: 'orange',
    1: 'wheat'
    }
    sns.swarmplot(x="Color", y="ord__Item Size", data=encoded_pumpkins, palette=palette)
    

    Swarm-график визуализированных данных

Обратите внимание: приведенный выше код может вызвать предупреждение, так как Seaborn не может корректно отобразить такое количество точек данных на swarm-графике. Возможным решением является уменьшение размера маркера с помощью параметра 'size'. Однако имейте в виду, что это влияет на читаемость графика.

🧮 Покажите математику

Логистическая регрессия основывается на концепции 'максимального правдоподобия', используя сигмоидные функции. Сигмоидная функция на графике выглядит как форма 'S'. Она принимает значение и отображает его в диапазоне от 0 до 1. Ее кривая также называется 'логистической кривой'. Формула выглядит следующим образом:

логистическая функция

где середина сигмоида находится в точке 0 по оси x, L — максимальное значение кривой, а k — крутизна кривой. Если результат функции больше 0.5, метке присваивается класс '1' бинарного выбора. Если нет, она классифицируется как '0'.

Построение модели

Построение модели для нахождения этих бинарных классификаций удивительно просто в Scikit-learn.

Машинное обучение для начинающих - Логистическая регрессия для классификации данных

🎥 Нажмите на изображение выше, чтобы посмотреть короткое видео о построении модели линейной регрессии.

  1. Выберите переменные, которые вы хотите использовать в своей модели классификации, и разделите тренировочные и тестовые наборы, вызвав train_test_split():

    from sklearn.model_selection import train_test_split
    
    X = encoded_pumpkins[encoded_pumpkins.columns.difference(['Color'])]
    y = encoded_pumpkins['Color']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
    
  2. Теперь вы можете обучить свою модель, вызвав fit() с вашими тренировочными данными, и вывести ее результат:

    from sklearn.metrics import f1_score, classification_report 
    from sklearn.linear_model import LogisticRegression
    
    model = LogisticRegression()
    model.fit(X_train, y_train)
    predictions = model.predict(X_test)
    
    print(classification_report(y_test, predictions))
    print('Predicted labels: ', predictions)
    print('F1-score: ', f1_score(y_test, predictions))
    

    Посмотрите на результаты вашей модели. Это неплохо, учитывая, что у вас всего около 1000 строк данных:

                       precision    recall  f1-score   support
    
                    0       0.94      0.98      0.96       166
                    1       0.85      0.67      0.75        33
    
        accuracy                                0.92       199
        macro avg           0.89      0.82      0.85       199
        weighted avg        0.92      0.92      0.92       199
    
        Predicted labels:  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
        0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
        1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0
        0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0
        0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
        0 0 0 1 0 0 0 0 0 0 0 0 1 1]
        F1-score:  0.7457627118644068
    

Лучшая интерпретация через матрицу ошибок

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

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

  1. Чтобы использовать матрицу ошибок, вызовите confusion_matrix():

    from sklearn.metrics import confusion_matrix
    confusion_matrix(y_test, predictions)
    

    Посмотрите на матрицу ошибок вашей модели:

    array([[162,   4],
           [ 11,  22]])
    

В Scikit-learn строки (ось 0) представляют собой фактические метки, а столбцы (ось 1) — предсказанные метки.

0 1
0 TN FP
1 FN TP

Что здесь происходит? Допустим, наша модель должна классифицировать тыквы между двумя бинарными категориями: категория "белая" и категория "не белая".

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

Как вы могли догадаться, предпочтительно иметь больше истинных положений и истинных отрицаний и меньше ложных положений и ложных отрицаний, что означает, что модель работает лучше. Как связаны матрица ошибок, точность и полнота? Помните, что отчет о классификации, напечатанный выше, показал точность (0.85) и полноту (0.67).

Точность = tp / (tp + fp) = 22 / (22 + 4) = 0.8461538461538461

Полнота = tp / (tp + fn) = 22 / (22 + 11) = 0.6666666666666666

В: Как модель справилась, согласно матрице ошибок? О: Неплохо; есть хорошее количество истинных отрицательных, но также несколько ложных отрицательных.

Давайте снова рассмотрим термины, которые мы видели ранее, с помощью отображения TP/TN и FP/FN в матрице ошибок:

🎓 Точность: TP/(TP + FP) Доля релевантных объектов среди найденных (например, какие метки были правильно определены).

🎓 Полнота: TP/(TP + FN) Доля релевантных объектов, которые были найдены, независимо от того, правильно ли они определены.

🎓 f1-оценка: (2 * точность * полнота)/(точность + полнота) Взвешенное среднее точности и полноты, где лучший результат — 1, а худший — 0.

🎓 Поддержка: Количество случаев для каждой найденной метки.

🎓 Точность (Accuracy): (TP + TN)/(TP + TN + FP + FN) Процент меток, предсказанных правильно для выборки.

🎓 Среднее по меткам (Macro Avg): Расчет невзвешенного среднего показателей для каждой метки, без учета дисбаланса меток.

🎓 Взвешенное среднее (Weighted Avg): Расчет среднего показателей для каждой метки, с учетом дисбаланса меток путем их взвешивания по поддержке (количеству истинных случаев для каждой метки).

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

Визуализация ROC-кривой этой модели

ML для начинающих - Анализ производительности логистической регрессии с помощью ROC-кривых

🎥 Нажмите на изображение выше, чтобы посмотреть короткий видеообзор ROC-кривых.

Давайте сделаем еще одну визуализацию, чтобы увидеть так называемую 'ROC'-кривую:

from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline

y_scores = model.predict_proba(X_test)
fpr, tpr, thresholds = roc_curve(y_test, y_scores[:,1])

fig = plt.figure(figsize=(6, 6))
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr, tpr)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.show()

Используя Matplotlib, постройте Receiving Operating Characteristic или ROC-кривую модели. ROC-кривые часто используются для анализа работы классификатора в терминах истинных и ложных положительных. "ROC-кривые обычно показывают долю истинных положительных на оси Y и долю ложных положительных на оси X." Таким образом, важны крутизна кривой и пространство между линией середины и кривой: вы хотите, чтобы кривая быстро поднималась вверх и уходила от линии. В нашем случае сначала есть ложные положительные, а затем линия поднимается вверх и уходит правильно:

ROC

Наконец, используйте API roc_auc_score из Scikit-learn, чтобы вычислить фактическую 'Площадь под кривой' (AUC):

auc = roc_auc_score(y_test,y_scores[:,1])
print(auc)

Результат — 0.9749908725812341. Учитывая, что AUC варьируется от 0 до 1, вы хотите получить высокий результат, так как модель, которая на 100% правильна в своих предсказаниях, будет иметь AUC, равный 1; в данном случае модель довольно хороша.

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


🚀Задание

Логистическая регрессия — это обширная тема! Но лучший способ учиться — это экспериментировать. Найдите набор данных, который подходит для такого типа анализа, и создайте модель на его основе. Что вы узнаете? совет: попробуйте Kaggle для интересных наборов данных.

Тест после лекции

Обзор и самостоятельное изучение

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

Задание

Повторное выполнение этой регрессии


Отказ от ответственности:
Этот документ был переведен с использованием сервиса автоматического перевода Co-op Translator. Хотя мы стремимся к точности, пожалуйста, имейте в виду, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на его исходном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется профессиональный перевод человеком. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования данного перевода.