MAI_ISE-31_Andrikhov-A-S/lab2.ipynb
2024-10-26 14:04:14 +04:00

422 KiB
Raw Blame History

Лабораторная работа 2. Анализ нескольких датасетов.

1.Выбрать три набора данных, которые не соответствуют Вашему варианту задания

Выбранны варианты: Данные по инсультам(Вариант 4), Продажи домов(Вариант 6), Цены на мобильные устройства (Вариант 18)

2. Провести анализ сведений о каждом наборе данных со страницы загрузки в Kaggle. Какова проблемная область?

Данные по инсультам:

  • Проблемная область: Анализ данных о пациентах с инсультом
  • Цели: Анализ данных о пациентах с инсультом, определение факторов, влияющих на шансы возникновения болезни
  • Набор данных: 5111 записей, 12 переменных:
    • id
    • gender
    • age
    • hypertension
    • heart_disease
    • ever_married
    • work_type
    • residence_typr
    • avg_glucose_level
    • bmi
    • smoking_status
    • stroke
  • Описание данных: Сведения о пациентах с инсультом, их образе жизни и медецинских показателях

Продажи домов:

  • Проблемная область: Анализ продаж домов и их цен в зависисмости от различных факторов
  • Цели: Анализ продаж домов, определение факторов влияющих на цены
  • Набор данных: 21614 записей, 21 переменная:
    • id
    • date
    • price
    • bedrooms
    • bathrooms
    • sqft_living
    • sqft_loft
    • floors
    • waterfront
    • view
    • condition
    • grade
    • sqft_above
    • sqft_basment
    • yr_build
    • yr_renovated
    • zipcode
    • lat
    • longsqft_living15
    • sqft_lot15
  • Описание данных: Сведения о проданных домах в King County, США

Цены на мобильные устройства:

  • Проблемная область: Анализ цен на мобильные устройства
  • Цели: Анализ цен на мобильные устройства, определение факторов, влияющих на цены
  • Набор данных: 1371 записей, 18 переменных:
    • id
    • name
    • rating
    • spec_score
    • no_of_sim
    • ram
    • battery
    • camera
    • external_memory
    • android_version
    • price
    • company
    • inbuild_memory
    • fast_charging
    • screen_resolution
    • processor
    • processor_name
  • Описание данных: Сведения о ценах на мобильные устройства в зависимости от различных характеристик

Данные по инсультам:

Каждая строка в датасете содержит соответствующую информацию о пациенте, что позволяет проводить анализ и строить модели для предсказания риска инсульта.

In [1]:
import pandas as pd

var4 =  pd.read_csv("./datasets/var4/healthcare-dataset-stroke-data.csv")
var4
Out[1]:
id gender age hypertension heart_disease ever_married work_type Residence_type avg_glucose_level bmi smoking_status stroke
0 9046 Male 67.0 0 1 Yes Private Urban 228.69 36.6 formerly smoked 1
1 51676 Female 61.0 0 0 Yes Self-employed Rural 202.21 NaN never smoked 1
2 31112 Male 80.0 0 1 Yes Private Rural 105.92 32.5 never smoked 1
3 60182 Female 49.0 0 0 Yes Private Urban 171.23 34.4 smokes 1
4 1665 Female 79.0 1 0 Yes Self-employed Rural 174.12 24.0 never smoked 1
... ... ... ... ... ... ... ... ... ... ... ... ...
5105 18234 Female 80.0 1 0 Yes Private Urban 83.75 NaN never smoked 0
5106 44873 Female 81.0 0 0 Yes Self-employed Urban 125.20 40.0 never smoked 0
5107 19723 Female 35.0 0 0 Yes Self-employed Rural 82.99 30.6 never smoked 0
5108 37544 Male 51.0 0 0 Yes Private Rural 166.29 25.6 formerly smoked 0
5109 44679 Female 44.0 0 0 Yes Govt_job Urban 85.28 26.2 Unknown 0

5110 rows × 12 columns

In [2]:
var4.dtypes
Out[2]:
id                     int64
gender                object
age                  float64
hypertension           int64
heart_disease          int64
ever_married          object
work_type             object
Residence_type        object
avg_glucose_level    float64
bmi                  float64
smoking_status        object
stroke                 int64
dtype: object

Продажи домов

Каждая строка в датасете содержит соответствующую информацию о доме, что позволяет проводить анализ и строить модели для предсказания его цены.

In [3]:
var6 = pd.read_csv("./datasets/var6/kc_house_data.csv")
var6
Out[3]:
id date price bedrooms bathrooms sqft_living sqft_lot floors waterfront view ... grade sqft_above sqft_basement yr_built yr_renovated zipcode lat long sqft_living15 sqft_lot15
0 7129300520 20141013T000000 221900.0 3 1.00 1180 5650 1.0 0 0 ... 7 1180 0 1955 0 98178 47.5112 -122.257 1340 5650
1 6414100192 20141209T000000 538000.0 3 2.25 2570 7242 2.0 0 0 ... 7 2170 400 1951 1991 98125 47.7210 -122.319 1690 7639
2 5631500400 20150225T000000 180000.0 2 1.00 770 10000 1.0 0 0 ... 6 770 0 1933 0 98028 47.7379 -122.233 2720 8062
3 2487200875 20141209T000000 604000.0 4 3.00 1960 5000 1.0 0 0 ... 7 1050 910 1965 0 98136 47.5208 -122.393 1360 5000
4 1954400510 20150218T000000 510000.0 3 2.00 1680 8080 1.0 0 0 ... 8 1680 0 1987 0 98074 47.6168 -122.045 1800 7503
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
21608 263000018 20140521T000000 360000.0 3 2.50 1530 1131 3.0 0 0 ... 8 1530 0 2009 0 98103 47.6993 -122.346 1530 1509
21609 6600060120 20150223T000000 400000.0 4 2.50 2310 5813 2.0 0 0 ... 8 2310 0 2014 0 98146 47.5107 -122.362 1830 7200
21610 1523300141 20140623T000000 402101.0 2 0.75 1020 1350 2.0 0 0 ... 7 1020 0 2009 0 98144 47.5944 -122.299 1020 2007
21611 291310100 20150116T000000 400000.0 3 2.50 1600 2388 2.0 0 0 ... 8 1600 0 2004 0 98027 47.5345 -122.069 1410 1287
21612 1523300157 20141015T000000 325000.0 2 0.75 1020 1076 2.0 0 0 ... 7 1020 0 2008 0 98144 47.5941 -122.299 1020 1357

21613 rows × 21 columns

In [4]:
var6.dtypes
Out[4]:
id                 int64
date              object
price            float64
bedrooms           int64
bathrooms        float64
sqft_living        int64
sqft_lot           int64
floors           float64
waterfront         int64
view               int64
condition          int64
grade              int64
sqft_above         int64
sqft_basement      int64
yr_built           int64
yr_renovated       int64
zipcode            int64
lat              float64
long             float64
sqft_living15      int64
sqft_lot15         int64
dtype: object

Цены на мобильные устройства

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

In [5]:
var18 = pd.read_csv("./datasets/var18/mobile_phone_price_prediction.csv")
var18
Out[5]:
Unnamed: 0 Name Rating Spec_score No_of_sim Ram Battery Display Camera External_Memory Android_version Price company Inbuilt_memory fast_charging Screen_resolution Processor Processor_name
0 0 Samsung Galaxy F14 5G 4.65 68 Dual Sim, 3G, 4G, 5G, VoLTE, 4 GB RAM 6000 mAh Battery 6.6 inches 50 MP + 2 MP Dual Rear & 13 MP Front Camera Memory Card Supported, upto 1 TB 13 9,999 Samsung 128 GB inbuilt 25W Fast Charging 2408 x 1080 px Display with Water Drop Notch Octa Core Processor Exynos 1330
1 1 Samsung Galaxy A11 4.20 63 Dual Sim, 3G, 4G, VoLTE, 2 GB RAM 4000 mAh Battery 6.4 inches 13 MP + 5 MP + 2 MP Triple Rear & 8 MP Fro... Memory Card Supported, upto 512 GB 10 9,990 Samsung 32 GB inbuilt 15W Fast Charging 720 x 1560 px Display with Punch Hole 1.8 GHz Processor Octa Core
2 2 Samsung Galaxy A13 4.30 75 Dual Sim, 3G, 4G, VoLTE, 4 GB RAM 5000 mAh Battery 6.6 inches 50 MP Quad Rear & 8 MP Front Camera Memory Card Supported, upto 1 TB 12 11,999 Samsung 64 GB inbuilt 25W Fast Charging 1080 x 2408 px Display with Water Drop Notch 2 GHz Processor Octa Core
3 3 Samsung Galaxy F23 4.10 73 Dual Sim, 3G, 4G, VoLTE, 4 GB RAM 6000 mAh Battery 6.4 inches 48 MP Quad Rear & 13 MP Front Camera Memory Card Supported, upto 1 TB 12 11,999 Samsung 64 GB inbuilt NaN 720 x 1600 px Octa Core Helio G88
4 4 Samsung Galaxy A03s (4GB RAM + 64GB) 4.10 69 Dual Sim, 3G, 4G, VoLTE, 4 GB RAM 5000 mAh Battery 6.5 inches 13 MP + 2 MP + 2 MP Triple Rear & 5 MP Fro... Memory Card Supported, upto 1 TB 11 11,999 Samsung 64 GB inbuilt 15W Fast Charging 720 x 1600 px Display with Water Drop Notch Octa Core Helio P35
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1365 1365 TCL 40R 4.05 75 Dual Sim, 3G, 4G, 5G, VoLTE, 4 GB RAM 5000 mAh Battery 6.6 inches 50 MP + 2 MP + 2 MP Triple Rear & 8 MP Fro... Memory Card (Hybrid) 12 18,999 TCL 64 GB inbuilt 15W Fast Charging 720 x 1612 px Octa Core Dimensity 700 5G
1366 1366 TCL 50 XL NxtPaper 5G 4.10 80 Dual Sim, 3G, 4G, VoLTE, 8 GB RAM 5000 mAh Battery 6.8 inches 50 MP + 2 MP Dual Rear & 16 MP Front Camera Memory Card (Hybrid) 14 24,990 TCL 128 GB inbuilt 33W Fast Charging 1200 x 2400 px Octa Core Dimensity 7050
1367 1367 TCL 50 XE NxtPaper 5G 4.00 80 Dual Sim, 3G, 4G, 5G, VoLTE, 6 GB RAM 5000 mAh Battery 6.6 inches 50 MP + 2 MP Dual Rear & 16 MP Front Camera Memory Card Supported, upto 1 TB 13 23,990 TCL 256 GB inbuilt 18W Fast Charging 720 x 1612 px Octa Core Dimensity 6080
1368 1368 TCL 40 NxtPaper 5G 4.50 79 Dual Sim, 3G, 4G, 5G, VoLTE, 6 GB RAM 5000 mAh Battery 6.6 inches 50 MP + 2 MP + 2 MP Triple Rear & 8 MP Fro... Memory Card Supported, upto 1 TB 13 22,499 TCL 256 GB inbuilt 15W Fast Charging 720 x 1612 px Octa Core Dimensity 6020
1369 1369 TCL Trifold 4.65 93 Dual Sim, 3G, 4G, 5G, VoLTE, Vo5G, 12 GB RAM 4600 mAh Battery 10 inches Foldable Display, Dual Display 50 MP + 48 MP + 8 MP Triple Rear & 32 MP F... 13 1,19,990 TCL 256 GB inbuilt 67W Fast Charging 1916 x 2160 px Octa Core Snapdragon 8 Gen2

1370 rows × 18 columns

In [6]:
var18.dtypes
Out[6]:
Unnamed: 0             int64
Name                  object
Rating               float64
Spec_score             int64
No_of_sim             object
Ram                   object
Battery               object
Display               object
Camera                object
External_Memory       object
Android_version       object
Price                 object
company               object
Inbuilt_memory        object
fast_charging         object
Screen_resolution     object
Processor             object
Processor_name        object
dtype: object

3. Провести анализ содержимого каждого набора данных. Что является объектом/объектами наблюдения? Каковы атрибуты объектов? Есть ли связи между объектами?

  1. Датасет о риске инсульта
    • Объект наблюдения: Пациенты
  2. Датасет о продажах недвижимости
    • Объект наблюдения: Сделки по проданным домам в King Country, США
  3. Датасет о цене мобильных устройств
    • Объект наблюдения: Модели телефонов и их цены

Все аттрибуты были перечислены выше.

4. Привести примеры бизнес-целей, для достижения которых могут подойти выбранные наборы данных. Каков эффект для бизнеса?

  1. Датасет о риске инсульта
    • Бизнес-цель: Определить факторы риска инсульта и предохранить пациентов от инсульта.
    • Эффект для бизнеса: Снижение количества случаев инсульта, снижение затрат на лечение и улучшение репутации клиники.
  2. Датасет о продажах недвижимости
    • Бизнес-цель: Определить факторы, влияющие на продажи недвижимости
    • Эффект для бизнеса: Улучшение стратегии продаж, повышение эффективности подбора имущества для последующего извлесения прибыли
  3. Датасет о цене мобильных устройств
    • Бизнес-цель: Определить факторы, влияющие на цену мобильных устройств
    • Эффект для бизнеса: Улучшение стратегии ценообразования, повышение эффективности продаж и прибыли.

5. Привести примеры целей технического проекта для каждой выделенной ранее бизнес-цели. Что поступает на вход, что является целевым признаком?

  1. Датасет о риске инсульта
    • Цель технического проекта: Создание модели машинного обучения для прогнозирования вероятности инсульта.
    • Входные данные: Пол Возраст Наличие гипертензии Наличие сердечных заболеваний Статус брака Тип работы Тип проживания Средний уровень глюкозы Индекс массы тела Статус курения и т.д.
    • Целевой признак: Случался ли инсульт (stroke).
  2. Датасет о продажах недвижимости
    • Цель технического проекта: Разработка модели машинного обучения для прогнозирования цены недвижимости.
    • Входные данные: Площадь Площадь комнат Площадь участка Тип дома Тип комнат и другие признаки.
    • Целевой признак: Цена недвижимости (Price).
  3. Датасет о цене мобильных устройств
    • Цель технического проекта: Построение модели для предсказания рекомендованной цены мобильного устройства на основе характеристик.
    • Входные данные: Имя Рейтинг Очки производительности Кол-во SIM-слотов Оперативная память Емкость аккумклятора Дисплей Камера Дополнительные слоты для карт памяти и остальное.
    • Целевой признак: Очки производительности (Spec_score).

6. Определить проблемы выбранных наборов данных: зашумленность, смещение, актуальность, выбросы, просачивание данных.

7. Привести примеры решения обнаруженных проблем для каждого набора данных¶

In [7]:
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

# 1. Проверка на зашумленность ---- количество пропусков в процентах от общего кол-ва
def check_noise(dataframe):
    total_values = dataframe.size
    missing_values = dataframe.isnull().sum().sum()
    noise_percentage = (missing_values / total_values) * 100
    return f"Зашумленность: {noise_percentage:.2f}%"

# 2. Проверка на смещение ----- объем уникальных значений внутри определнной колонки 
def check_bias(dataframe, target_column):
    if target_column in dataframe.columns:
        unique_values = dataframe[target_column].nunique()
        total_values = len(dataframe)
        bias_percentage = (unique_values / total_values) * 100
        return f"Смещение по {target_column}: {bias_percentage:.2f}% уникальных значений"
    return "Целевой признак не найден."

# 3. Проверка на дубликаты
def check_duplicates(dataframe):
    duplicate_percentage = dataframe.duplicated().mean() * 100
    return f"Количество дубликатов: {duplicate_percentage:.2f}%"

# 4. Проверка на выбросы
def check_outliers(dataframe, column):
    if column in dataframe.columns:
        Q1 = dataframe[column].quantile(0.25)
        Q3 = dataframe[column].quantile(0.75)
        IQR = Q3 - Q1
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        outlier_count = dataframe[(dataframe[column] < lower_bound) | (dataframe[column] > upper_bound)].shape[0]
        total_count = dataframe.shape[0]
        outlier_percentage = (outlier_count / total_count) * 100
        return f"Выбросы по {column}: {outlier_percentage:.2f}%"
    return f"Признак {column} не найден."

# 5. Проверка на просачивание данных
def check_data_leakage(dataframe, target_column):
    if target_column in dataframe.columns:
        correlation_matrix = dataframe.select_dtypes(include=[np.number]).corr()
        leakage_info = correlation_matrix[target_column].abs().nlargest(10)
        leakage_report = ", ".join([f"{feature}: {value:.2f}" for feature, value in leakage_info.items() if feature != target_column])
        return f"Признаки просачивания данных: {leakage_report}"
    return "Целевой признак не найден."

Датасет о риске инсульта:

In [8]:
noise_columns = check_noise(var4)
bias_info = check_bias(var4, 'avg_glucose_level') 
duplicate_count = check_duplicates(var4)
outliers_data = check_outliers(var4, 'avg_glucose_level')  
leakage_info = check_data_leakage(var4, 'stroke') 

print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Зашумленность: 0.33%
Смещение по avg_glucose_level: 77.87% уникальных значений
Количество дубликатов: 0.00%
Выбросы по avg_glucose_level: 12.27%
Признаки просачивания данных: age: 0.25, heart_disease: 0.13, avg_glucose_level: 0.13, hypertension: 0.13, bmi: 0.04, id: 0.01

Датасет о продажах недвижимости:

In [9]:
noise_columns = check_noise(var6)
bias_info = check_bias(var6, 'price') 
duplicate_count = check_duplicates(var6)
outliers_data = check_outliers(var6, 'yr_renovated')  
leakage_info = check_data_leakage(var6, 'condition') 

print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Зашумленность: 0.00%
Смещение по price: 18.64% уникальных значений
Количество дубликатов: 0.00%
Выбросы по yr_renovated: 4.23%
Признаки просачивания данных: yr_built: 0.36, floors: 0.26, sqft_basement: 0.17, sqft_above: 0.16, grade: 0.14, bathrooms: 0.12, long: 0.11, sqft_living15: 0.09, yr_renovated: 0.06

Датасет о цене мобильных устройств:

In [10]:
noise_columns = check_noise(var18)
bias_info = check_bias(var18, 'company') 
duplicate_count = check_duplicates(var18)
outliers_data = check_outliers(var18, 'Spec_score')  
leakage_info = check_data_leakage(var18, 'Rating') 

print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Зашумленность: 2.36%
Смещение по company: 1.90% уникальных значений
Количество дубликатов: 0.00%
Выбросы по Spec_score: 1.24%
Признаки просачивания данных: Spec_score: 0.06, Unnamed: 0: 0.03

9. Устранить проблему пропущенных данных. Для каждого набора данных использовать разные методы: удаление, подстановка константного значения (0 или подобное), подстановка среднего значения

In [11]:
# Инсульт
var4.isnull().sum()
Out[11]:
id                     0
gender                 0
age                    0
hypertension           0
heart_disease          0
ever_married           0
work_type              0
Residence_type         0
avg_glucose_level      0
bmi                  201
smoking_status         0
stroke                 0
dtype: int64
In [12]:
var4['bmi'] = var4['bmi'].fillna(var4['bmi'].mean())
In [13]:
var4.isnull().sum()
Out[13]:
id                   0
gender               0
age                  0
hypertension         0
heart_disease        0
ever_married         0
work_type            0
Residence_type       0
avg_glucose_level    0
bmi                  0
smoking_status       0
stroke               0
dtype: int64
In [14]:
#Дома
var6.isnull().sum()
Out[14]:
id               0
date             0
price            0
bedrooms         0
bathrooms        0
sqft_living      0
sqft_lot         0
floors           0
waterfront       0
view             0
condition        0
grade            0
sqft_above       0
sqft_basement    0
yr_built         0
yr_renovated     0
zipcode          0
lat              0
long             0
sqft_living15    0
sqft_lot15       0
dtype: int64
In [15]:
#Мобильные устройства
var18.isnull().sum()
Out[15]:
Unnamed: 0             0
Name                   0
Rating                 0
Spec_score             0
No_of_sim              0
Ram                    0
Battery                0
Display                0
Camera                 0
External_Memory        0
Android_version      443
Price                  0
company                0
Inbuilt_memory        19
fast_charging         89
Screen_resolution      2
Processor             28
Processor_name         0
dtype: int64
In [16]:
var18['Android_version'] = var18['Android_version'].fillna('No info')
var18['Inbuilt_memory'] = var18['Inbuilt_memory'].fillna('No info')
var18['fast_charging'] = var18['fast_charging'].fillna('No info')
var18['Screen_resolution'] = var18['Screen_resolution'].fillna('No info')
var18['Processor'] = var18['Processor'].fillna('No info')
In [17]:
var18.isnull().sum()
Out[17]:
Unnamed: 0           0
Name                 0
Rating               0
Spec_score           0
No_of_sim            0
Ram                  0
Battery              0
Display              0
Camera               0
External_Memory      0
Android_version      0
Price                0
company              0
Inbuilt_memory       0
fast_charging        0
Screen_resolution    0
Processor            0
Processor_name       0
dtype: int64

10. Выполнить разбиение каждого набора данных на обучающую, контрольную и тестовую выборки¶

In [18]:
from sklearn.model_selection import train_test_split
In [19]:
# Разбиение var4 (Инсульт)

original_var4_size = len(var4)
train_var4, temp_var4 = train_test_split(var4, test_size=0.2, random_state=42)
val_var4, test_var4 = train_test_split(temp_var4, test_size=0.5, random_state=42)

print("var4 Dataset:")
print(f"Train: {len(train_var4)/original_var4_size*100:.2f}%")
print(f"Validation: {len(val_var4)/original_var4_size*100:.2f}%")
print(f"Test: {len(test_var4)/original_var4_size*100:.2f}%\n")
var4 Dataset:
Train: 80.00%
Validation: 10.00%
Test: 10.00%

In [20]:
# Разбиение var6 (Дома)
original_var6_size = len(var6)
train_var6, temp_var6 = train_test_split(var6, test_size=0.2, random_state=42)
val_var6, test_var6 = train_test_split(temp_var6, test_size=0.5, random_state=42)

print("var6 Dataset:")
print(f"Train: {len(train_var6)/original_var6_size*100:.2f}%")
print(f"Validation: {len(val_var6)/original_var6_size*100:.2f}%")
print(f"Test: {len(test_var6)/original_var6_size*100:.2f}%\n")
var6 Dataset:
Train: 80.00%
Validation: 10.00%
Test: 10.00%

In [21]:
# Разбиение var18 (Мобильные устройства)
original_var18_size = len(var18)
train_var18, temp_var18 = train_test_split(var18, test_size=0.2, random_state=42)
val_var18, test_var18 = train_test_split(temp_var18, test_size=0.5, random_state=42)

print("var18 Dataset:")
print(f"Train: {len(train_var18)/original_var18_size*100:.2f}%")
print(f"Validation: {len(val_var18)/original_var18_size*100:.2f}%")
print(f"Test: {len(test_var18)/original_var18_size*100:.2f}%\n")
var18 Dataset:
Train: 80.00%
Validation: 10.00%
Test: 10.00%

11. Оценить сбалансированность выборок для каждого набора данных. Оценить необходимость использования методов приращения (аугментации) данных.

12. Выполнить приращение данных методами выборки с избытком (oversampling) и выборки с недостатком (undersampling). Должны быть представлены примеры реализации обоих методов для выборок каждого набора данных.

In [22]:
def plot_sample_balance(y, sample_name):
    plt.figure(figsize=(8, 5))
    sns.histplot(y, bins=30, kde=True)
    plt.title(f'Распределение целевой переменной для {sample_name}')
    plt.xlabel(sample_name)
    plt.ylabel('Частота')
    plt.show()

# Оценка сбалансированности выборок
plot_sample_balance(train_var6['price'], 'Train var6')
plot_sample_balance(val_var6['price'], 'Validation var6')
plot_sample_balance(test_var6['price'], 'Test var6')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Распределения выборок у данного датасета выглядят схоже. Это говорит о сбалансированности выборок.

In [23]:
plot_sample_balance(train_var4['stroke'], 'Train var4')
plot_sample_balance(val_var4['stroke'], 'Validation var4')
plot_sample_balance(test_var4['stroke'], 'Test var4')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

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

In [24]:
plot_sample_balance(train_var18['Spec_score'], 'Train var18')
plot_sample_balance(val_var18['Spec_score'], 'Validation var18')
plot_sample_balance(test_var18['Spec_score'], 'Test var18')
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

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

12. Выполнить приращение данных методами выборки с избытком (oversampling) и выборки с недостатком (undersampling). Должны быть представлены примеры реализации обоих методов для выборок каждого набора данных

Инсульт

In [25]:
from imblearn.over_sampling import SMOTE

X_var4 = var4.drop('stroke', axis=1)
y_var4 = var4['stroke']

# Кодирование категориальных признаков
for column in X_var4.select_dtypes(include=['object']).columns:
    X_var4[column] = X_var4[column].astype('category').cat.codes

# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_var4, y_resampled_var4 = smote.fit_resample(X_var4, y_var4)

# Получаем результаты
print(f'После oversampling (var4): {pd.Series(y_resampled_var4).value_counts()}')
После oversampling (var4): stroke
1    4861
0    4861
Name: count, dtype: int64
In [26]:
from imblearn.under_sampling import RandomUnderSampler

# Undersampling для var4
undersample = RandomUnderSampler(random_state=42)
X_under_var4, y_under_var4 = undersample.fit_resample(X_var4, y_var4)

print(f'После undersampling (var4): {pd.Series(y_under_var4).value_counts()}')
После undersampling (var4): stroke
0    249
1    249
Name: count, dtype: int64

Дома

In [27]:
X_var6 = var6.drop('Price', axis=1)
y_var6 = var6['Price']

# Кодирование категориальных признаков
for column in X_var6.select_dtypes(include=['object']).columns:
    X_var6[column] = X_var6[column].astype('category').cat.codes

# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_var6, y_resampled_var6 = smote.fit_resample(X_var6, y_var6)

# Получаем результаты
print(f'После oversampling (var6): {pd.Series(y_resampled_var6).value_counts()}')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[27], line 1
----> 1 X_var6 = var6.drop('Price', axis=1)
      2 y_var6 = var6['Price']
      4 # Кодирование категориальных признаков

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\pandas\core\frame.py:5581, in DataFrame.drop(self, labels, axis, index, columns, level, inplace, errors)
   5433 def drop(
   5434     self,
   5435     labels: IndexLabel | None = None,
   (...)
   5442     errors: IgnoreRaise = "raise",
   5443 ) -> DataFrame | None:
   5444     """
   5445     Drop specified labels from rows or columns.
   5446 
   (...)
   5579             weight  1.0     0.8
   5580     """
-> 5581     return super().drop(
   5582         labels=labels,
   5583         axis=axis,
   5584         index=index,
   5585         columns=columns,
   5586         level=level,
   5587         inplace=inplace,
   5588         errors=errors,
   5589     )

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\pandas\core\generic.py:4788, in NDFrame.drop(self, labels, axis, index, columns, level, inplace, errors)
   4786 for axis, labels in axes.items():
   4787     if labels is not None:
-> 4788         obj = obj._drop_axis(labels, axis, level=level, errors=errors)
   4790 if inplace:
   4791     self._update_inplace(obj)

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\pandas\core\generic.py:4830, in NDFrame._drop_axis(self, labels, axis, level, errors, only_slice)
   4828         new_axis = axis.drop(labels, level=level, errors=errors)
   4829     else:
-> 4830         new_axis = axis.drop(labels, errors=errors)
   4831     indexer = axis.get_indexer(new_axis)
   4833 # Case for non-unique axis
   4834 else:

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\pandas\core\indexes\base.py:7070, in Index.drop(self, labels, errors)
   7068 if mask.any():
   7069     if errors != "ignore":
-> 7070         raise KeyError(f"{labels[mask].tolist()} not found in axis")
   7071     indexer = indexer[~mask]
   7072 return self.delete(indexer)

KeyError: "['Price'] not found in axis"
In [ ]:
X_var18 = var18.drop('Price', axis=1)
y_var18 = var18['Price']

# Кодирование категориальных признаков
for column in X_var18.select_dtypes(include=['object']).columns:
    X_var18[column] = X_var18[column].astype('category').cat.codes

# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_var18, y_resampled_var18 = smote.fit_resample(X_var18, y_var18)

# Получаем результаты
print(f'После oversampling (var18): {pd.Series(y_resampled_var18).value_counts()}')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[69], line 10
      8 # Теперь применяем SMOTE
      9 smote = SMOTE(random_state=42)
---> 10 X_resampled_var18, y_resampled_var18 = smote.fit_resample(X_var18, y_var18)
     12 # Получаем результаты
     13 print(f'После oversampling (var18): {pd.Series(y_resampled_var18).value_counts()}')

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\imblearn\base.py:208, in BaseSampler.fit_resample(self, X, y)
    187 """Resample the dataset.
    188 
    189 Parameters
   (...)
    205     The corresponding label of `X_resampled`.
    206 """
    207 self._validate_params()
--> 208 return super().fit_resample(X, y)

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\imblearn\base.py:112, in SamplerMixin.fit_resample(self, X, y)
    106 X, y, binarize_y = self._check_X_y(X, y)
    108 self.sampling_strategy_ = check_sampling_strategy(
    109     self.sampling_strategy, y, self._sampling_type
    110 )
--> 112 output = self._fit_resample(X, y)
    114 y_ = (
    115     label_binarize(output[1], classes=np.unique(y)) if binarize_y else output[1]
    116 )
    118 X_, y_ = arrays_transformer.transform(output[0], y_)

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\imblearn\over_sampling\_smote\base.py:389, in SMOTE._fit_resample(self, X, y)
    386 X_class = _safe_indexing(X, target_class_indices)
    388 self.nn_k_.fit(X_class)
--> 389 nns = self.nn_k_.kneighbors(X_class, return_distance=False)[:, 1:]
    390 X_new, y_new = self._make_samples(
    391     X_class, y.dtype, class_sample, X_class, nns, n_samples, 1.0
    392 )
    393 X_resampled.append(X_new)

File c:\Users\HomePC\Desktop\MII_Lab1\.venv\Lib\site-packages\sklearn\neighbors\_base.py:834, in KNeighborsMixin.kneighbors(self, X, n_neighbors, return_distance)
    832     else:
    833         inequality_str = "n_neighbors <= n_samples_fit"
--> 834     raise ValueError(
    835         f"Expected {inequality_str}, but "
    836         f"n_neighbors = {n_neighbors}, n_samples_fit = {n_samples_fit}, "
    837         f"n_samples = {X.shape[0]}"  # include n_samples for common tests
    838     )
    840 n_jobs = effective_n_jobs(self.n_jobs)
    841 chunked_results = None

ValueError: Expected n_neighbors <= n_samples_fit, but n_neighbors = 6, n_samples_fit = 1, n_samples = 1
In [ ]:
from imblearn.under_sampling import RandomUnderSampler

# Undersampling для var4
undersample = RandomUnderSampler(random_state=42)
X_under_var4, y_under_var4 = undersample.fit_resample(X_var4, y_var4)

print(f'После undersampling (var4): {pd.Series(y_under_var4).value_counts()}')
После undersampling (var4): stroke
0    249
1    249
Name: count, dtype: int64

В данном случае у нас есть только один датасет, предназначенный для решения задачи классификации (инсульт). Проблему дисбаланса в нем мы решили применив undersampling & oversampling.

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