olshab 1aaa87c3c4 Едут дальнобойщик с напарником. Смотрят — девка голосует симпатичная...
Едут дальнобойщик с напарником. Смотрят — девка голосует симпатичная.
— Возьмём?
— Конечно!
Она сзади села и в спальник забралась.
Водила сразу:
— Ну–ка, порули пока, я сейчас... — и к ней в спальник.
Через 10 минут выбрался, сел вперёд, закурил:
— Ай, хороша девка!
Напарник:
— Чё, правда хороша? Ну–ка, порули пока... — и к ней в спальник.
Через 10 минут девка вылезает, садится с водилой, закуривает:
— Ай, хорош у тебя напарник!
Водила:
— Чё правда так хорош? Ну–ка, порули...
2024-12-14 00:24:39 +04:00

157 KiB
Raw Blame History

Лабораторная работа №4. Обучение с учителем.

Датасет "Набор данных для анализа и прогнозирования сердечного приступа".

Ссылка

Описание датасета

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

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

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

Атрибуты объектов:

  • HeartDisease — наличие сердечного приступа (Yes/No) (целевая переменная).
  • BMI — индекс массы тела (Body Mass Index), числовой показатель.
  • Smoking — курение (Yes/No).
  • AlcoholDrinking — употребление алкоголя (Yes/No).
  • Stroke — наличие инсульта (Yes/No).
  • PhysicalHealth — количество дней в месяц, когда физическое здоровье было неудовлетворительным.
  • MentalHealth — количество дней в месяц, когда психическое здоровье было неудовлетворительным.
  • DiffWalking — трудности при ходьбе (Yes/No).
  • Sex — пол (Male/Female).
  • AgeCategory — возрастная категория (например, 55-59, 80 or older).
  • Race — расовая принадлежность (например, White, Black).
  • Diabetic — наличие диабета (Yes/No/No, borderline diabetes).
  • PhysicalActivity — физическая активность (Yes/No).
  • GenHealth — общее состояние здоровья (от Excellent до Poor).
  • SleepTime — среднее количество часов сна за сутки.
  • Asthma — наличие астмы (Yes/No).
  • KidneyDisease — наличие заболеваний почек (Yes/No).
  • SkinCancer — наличие кожного рака (Yes/No).
In [1]:
import pandas as pd
df = pd.read_csv(".//static//csv//heart_2020_cleaned.csv")
df.head()
Out[1]:
HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma KidneyDisease SkinCancer
0 No 16.60 Yes No No 3.0 30.0 No Female 55-59 White Yes Yes Very good 5.0 Yes No Yes
1 No 20.34 No No Yes 0.0 0.0 No Female 80 or older White No Yes Very good 7.0 No No No
2 No 26.58 Yes No No 20.0 30.0 No Male 65-69 White Yes Yes Fair 8.0 Yes No No
3 No 24.21 No No No 0.0 0.0 No Female 75-79 White No No Good 6.0 No No Yes
4 No 23.71 No No No 28.0 0.0 Yes Female 40-44 White No Yes Very good 8.0 No No No

Бизнес-цель №1. Задача классификации

Описание бизнес-цели

Цель: предсказание наличия сердечного приступа. Цель состоит в разработке модели, которая будет предсказывать, возникнет ли у человека сердечный приступ (признак HeartDisease). Это важная задача для профилактики сердечно-сосудистых заболеваний, позволяющая выявить группы риска и назначить своевременное лечение или профилактические меры.

Достижимый уровень качества модели

Основные метрики для классификации:

  • Accuracy (точность) показывает долю правильно классифицированных примеров среди всех наблюдений. Легко интерпретируется, но может быть недостаточно информативной для несбалансированных классов.
  • F1-Score гармоническое среднее между точностью (precision) и полнотой (recall). Подходит для задач, где важно одновременно учитывать как ложные положительные, так и ложные отрицательные ошибки, особенно при несбалансированных классах.
  • ROC AUC (Area Under the ROC Curve) отражает способность модели различать положительные и отрицательные классы на всех уровнях порога вероятности. Значение от 0.5 (случайное угадывание) до 1.0 (идеальная модель). Полезна для оценки модели на несбалансированных данных.
  • Cohen's Kappa измеряет степень согласия между предсказаниями модели и истинными метками с учётом случайного угадывания. Значения варьируются от -1 (полное несогласие) до 1 (идеальное согласие). Удобна для оценки на несбалансированных данных.
  • MCC (Matthews Correlation Coefficient) метрика корреляции между предсказаниями и истинными классами, учитывающая все типы ошибок (TP, TN, FP, FN). Значение варьируется от -1 (полная несоответствие) до 1 (идеальное совпадение). Отлично подходит для задач с несбалансированными классами.
  • Confusion Matrix (матрица ошибок) матрица ошибок отражает распределение предсказаний модели по каждому из классов.

Выбор ориентира

В качестве базовой модели для оценки качества предсказаний выбрано использование самой распространённой категории целевой переменной HeartDisease в обучающей выборке. Этот подход, известный как "most frequent class baseline", заключается в том, что модель всегда предсказывает наиболее часто встречающееся значение наличия сердечного приступа.

Разбиение набора данных на выборки

Выполним разбиение исходного набора на обучающую (80%) и тестовую (20%) выборки:

In [2]:
from typing import Tuple
import pandas as pd
from pandas import DataFrame
from sklearn.model_selection import train_test_split

def split_stratified_into_train_val_test(
    df_input,
    stratify_colname="y",
    frac_train=0.6,
    frac_val=0.15,
    frac_test=0.25,
    random_state=None,
) -> Tuple[DataFrame, DataFrame, DataFrame, DataFrame, DataFrame, DataFrame]:
   
    if frac_train + frac_val + frac_test != 1.0:
        raise ValueError(
            "fractions %f, %f, %f do not add up to 1.0"
            % (frac_train, frac_val, frac_test)
        )
    if stratify_colname not in df_input.columns:
        raise ValueError("%s is not a column in the dataframe" % (stratify_colname))
    X = df_input
    y = df_input[
        [stratify_colname]
    ]
    df_train, df_temp, y_train, y_temp = train_test_split(
        X, y, stratify=y, test_size=(1.0 - frac_train), random_state=random_state
    )
    if frac_val <= 0:
        assert len(df_input) == len(df_train) + len(df_temp)
        return df_train, pd.DataFrame(), df_temp, y_train, pd.DataFrame(), y_temp
    
    relative_frac_test = frac_test / (frac_val + frac_test)
    df_val, df_test, y_val, y_test = train_test_split(
        df_temp,
        y_temp,
        stratify=y_temp,
        test_size=relative_frac_test,
        random_state=random_state,
    )
    assert len(df_input) == len(df_train) + len(df_val) + len(df_test)
    return df_train, df_val, df_test, y_train, y_val, y_test

X_train, X_val, X_test, y_train, y_val, y_test = split_stratified_into_train_val_test(
    df, stratify_colname='HeartDisease', frac_train=0.8, frac_val=0, frac_test=0.2, random_state=9
)

display("X_train", X_train)
display("y_train", y_train)

display("X_test", X_test)
display("y_test", y_test)
'X_train'
HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma KidneyDisease SkinCancer
249455 No 65.00 No No No 3.0 0.0 No Female 30-34 White No Yes Good 7.0 Yes No No
14270 No 31.89 No No No 0.0 0.0 No Female 55-59 Hispanic No Yes Good 8.0 No No No
163088 No 24.41 No No No 0.0 5.0 No Male 40-44 White No Yes Very good 7.0 No No No
136626 Yes 36.86 Yes No No 30.0 0.0 Yes Male 65-69 White No, borderline diabetes No Good 8.0 No No No
265773 No 35.15 Yes No No 2.0 0.0 No Male 70-74 White No Yes Good 7.0 No Yes No
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
193686 No 30.43 Yes No No 0.0 0.0 No Male 55-59 White No Yes Excellent 7.0 No No No
207316 No 33.66 Yes No No 0.0 0.0 No Female 55-59 White No Yes Very good 6.0 No No No
229094 No 38.95 No No No 0.0 0.0 No Male 60-64 White Yes Yes Good 7.0 No No No
148788 No 35.44 Yes No No 0.0 0.0 No Male 70-74 White No No Very good 6.0 No No No
35742 No 27.26 Yes No No 0.0 0.0 No Male 35-39 White No Yes Very good 8.0 No No No

255836 rows × 18 columns

'y_train'
HeartDisease
249455 No
14270 No
163088 No
136626 Yes
265773 No
... ...
193686 No
207316 No
229094 No
148788 No
35742 No

255836 rows × 1 columns

'X_test'
HeartDisease BMI Smoking AlcoholDrinking Stroke PhysicalHealth MentalHealth DiffWalking Sex AgeCategory Race Diabetic PhysicalActivity GenHealth SleepTime Asthma KidneyDisease SkinCancer
215485 No 32.89 No No No 10.0 5.0 Yes Male 45-49 White Yes No Good 6.0 Yes No No
150930 No 33.00 Yes No No 0.0 0.0 No Male 50-54 Black No No Fair 8.0 No No No
305511 No 39.16 Yes No No 0.0 0.0 Yes Female 75-79 White Yes Yes Very good 7.0 No No No
284576 No 28.89 Yes No No 0.0 0.0 No Male 65-69 White Yes Yes Very good 7.0 No No No
170107 No 33.96 No No No 0.0 0.0 No Female 60-64 White No Yes Very good 7.0 No No No
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
318712 No 34.70 Yes No No 30.0 0.0 No Male 25-29 Hispanic No Yes Excellent 8.0 Yes No No
169792 No 32.61 Yes No No 7.0 0.0 No Female 60-64 Hispanic No Yes Fair 7.0 No No No
19564 No 25.09 Yes No No 0.0 2.0 No Male 60-64 Black No Yes Very good 8.0 No No No
74293 No 21.29 Yes Yes No 0.0 0.0 Yes Male 60-64 White Yes Yes Good 8.0 No No No
284877 Yes 23.30 No No No 0.0 0.0 No Female 80 or older White No Yes Good 6.0 No No No

63959 rows × 18 columns

'y_test'
HeartDisease
215485 No
150930 No
305511 No
284576 No
170107 No
... ...
318712 No
169792 No
19564 No
74293 No
284877 Yes

63959 rows × 1 columns

Построим базовую модель, описанную выше, и оценим ее метрики Accuracy и F1-Score:

In [3]:
from sklearn.metrics import accuracy_score, f1_score

# Определяем самый частый класс
most_frequent_class = y_train.mode().values[0][0]
print(f"Самый частый класс: {most_frequent_class}")

# Вычисляем предсказания базовой модели (все предсказания равны самому частому классу)
baseline_predictions: list[str] = [most_frequent_class] * len(y_test)

# Оцениваем базовую модель
print('Baseline Accuracy:', accuracy_score(y_test, baseline_predictions))
print('Baseline F1:', f1_score(y_test, baseline_predictions, average='weighted'))

# Унитарное кодирование для целевого признака
y_train = y_train['HeartDisease'].map({'Yes': 1, 'No': 0})
y_test = y_test['HeartDisease'].map({'Yes': 1, 'No': 0})
Самый частый класс: No
Baseline Accuracy: 0.9143982864022264
Baseline F1: 0.8735112563715003

Выбор моделей обучения

Для обучения были выбраны следующие модели:

  1. Случайный лес (Random Forest): Ансамблевая модель, которая использует множество решающих деревьев. Она хорошо справляется с нелинейными зависимостями и шумом в данных, а также обладает устойчивостью к переобучению.
  2. Логистическая регрессия (Logistic Regression): Статистический метод для бинарной классификации, который моделирует зависимость между целевой переменной и независимыми признаками, используя логистическую функцию. Она проста в интерпретации и быстра в обучении.
  3. Метод ближайших соседей (KNN): Алгоритм классификации, который предсказывает класс на основе ближайших k обучающих примеров. KNN интуитивно понятен и не требует обучения, но может быть медленным на больших данных и чувствительным к выбору параметров.

Построение конвейера

In [6]:
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

# Разделение признаков на числовые и категориальные
num_columns = [
    column
    for column in df.columns
    if df[column].dtype != "object"
]
cat_columns = [
    column
    for column in df.columns
    if df[column].dtype == "object"
]

# Числовая обработка: заполнение пропусков медианой и стандартизация
num_imputer = SimpleImputer(strategy="median")
num_scaler = StandardScaler()
preprocessing_num = Pipeline(
    [
        ("imputer", num_imputer),
        ("scaler", num_scaler),
    ]
)

# Категориальная обработка: заполнение пропусков значением "unknown" и кодирование
cat_imputer = SimpleImputer(strategy="constant", fill_value="unknown")
cat_encoder = OneHotEncoder(handle_unknown="ignore", sparse_output=False, drop="first")
preprocessing_cat = Pipeline(
    [
        ("imputer", cat_imputer),
        ("encoder", cat_encoder),
    ]
)

# Общий конвейер обработки признаков
features_preprocessing = ColumnTransformer(
    verbose_feature_names_out=False,
    transformers=[
        ("prepocessing_num", preprocessing_num, num_columns),
        ("prepocessing_cat", preprocessing_cat, cat_columns),
    ],
    remainder="passthrough"
)

# Итоговый конвейер
pipeline_end = Pipeline(
    [
        ("features_preprocessing", features_preprocessing),
    ]
)

Использование конвейера на тренировочных данных

In [7]:
preprocessing_result = pipeline_end.fit_transform(X_train)
preprocessed_df = pd.DataFrame(
    preprocessing_result,
    columns=pipeline_end.get_feature_names_out(),
)

preprocessed_df
Out[7]:
BMI PhysicalHealth MentalHealth SleepTime HeartDisease_Yes Smoking_Yes AlcoholDrinking_Yes Stroke_Yes DiffWalking_Yes Sex_Male ... Diabetic_Yes Diabetic_Yes (during pregnancy) PhysicalActivity_Yes GenHealth_Fair GenHealth_Good GenHealth_Poor GenHealth_Very good Asthma_Yes KidneyDisease_Yes SkinCancer_Yes
0 5.773647 -0.046285 -0.489254 -0.065882 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 1.0 0.0 0.0
1 0.561206 -0.424023 -0.489254 0.630754 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.0 0.0
2 -0.616356 -0.424023 0.140196 -0.065882 0.0 0.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0
3 1.343623 3.353355 -0.489254 0.630754 1.0 1.0 0.0 0.0 1.0 1.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
4 1.074421 -0.172198 -0.489254 -0.065882 0.0 1.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
255831 0.331361 -0.424023 -0.489254 -0.065882 0.0 1.0 0.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
255832 0.839853 -0.424023 -0.489254 -0.762519 0.0 1.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
255833 1.672648 -0.424023 -0.489254 -0.065882 0.0 0.0 0.0 0.0 0.0 1.0 ... 1.0 0.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
255834 1.120075 -0.424023 -0.489254 -0.762519 0.0 1.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0
255835 -0.167686 -0.424023 -0.489254 0.630754 0.0 1.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0

255836 rows × 38 columns

Обучение моделей

In [9]:
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics


# Оценка качества различных моделей на основе метрик
def evaluate_models(models, 
                    pipeline_end: Pipeline, 
                    X_train: DataFrame, y_train, 
                    X_test: DataFrame, y_test):
    results = {}
    
    for model_name, model in models.items():
        # Создание конвейера для текущей модели
        model_pipeline = Pipeline(
            [
                ("pipeline", pipeline_end), 
                ("model", model),
            ]
        )
        
        # Обучение модели
        model_pipeline.fit(X_train, y_train)
        
        # Предсказание для обучающей и тестовой выборки
        y_train_predict = model_pipeline.predict(X_train)
        y_test_predict = model_pipeline.predict(X_test)
        
        # Вычисление метрик для текущей модели
        metrics_dict = {
            "Precision_train": metrics.precision_score(y_train, y_train_predict),
            "Precision_test": metrics.precision_score(y_test, y_test_predict),
            "Recall_train": metrics.recall_score(y_train, y_train_predict),
            "Recall_test": metrics.recall_score(y_test, y_test_predict),
            "Accuracy_train": metrics.accuracy_score(y_train, y_train_predict),
            "Accuracy_test": metrics.accuracy_score(y_test, y_test_predict),
            "F1_train": metrics.f1_score(y_train, y_train_predict),
            "F1_test": metrics.f1_score(y_test, y_test_predict),
            "ROC_AUC_test": metrics.roc_auc_score(y_test, y_test_predict),
            "Cohen_kappa_test": metrics.cohen_kappa_score(y_test, y_test_predict),
            "MCC_test": metrics.matthews_corrcoef(y_test, y_test_predict),
            "Confusion_matrix": metrics.confusion_matrix(y_test, y_test_predict),
        }
        
        # Сохранение результатов
        results[model_name] = metrics_dict
    
    return results


# Выбранные модели для классификации
models_classification = {
    "RandomForestClassifier": RandomForestClassifier(random_state=42),
    "LogisticRegression": LogisticRegression(max_iter=1000),
    "KNN": KNeighborsClassifier(),
}

results = evaluate_models(models_classification,
                                                     pipeline_end,
                                                     X_train, y_train,
                                                     X_test, y_test)

# Вывод результатов
for model_name, metrics_dict in results.items():
    print(f"Модель: {model_name}")
    for metric_name, value in metrics_dict.items():
        print(f"\t{metric_name}: {value}")
    print()
Модель: RandomForestClassifier
	Precision_train: 1.0
	Precision_test: 1.0
	Recall_train: 1.0
	Recall_test: 1.0
	Accuracy_train: 1.0
	Accuracy_test: 1.0
	F1_train: 1.0
	F1_test: 1.0
	ROC_AUC_test: 1.0
	Cohen_kappa_test: 1.0
	MCC_test: 1.0
	Confusion_matrix: [[58484     0]
 [    0  5475]]

Модель: LogisticRegression
	Precision_train: 1.0
	Precision_test: 1.0
	Recall_train: 1.0
	Recall_test: 1.0
	Accuracy_train: 1.0
	Accuracy_test: 1.0
	F1_train: 1.0
	F1_test: 1.0
	ROC_AUC_test: 1.0
	Cohen_kappa_test: 1.0
	MCC_test: 1.0
	Confusion_matrix: [[58484     0]
 [    0  5475]]

Модель: KNN
	Precision_train: 0.9985596365852307
	Precision_test: 0.9934322549258088
	Recall_train: 0.8231345328340488
	Recall_test: 0.7459360730593607
	Accuracy_train: 0.9847597679763599
	Accuracy_test: 0.9778295470535812
	F1_train: 0.9024005607149115
	F1_test: 0.8520759440851241
	ROC_AUC_test: 0.872737204165273
	Cohen_kappa_test: 0.8403545562876147
	MCC_test: 0.8504421479558301
	Confusion_matrix: [[58457    27]
 [ 1391  4084]]

Результаты:

  1. Случайный лес (Random Forest):

    • Метрики:
      • Precision (обучение): 1.0
      • Precision (тест): 1.0
      • Recall (обучение): 1.0
      • Recall (тест): 1.0
      • Accuracy (обучение): 1.0
      • Accuracy (тест): 1.0
      • F1 Score (обучение): 1.0
      • F1 Score (тест): 1.0
      • ROC AUC (тест): 1.0
      • Cohen Kappa (тест): 1.0
      • MCC (тест): 1.0
      • Confusion Matrix (тест):
      [[58484     0]
      [    0  5475]]
      
    • Вывод: модель продемонстрировала идеальные результаты как на обучающей, так и на тестовой выборке. Все метрики (Precision, Recall, Accuracy, F1 Score, ROC AUC и др.) равны 1.0, что свидетельствует о 100%-й точности классификации. Вероятно, модель переобучилась, так как такие результаты практически невозможно достичь на реальных данных. Необходимо проверить данные, наличие утечек информации (например, коррелирующих с целевой переменной признаков), а также параметры модели.
  2. Логистическая регрессия (Logistic Regression):

    • Метрики:
      • Precision (обучение): 1.0
      • Precision (тест): 1.0
      • Recall (обучение): 1.0
      • Recall (тест): 1.0
      • Accuracy (обучение): 1.0
      • Accuracy (тест): 1.0
      • F1 Score (обучение): 1.0
      • F1 Score (тест): 1.0
      • ROC AUC (тест): 1.0
      • Cohen Kappa (тест): 1.0
      • MCC (тест): 1.0
      • Confusion Matrix (тест):
      [[58484     0]
      [    0  5475]]
      
    • Вывод: аналогично Random Forest, результаты выглядят идеальными: все метрики равны 1.0, включая ROC AUC, что предполагает идеальную работу модели. Здесь также есть признаки переобучения или утечки данных. Необходимо пересмотреть подготовку данных и проверить конвейер обработки (особенно этапы предобработки).
  3. Метод ближайших соседей (KNN):

    • Метрики:
      • Precision (обучение): 0.999
      • Precision (тест): 0.993
      • Recall (обучение): 0.823
      • Recall (тест): 0.746
      • Accuracy (обучение): 0.985
      • Accuracy (тест): 0.978
      • F1 Score (обучение): 0.902
      • F1 Score (тест): 0.852
      • ROC AUC (тест): 0.872
      • Cohen Kappa (тест): 0.840
      • MCC (тест): 0.850
      • Confusion Matrix (тест):
      [[58457    27]
      [  1391 4084]]
      
    • Вывод: модель KNN выглядит наиболее реалистичной и стабильной, но уступает случайному лесу и логистической регрессии в точности. Эта модель является хорошей точкой отсчета для дальнейших экспериментов.

Матрица неточностей

In [10]:
from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt
from math import ceil

_, ax = plt.subplots(ceil(len(models_classification) / 2), 2, figsize=(12, 10), sharex=False, sharey=False)

for index, key in enumerate(models_classification.keys()):
  c_matrix = results[key]["Confusion_matrix"]
  disp = ConfusionMatrixDisplay(
    confusion_matrix=c_matrix, display_labels=["Yes", "No"]
  ).plot(ax=ax.flat[index])
  disp.ax_.set_title(key)

plt.subplots_adjust(top=1, bottom=0, hspace=0.4, wspace=0.1)
plt.show()
No description has been provided for this image

Подбор гиперпараметров

In [11]:
from sklearn.model_selection import GridSearchCV

# Создание конвейера
pipeline = Pipeline([
    ("processing", pipeline_end),
    ("model", RandomForestClassifier(random_state=42))
])

# Установка параметров для поиска по сетке
param_grid = {
    "model__n_estimators": [10, 50, 100],
    "model__max_features": ["sqrt", "log2"],
    "model__max_depth": [5, 7, 10],
    "model__criterion": ["gini", "entropy"],
}

# Подбор гиперпараметров с помощью поиска по сетке
grid_search = GridSearchCV(estimator=pipeline, 
                           param_grid=param_grid,
                           n_jobs=-1)

# Обучение модели на тренировочных данных
grid_search.fit(X_train, y_train)

# Результаты подбора гиперпараметров
print("Лучшие параметры:", grid_search.best_params_)
c:\Users\Oleg\Desktop\AIM_ForLab4\lab_4\aimenv\Lib\site-packages\numpy\ma\core.py:2881: RuntimeWarning: invalid value encountered in cast
  _data = np.array(data, dtype=dtype, copy=copy,
Лучшие параметры: {'model__criterion': 'gini', 'model__max_depth': 5, 'model__max_features': 'sqrt', 'model__n_estimators': 100}

Сравнение наборов гиперпараметров

In [12]:
# Обучение модели со старыми гипермараметрами
pipeline.fit(X_train, y_train)

# Предсказание для обучающей и тестовой выборки
y_train_predict = pipeline.predict(X_train)
y_test_predict = pipeline.predict(X_test)
        
# Вычисление метрик для модели со старыми гипермараметрами
base_model_metrics = {
    "Precision_train": metrics.precision_score(y_train, y_train_predict),
    "Precision_test": metrics.precision_score(y_test, y_test_predict),
    "Recall_train": metrics.recall_score(y_train, y_train_predict),
    "Recall_test": metrics.recall_score(y_test, y_test_predict),
    "Accuracy_train": metrics.accuracy_score(y_train, y_train_predict),
    "Accuracy_test": metrics.accuracy_score(y_test, y_test_predict),
    "F1_train": metrics.f1_score(y_train, y_train_predict),
    "F1_test": metrics.f1_score(y_test, y_test_predict),
    "ROC_AUC_test": metrics.roc_auc_score(y_test, y_test_predict),
    "Cohen_kappa_test": metrics.cohen_kappa_score(y_test, y_test_predict),
    "MCC_test": metrics.matthews_corrcoef(y_test, y_test_predict),
    "Confusion_matrix": metrics.confusion_matrix(y_test, y_test_predict),
}

# Модель с новыми гипермараметрами
optimized_model = RandomForestClassifier(
    random_state=42,
    criterion="gini",
    max_depth=5,
    max_features="sqrt",
    n_estimators=10,
)

# Создание конвейера для модели с новыми гипермараметрами
optimized_model_pipeline = Pipeline(
    [
        ("pipeline", pipeline_end), 
        ("model", optimized_model),
    ]
)
        
# Обучение модели с новыми гипермараметрами
optimized_model_pipeline.fit(X_train, y_train)
        
# Предсказание для обучающей и тестовой выборки
y_train_predict = optimized_model_pipeline.predict(X_train)
y_test_predict = optimized_model_pipeline.predict(X_test)
        
# Вычисление метрик для модели с новыми гипермараметрами
optimized_model_metrics = {
    "Precision_train": metrics.precision_score(y_train, y_train_predict),
    "Precision_test": metrics.precision_score(y_test, y_test_predict),
    "Recall_train": metrics.recall_score(y_train, y_train_predict),
    "Recall_test": metrics.recall_score(y_test, y_test_predict),
    "Accuracy_train": metrics.accuracy_score(y_train, y_train_predict),
    "Accuracy_test": metrics.accuracy_score(y_test, y_test_predict),
    "F1_train": metrics.f1_score(y_train, y_train_predict),
    "F1_test": metrics.f1_score(y_test, y_test_predict),
    "ROC_AUC_test": metrics.roc_auc_score(y_test, y_test_predict),
    "Cohen_kappa_test": metrics.cohen_kappa_score(y_test, y_test_predict),
    "MCC_test": metrics.matthews_corrcoef(y_test, y_test_predict),
    "Confusion_matrix": metrics.confusion_matrix(y_test, y_test_predict),
}

# Вывод информации
print('Стоковая модель:')
for metric_name, value in base_model_metrics.items():
    print(f"\t{metric_name}: {value}")

print('\nОптимизированная модель:')
for metric_name, value in optimized_model_metrics.items():
    print(f"\t{metric_name}: {value}")
Стоковая модель:
	Precision_train: 1.0
	Precision_test: 1.0
	Recall_train: 1.0
	Recall_test: 1.0
	Accuracy_train: 1.0
	Accuracy_test: 1.0
	F1_train: 1.0
	F1_test: 1.0
	ROC_AUC_test: 1.0
	Cohen_kappa_test: 1.0
	MCC_test: 1.0
	Confusion_matrix: [[58484     0]
 [    0  5475]]

Оптимизированная модель:
	Precision_train: 1.0
	Precision_test: 1.0
	Recall_train: 0.9995433372910768
	Recall_test: 0.9994520547945206
	Accuracy_train: 0.9999609124595444
	Accuracy_test: 0.9999530949514532
	F1_train: 0.9997716164984242
	F1_test: 0.9997259523157029
	ROC_AUC_test: 0.9997260273972604
	Cohen_kappa_test: 0.9997003049351247
	MCC_test: 0.9997003498302348
	Confusion_matrix: [[58484     0]
 [    3  5472]]