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

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

Для получения дополнительной информации о наборе данных не стесняйтесь проверять страницу набора данных. Блокнот со всем этим кодом и пояснениями находится в свободном доступе на Kaggle. Чтобы посмотреть видеоверсию этого урока, посмотрите это видео на YouTube.

Импорт данных

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

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import seaborn as sns

data = pd.read_csv("../input/breast-cancer-wisconsin-data/data.csv")
data.head()

Очистить данные

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

Мы также будем преобразовывать нашу целевую переменную в 1 и 0 для обучения модели.

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

# visualize NAs in heatmap
sns.heatmap(data.isnull(), yticklabels=False, cbar=False, cmap='viridis')

Теперь очистите эти данные:

# drop id and empty columnpy
data.drop(['Unnamed: 32', "id"], axis=1, inplace=True)

# turn target variable into 1s and 0s
data.diagnosis =[1 if value == "M" else 0 for value in data.diagnosis]

# turn the target variable into categorical data
data['diagnosis'] = data['diagnosis'].astype('category',copy=False)
data['diagnosis'].value_counts().plot(kind='bar')

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

Предварительная обработка

Как только наш набор данных будет чистым и мы узнаем, что наши переменные надежны, мы можем приступить к обучению нашей модели. Первое, что нужно сделать, это разделить целевую переменную (здесь называемую «y») и предикторы (здесь называемые «X»). Обратите внимание, что мы используем X в верхнем регистре как соглашение, чтобы имитировать математический язык. В математике заглавные буквы означают, что переменная является многомерной (матрицей).

# Prepare the model
y = data["diagnosis"] # our target variable
X = data.drop(["diagnosis"], axis=1) # our predictors

Нормализация данных

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

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

from sklearn.preprocessing import StandardScaler

# Create a scaler object
scaler = StandardScaler()

# Fit the scaler to the data and transform the data
X_scaled = scaler.fit_transform(X)

# X_scaled is now a numpy array with normalized data

Затем мы разделяем набор данных на обучающий набор и набор для тестирования. Оба имеют одинаковые переменные (столбцы), но разные наблюдения (строки). Для этого мы используем очень удобную функцию Scikit-Learn под названием train_test_split. Эта функция берет наши предикторы и нашу целевую переменную и случайным образом разбивает их на набор для тестирования и набор для обучения. Он возвращает 4 значения:

  • Предикторы нашего тренировочного набора. Мы сохраняем это в переменной Python, которую называем X_train.
  • Цели нашего тренировочного набора. Мы сохраним их в переменной Python, которую назовем y_train.
  • Предикторы нашего тестового набора. Мы сохраним их в переменной Python, которую назовем X_test.
  • Цели нашего набора тестов. Мы сохраним их в переменной Python, которую назовем y_test.

В них каждое наблюдение (строка) в X соответствует целевому значению в y.

Другими параметрами, которые принимает наша функция train_test_split, являются test_size и random_state:

  • train_test_split устанавливает размер нашего X_test и его y_test.
  • random_state, которое представляет собой произвольное целое число, которое позволит нам воспроизвести разделение, если нам когда-нибудь понадобится снова выполнить точное случайное разделение. Обычно мы выбираем 42, потому что это ответ на все вопросы.
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.30, random_state=42)

# Create logistic regression model
lr = LogisticRegression()

# Train the model on the training data
lr.fit(X_train, y_train)

# Predict the target variable on the test data
y_pred = lr.predict(X_test)

Оценить модель

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

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

from sklearn.metrics import accuracy_score

# Evaluate the accuracy of the model
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
# output: Accuracy: 0.98
from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))

"""
Output:
              precision    recall  f1-score   support

           0       0.99      0.98      0.99       108
           1       0.97      0.98      0.98        63

    accuracy                           0.98       171
   macro avg       0.98      0.98      0.98       171
weighted avg       0.98      0.98      0.98       171
"""

Заключение

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

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

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