122 KiB
122 KiB
In [65]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Загрузка данных
data = pd.read_csv('./csv/option4.csv')
# Обзор данных
print("Количество колонок:", data.columns.size)
print("Колонки:", data.columns)
In [66]:
print("\nНаличие пропущенных значений:")
print(data.isnull().sum())
In [67]:
print(data.describe)
Возьмем и заменим нулевые значения в столбце bmi на средние значения по столбцу
In [68]:
data['bmi'] = data['bmi'].fillna(data['bmi'].median())
print("\nНаличие пропущенных значений:")
print(data.isnull().sum())
Взглянем на выбросы:
In [69]:
def plot_numeric_boxplots(dataframe, columns):
# Фильтрация числовых столбцов
numeric_columns = ['age', 'avg_glucose_level', 'bmi']
# Построение графиков
if numeric_columns:
plt.figure(figsize=(15, 5))
for i, col in enumerate(numeric_columns):
if col != 'id':
plt.subplot(1, len(numeric_columns), i + 1)
sns.boxplot(y=dataframe[col])
plt.title(f'{col}')
plt.ylabel('')
plt.xlabel(col)
plt.tight_layout()
plt.show()
else:
print("Нет подходящих числовых столбцов для построения графиков.")
plot_numeric_boxplots(data, data.columns)
Видим выбросы в столбцах со средним уровнем глюкозы и в столбце bmi (индекс массы тела). устраним выбросы - поставим верхние и нижние границы
In [70]:
def remove_outliers(df):
numeric_columns = ['age', 'avg_glucose_level', 'bmi']
for column in numeric_columns:
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
df[column] = df[column].apply(lambda x: lower_bound if x < lower_bound else upper_bound if x > upper_bound else x)
return df
data = remove_outliers(data)
plot_numeric_boxplots(data, data.columns)
Так, от выбросов избавились, теперь разобьем на выборки
In [71]:
from sklearn.model_selection import train_test_split
# Определение признаков и целевой переменной
X = data.drop(columns=['id', 'stroke'])
y = data['stroke']
# Обучающая выборка
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# Тестовая и контрольная выборки
X_test, X_control, y_test, y_control = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp)
print("\nРазмеры выборок:")
print(f"Обучающая выборка: {X_train.shape}")
print(f"Тестовая выборка: {X_test.shape}")
print(f"Контрольная выборка: {X_control.shape}")
In [74]:
import seaborn as sns
import matplotlib.pyplot as plt
# Подсчет количества объектов каждого класса
class_counts = y.value_counts()
print(class_counts)
# Визуализация
sns.barplot(x=class_counts.index, y=class_counts.values)
plt.title("Распределение классов (stroke)")
plt.xlabel("Класс")
plt.ylabel("Количество")
plt.show()
In [92]:
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
# 1. Увеличение меньшинственного класса
oversampler = RandomOverSampler(sampling_strategy=0.5, random_state=42) # Увеличиваем класс 1 до 50% от класса 0
X_train_over, y_train_over = oversampler.fit_resample(X_train, y_train)
print("После OverSampling:")
print(y_train_over.value_counts())
# 2. Уменьшение большинства
undersampler = RandomUnderSampler(sampling_strategy=1.0, random_state=42) # Балансируем классы 1:1
X_train_balanced, y_train_balanced = undersampler.fit_resample(X_train_over, y_train_over)
print("После комбинированного подхода (Over + Under Sampling):")
print(y_train_balanced.value_counts())
plt.pie(
y_train_balanced.value_counts(),
labels=class_counts.index, # Метки классов (0 и 1)
autopct='%1.1f%%', # Отображение процентов
colors=['skyblue', 'lightcoral'], # Цвета для классов
startangle=45, # Поворот диаграммы
explode=(0, 0.1) # Небольшое смещение для класса 1
)
plt.title("Распределение классов (stroke)")
plt.show()