188 KiB
Лабораторная 2¶
Первый датасет: информация о состоянии людей
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv("..\\static\\csv\\heart_2020_cleaned.csv")
print(df.columns)
Столбцы на русском:
HeartDisease - сердечная недостаточность
BMI - ИМТ
Smoking - курящий ли человек
AlcoholDrinking - выпивающий ли человек
Stroke - был ли инсульт
PhysicalHealth - физическое здоровье
MentalHealth - ментальное здоровье
DiffWalking - проблемы с ходьбой
Sex - пол
AgeCategory - возрастная категория
Race - раса
Diabetic - диабетик ли человек
PhysicalActivity - физическая активность
GenHealth - общее здоровье
SleepTime - время сна
Asthma - астматик ли человек
KidneyDisease - нефропатия
SkinCancer - рак кожи
df.info()
df.head()
Объект наблюдения: состояние человека
Атрибуты объектов: сердечная недостаточность, ИМТ, курящий человек или нет, выпивающий человек или нет, был ли инсульт у человека и т.д.
mean_menthalhealth = df.groupby('AgeCategory')['SleepTime'].mean().reset_index()
plt.figure(figsize=(14, 6))
plt.plot(mean_menthalhealth['AgeCategory'], mean_menthalhealth['SleepTime'], marker='.')
plt.title("Диаграмма 1")
plt.xlabel("Возрастная группа")
plt.ylabel("Время сна")
plt.show()
Между атрибутами присутствует связь. Пример, на диаграмме 1 - связь между возрастной группой и временем сна
Примеры бизнес-целей:
1. Прогнозирование инсульта на основе ИМТ.
2. Наблюдение за изменением времени сна в зависимости от возраста.
Эффект для бизнеса: влияние количества сна на здоровье, влияние ИМТ на здоровье, влияние возраста на инсульты
Цели технического проекта:
1. Первая бизнес-цель: вход - ИМТ, целевой признак - инсульт.
2. Вторая бизнес-цель: вход - возрастная группа, целевой признак - время сна.
Проверка на выбросы
null_values = df.isnull().sum()
print("Пустые значения по столбцам:")
print(null_values)
print("\nСтатистический обзор данных:")
df.describe()
На основе полученной информации видно, что пустых данных нет. Проверим данные на выбросы и дубликаты:
for column in df.select_dtypes(include=[np.number]).columns:
skewness = df[column].skew()
print(f"\nКоэффициент асимметрии для столбца '{column}': {skewness}")
duplicates = df.duplicated().sum()
print(f"\nКоличество дубликатов: {duplicates}")
На основе данных выше можно сказать, что выбросы незначительны. Удаляем все дубликаты.
cleaned_df = df.drop_duplicates()
Очищаем данные от шумов
plt.figure(figsize=(10, 6))
plt.scatter(cleaned_df['PhysicalHealth'], cleaned_df['BMI'])
plt.xlabel('Физическое здоровье')
plt.ylabel('ИМТ')
plt.title('Диаграмма рассеивания перед чисткой')
plt.show()
Q1 = cleaned_df["PhysicalHealth"].quantile(0.25)
Q3 = cleaned_df["PhysicalHealth"].quantile(0.75)
IQR = Q3 - Q1
threshold = 1.5 * IQR
lower_bound = Q1 - threshold
upper_bound = Q3 + threshold
outliers = (cleaned_df["PhysicalHealth"] < lower_bound) | (cleaned_df["PhysicalHealth"] > upper_bound)
print("Выбросы в датасете:")
print(cleaned_df[outliers])
median_score = cleaned_df["PhysicalHealth"].median()
cleaned_df.loc[outliers, "PhysicalHealth"] = median_score
plt.figure(figsize=(10, 6))
plt.scatter(cleaned_df['PhysicalHealth'], cleaned_df['BMI'])
plt.xlabel('Физическое здоровье')
plt.ylabel('ИМТ')
plt.title('Диаграмма рассеивания после чистки')
plt.show()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
from sklearn.model_selection import train_test_split
train_df, test_df = train_test_split(cleaned_df, test_size=0.2, random_state=42)
train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)
print("Размер обучающей выборки:", len(train_df))
print("Размер контрольной выборки:", len(val_df))
print("Размер тестовой выборки:", len(test_df))
Данные недостаточно сбалансированны
def check_balance(df, name):
counts = df['BMI'].value_counts()
print(f"Распределение ИМТ в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
def binning(target, bins):
return pd.qcut(target, q=bins, labels=False)
train_df['BMI_binned'] = binning(train_df['BMI'], bins=2)
val_df['BMI_binned'] = binning(val_df['BMI'], bins=2)
test_df['BMI_binned'] = binning(test_df['BMI'], bins=2)
def oversample(df, target_column):
X = df.drop(target_column, axis=1)
y = df[target_column]
oversampler = RandomOverSampler(random_state=42)
x_resampled, y_resampled = oversampler.fit_resample(X, y)
resampled_df = pd.concat([x_resampled, y_resampled], axis=1)
return resampled_df
def undersample(df, target_column):
X = df.drop(target_column, axis=1)
y = df[target_column]
undersampler = RandomUnderSampler(random_state=42)
x_resampled, y_resampled = undersampler.fit_resample(X, y)
resampled_df = pd.concat([x_resampled, y_resampled], axis=1)
return resampled_df
train_df_oversampled = oversample(train_df, 'BMI_binned')
val_df_oversampled = oversample(val_df, 'BMI_binned')
test_df_oversampled = oversample(test_df, 'BMI_binned')
train_df_undersampled = undersample(train_df, 'BMI_binned')
val_df_undersampled = undersample(val_df, 'BMI_binned')
test_df_undersampled = undersample(test_df, 'BMI_binned')
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")