/
urfu_itis_limits
/
code-review-101-pentomas
Обзор
Документация
Войти
/
urfu_itis_limits
/
code-review-101-pentomas
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
assignment.py
271 строка
10 KB
pentomas
update assignment.py
18 ноя 2025, 08:31
18 ноя 2025, 08:31
4ab5808
Код
Авторство
О чём код?
""" Задание 9: Анализ датасета Heart Disease - ШАБЛОН Цель: Анализ данных сердечных заболеваний - бинарная классификация ЗАДАЧИ: 1. Загрузить данные в load_data() 2. Получить информацию о датасете в data_info() 3. Анализировать целевую переменную в target_analysis() 4. Вычислить статистику признаков в feature_statistics() 5. Визуализировать целевую переменную в visualize_target() 6. Визуализировать медицинские показатели в visualize_numeric_features() 7. Создать boxplots признаков по статусу болезни в features_by_target() 8. Вычислить корреляции в correlation_analysis() 9. Провести анализ возраста и пола в age_analysis() """ import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datasets import load_dataset plt.rcParams['font.sans-serif'] = ['DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False def load_data(): """Загрузить датасет Heart Disease""" # Загрузить датасет "nezahatkorkmaz/heart-disease-dataset" dataset = load_dataset("nezahatkorkmaz/heart-disease-dataset") # Конвертировать в pandas DataFrame df = pd.DataFrame(dataset['train']) return df def data_info(df): """Получить общую информацию о датасете""" print(f"Размер датасета: {df.shape}") print(f"\nТипы данных:\n{df.dtypes}") print(f"\nПропущенные значения:\n{df.isnull().sum()}") def target_analysis(df): """Анализ целевой переменной""" # Найти целевой столбец (обычно 'target', 'disease', 'num' или 'class') target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col is None: # Если не найден, предположим, что это последний столбец target_col = df.columns[-1] print(f"Целевой столбец: {target_col}") print(f"\nРаспределение целевой переменной:\n{df[target_col].value_counts()}") print(f"\nПроценты классов:\n{df[target_col].value_counts(normalize=True) * 100}") def feature_statistics(df): """Вычислить статистику по медицинским показателям""" # Определить числовые признаки numeric_features = df.select_dtypes(include=[np.number]).columns.tolist() # Исключить целевую переменную, если она числовая target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col and target_col in numeric_features: numeric_features.remove(target_col) stats = df[numeric_features].describe() print(f"Статистика по числовым признакам:\n{stats}") def visualize_target(df): """Визуализировать целевую переменную""" # Найти целевой столбец target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col is None: target_col = df.columns[-1] fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) # Столбчатая диаграмма df[target_col].value_counts().plot(kind='bar', ax=ax1) ax1.set_title('Распределение целевой переменной') ax1.set_xlabel(target_col) ax1.set_ylabel('Количество') # Круговая диаграмма df[target_col].value_counts().plot(kind='pie', ax=ax2, autopct='%1.1f%%') ax2.set_title('Процентное распределение целевой переменной') ax2.set_ylabel('') plt.tight_layout() plt.savefig('09_heart_disease_target_distribution.png') plt.show() def visualize_numeric_features(df): """Визуализировать медицинские показатели""" # Определить числовые признаки numeric_features = df.select_dtypes(include=[np.number]).columns.tolist() # Исключить целевую переменную, если она числовая target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col and target_col in numeric_features: numeric_features.remove(target_col) # Ограничимся первыми 8 числовыми признаками для сетки 2x4 features_to_plot = numeric_features[:8] fig, axes = plt.subplots(2, 4, figsize=(16, 8)) axes = axes.ravel() for i, feature in enumerate(features_to_plot): if i < len(axes): df[feature].hist(bins=20, ax=axes[i]) axes[i].set_title(f'Распределение {feature}') axes[i].set_xlabel(feature) axes[i].set_ylabel('Частота') # Убираем пустые subplot'ы, если признаков меньше 8 for j in range(len(features_to_plot), len(axes)): fig.delaxes(axes[j]) plt.tight_layout() plt.savefig('09_heart_disease_features_distribution.png') plt.show() def features_by_target(df): """Boxplot признаков по наличию болезни""" # Найти целевой столбец target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col is None: target_col = df.columns[-1] # Определить числовые признаки numeric_features = df.select_dtypes(include=[np.number]).columns.tolist() if target_col in numeric_features: numeric_features.remove(target_col) # Ограничимся первыми 6 числовыми признаками для сетки 2x3 features_to_plot = numeric_features[:6] fig, axes = plt.subplots(2, 3, figsize=(15, 10)) axes = axes.ravel() for i, feature in enumerate(features_to_plot): if i < len(axes): sns.boxplot(x=target_col, y=feature, data=df, ax=axes[i]) axes[i].set_title(f'{feature} по статусу болезни') # Убираем пустые subplot'ы, если признаков меньше 6 for j in range(len(features_to_plot), len(axes)): fig.delaxes(axes[j]) plt.tight_layout() plt.savefig('09_heart_disease_features_by_target.png') plt.show() def correlation_analysis(df): """Анализ корреляций""" # Найти целевой столбец target_col = None for col in df.columns: if col.lower() in ['target', 'disease', 'num', 'class', 'condition']: target_col = col break if target_col is None: target_col = df.columns[-1] # Вычислить корреляцию каждого признака с целевой переменной correlations = df.corr()[target_col].abs().sort_values(ascending=False) print("Топ 10 корреляций с целевой переменной:") print(correlations.head(10)) # Создать горизонтальную диаграмму корреляций (без самой целевой переменной) top_corr = correlations.drop(target_col).head(10) plt.figure(figsize=(10, 6)) top_corr.plot(kind='barh') plt.title('Топ корреляций с целевой переменной') plt.xlabel('Корреляция (абсолютное значение)') plt.tight_layout() plt.savefig('09_heart_disease_correlation_bars.png') plt.show() def age_analysis(df): """Специальный анализ возраста и пола""" # Найти столбцы возраста и пола age_col = None sex_col = None for col in df.columns: if 'age' in col.lower(): age_col = col elif col.lower() in ['sex', 'gender', 'male', 'female']: sex_col = col if age_col: print(f"Средний возраст: {df[age_col].mean():.2f}") fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) # Гистограмма возраста df[age_col].hist(bins=20, ax=ax1) ax1.set_title('Распределение возраста') ax1.set_xlabel('Возраст') ax1.set_ylabel('Частота') # Столбчатая диаграмма по полу if sex_col: df[sex_col].value_counts().plot(kind='bar', ax=ax2) ax2.set_title('Распределение по полу') ax2.set_xlabel(sex_col) ax2.set_ylabel('Количество') ax2.tick_params(axis='x', rotation=0) else: ax2.text(0.5, 0.5, 'Столбец пола не найден', horizontalalignment='center', verticalalignment='center', transform=ax2.transAxes) ax2.set_title('Распределение по полу') plt.tight_layout() plt.savefig('09_heart_disease_demographics.png') plt.show() else: print("Столбец возраста не найден в датасете.") def main(): """Главная функция""" print("=" * 60) print("ЗАДАНИЕ 9: EXPLORATORY DATA ANALYSIS - HEART DISEASE DATASET") print("=" * 60) df = load_data() data_info(df) target_analysis(df) feature_statistics(df) visualize_target(df) visualize_numeric_features(df) features_by_target(df) correlation_analysis(df) age_analysis(df) print("\n" + "=" * 60) print("Анализ завершен!") print("=" * 60) if __name__ == "__main__": main()