PIbd-33_Dyakonov_R_R_MAI/lab2.2.ipynb
dyakonovr 851ccb3e02 done
2024-10-07 12:45:24 +04:00

117 KiB
Raw Blame History

Датасет 1. Цены мобильных телефонов

  1. Name: Название модели мобильного телефона.
  2. Rating: Рейтинг мобильного телефона (по отзывам пользователей).
  3. Spec_score: Оценка спецификаций телефона (возможно, по различным характеристикам).
  4. No_of_sim: Количество SIM-карт, поддерживаемых телефоном.
  5. Ram: Объем оперативной памяти (RAM) в гигабайтах.
  6. Battery: Емкость батареи в мАч.
  7. Display: Размер дисплея в дюймах.
  8. Camera: Разрешение камеры (в мегапикселях).
  9. External_Memory: Поддержка внешней памяти (да/нет).
  10. Android_version: Версия операционной системы Android.
  11. Price: Цена мобильного телефона в долларах США.
  12. Company: Производитель телефона.
  13. Inbuilt_memory: Объем встроенной памяти (в гигабайтах).
  14. Fast_charging: Наличие быстрой зарядки (да/нет).
  15. Screen_resolution: Разрешение экрана (в пикселях).
  16. Processor: Тип процессора.
  17. Processor_name: Наименование процессора.

Объект наблюдения: Каждый объект представляет собой отдельный мобильный телефон.

Связи между объектами: Внутри одного объекта есть взаимосвязь между характеристиками и его ценой. Например, объем оперативной памяти, емкость батареи, качество камеры и поддержка быстрой зарядки могут влиять на цену.

Бизнес-цель: Оптимизация продаж мобильных телефонов, оценка цен в зависимости от характеристик.

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

Техническая цель: Построение модели машинного обучения для прогнозирования цены мобильного телефона на основе его характеристик.

  • Вход: Характеристики мобильного телефона (объем RAM, емкость батареи, качество камеры и т.д.).
  • Целевой признак: Цена мобильного телефона.

Информативность: Высокая. Набор данных содержит важные характеристики мобильных телефонов, которые влияют на их цену.

Степень покрытия: Высокая. Датасет включает разнообразные модели телефонов, что позволяет провести полноценный анализ.

Соответствие реальным данным: Высокая. Характеристики мобильных телефонов в наборе данных соответствуют реальным характеристикам, определяемым производителями.

Согласованность меток: Высокая. Датасет не содержит проблем с несогласованностью меток, так как все данные соответствуют описанию в заголовках столбцов.


Датасет 2. Прогнозирование цен на автомобили

  1. make: Производитель автомобиля.
  2. model: Модель автомобиля.
  3. year: Год выпуска автомобиля.
  4. mileage: Пробег автомобиля в километрах.
  5. engine_size: Объем двигателя в литрах.
  6. horsepower: Мощность двигателя в лошадиных силах.
  7. fuel_type: Тип топлива (бензин, дизель и др.).
  8. transmission: Тип трансмиссии (механическая или автоматическая).
  9. color: Цвет автомобиля.
  10. body_type: Тип кузова (седан, хэтчбек, внедорожник и др.).
  11. price: Цена автомобиля в долларах США.

Объект наблюдения: Каждый объект представляет собой отдельный автомобиль.

Связи между объектами: Внутри одного объекта есть взаимосвязь между характеристиками и его ценой. Например, год выпуска, пробег и мощность двигателя могут влиять на цену автомобиля.

Бизнес-цель: Оптимизация продаж автомобилей, оценка цен в зависимости от характеристик.

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

Техническая цель: Построение модели машинного обучения для прогнозирования цены автомобиля на основе его характеристик.

  • Вход: Характеристики автомобиля (год выпуска, пробег, объем двигателя и др.).
  • Целевой признак: Цена автомобиля.

Датасет 3. Прогнозирование цен на жилье в Бостоне

  1. crim: Уровень преступности на душу населения по городам.
  2. zn: Доля крупных жилых участков (более 25,000 кв. футов).
  3. indus: Доля не розничных бизнес-акров на город.
  4. Chas: Двоичный признак, указывающий, находится ли объект рядом с рекой Чарльз (1 — да, 0 — нет).
  5. nox: Концентрация оксидов азота в воздухе.
  6. rm: Среднее количество комнат в одном жилом доме.
  7. age: Доля старых жилых единиц, построенных до 1940 года.
  8. dis: Взвешенные расстояния до рабочих центров Бостона.
  9. rad: Индекс доступности радиальных шоссе.
  10. tax: Налог на недвижимость на сумму $10,000.

Объект наблюдения: Каждый объект представляет собой отдельный дом или квартиру.

Связи между объектами: Внутри одного объекта есть взаимосвязь между характеристиками, такими как уровень преступности, количество комнат и налоги, которые могут влиять на цену жилья.

Бизнес-цель: Оценка стоимости недвижимости для покупателей и продавцов, а также для инвесторов в недвижимость.

Эффект для бизнеса: Более точная оценка цен на жилье может помочь улучшить принятие решений при покупке и продаже недвижимости.

Техническая цель: Построение модели машинного обучения для прогнозирования цен на жилье в Бостоне на основе его характеристик.

  • Вход: Характеристики жилья (уровень преступности, количество комнат, налоги и др.).
  • Целевой признак: Цена жилья.
In [4]:
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from imblearn.under_sampling import RandomUnderSampler
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv(
    "data/boston_housing.csv"
) 

# Проверка на пропуски и "зашумленные" столбцы (если процент пустых значений больше 10%)
noisy_features = []  # Список для хранения столбцов с большим количеством пропусков
for col in df.columns:  # Проходим по каждому столбцу
    if (
        df[col].isnull().sum() / len(df) > 0.1
    ):  # Проверяем, если доля пропусков больше 10%
        noisy_features.append(col)  # Добавляем столбец в список

# Проверка на смещение (относительно нормального распределения)
skewness = df.select_dtypes(
    include=[np.number]
).skew()  # Вычисляем коэффициент смещения для числовых столбцов

skewed_features = skewness[
    abs(skewness) > 1
].index.tolist()  # Находим сильно смещенные столбцы

# Поиск выбросов (сильно отличающиеся значения)
for col in df.select_dtypes(
    include=["number"]
).columns:  # Проходим по числовым столбцам
    Q1 = df[col].quantile(0.25)  # Находим первый квартиль (значение, ниже которого 25% данных)
    Q3 = df[col].quantile(
        0.75
    )  # Находим третий квартиль (значение, ниже которого 75% данных)
    IQR = Q3 - Q1  # Вычисляем интерквартильный размах 
    lower_bound = Q1 - 1.5 * IQR  # Вычисляем нижнюю границу
    upper_bound = Q3 + 1.5 * IQR  # Вычисляем верхнюю границу
    outliers = df[col][
        (df[col] < lower_bound) | (df[col] > upper_bound)
    ]  # Находим выбросы
    print(f"Выбросы в столбце '{col}':\n{outliers}\n")  # Выводим выбросы

# Визуализация выбросов
numeric_cols = df.select_dtypes(
    include=["number"]
).columns  # Получаем список числовых столбцов
plt.figure(figsize=(12, 8))  # Устанавливаем размер графика

for i, col in enumerate(
    numeric_cols, 1
):  # Проходим по числовым столбцам для построения графиков
    plt.subplot(
        len(numeric_cols) // 3 + 1, 3, i
    )  # Создаем подграфик для каждого столбца
    sns.boxplot(data=df, x=col)  # Строим боксплот для столбца
    plt.title(f"Boxplot for {col}")  # Устанавливаем заголовок для подграфик

plt.tight_layout()  # Упорядочиваем графики
plt.show()  # Отображаем графики

# Проверка на корреляцию (насколько одна переменная изменится (и зависит) от изменения другой) между признаками
if len(df.columns) >= 2:  # Проверяем, что в датасете более одного столбца
    for col1 in df.columns:  # Проходим по всем столбцам
        for col2 in df.columns:  # Сравниваем с каждым другим столбцом
            if col1 != col2:  # Проверяем, что это разные столбцы
                correlation = df[col1].corr(df[col2])  # Вычисляем корреляцию
                if abs(correlation) > 0.9:  # Проверяем, превышает ли корреляция 0.9
                    print(
                        f"Просачивание данных: Высокая корреляция ({correlation:.2f}) между столбцами '{col1}' и '{col2}'"
                    )  # Выводим информацию о высокой корреляции


# Функция для разбиения на train/val/test
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,
):
    if frac_train + frac_val + frac_test != 1.0:  # Проверяем, что доли составляют 1
        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
        )
    )

    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  # Возвращаем разбитые данные


# целевой признак  'tax'
df["tax_binned"] = pd.cut(  # Разбиваем значения 'tax' на категории
    df["tax"],
    bins=[0, 200, 400, 600, 800, 1000],
    labels=["Very Low", "Low", "Medium", "High", "Very High"],
)
df = df.dropna()  # Удаляем строки с пропусками

# Разделение данных
df_train, df_val, df_test = (
    split_stratified_into_train_val_test(  # Разбиваем данные на обучающие, валидационные и тестовые
        df,
        stratify_colname="tax_binned",
        frac_train=0.60,
        frac_val=0.20,
        frac_test=0.20,
    )
)

# Выводим размеры разбитых выборок
print("Обучающая выборка: ", df_train.shape)
print("Контрольная выборка: ", df_val.shape)
print("Тестовая выборка: ", df_test.shape)

# Уравнивание данных для обучения модели
# Подход с Random Under Sampler
rus = RandomUnderSampler(
    random_state=42
)  # Инициализируем метод уменьшения дисбаланса классов
X_resampled, y_resampled = rus.fit_resample(
    df_train, df_train["tax_binned"]
)  # Применяем undersampling

print(df_train.tax_binned.value_counts())

df_train_rus = pd.DataFrame(X_resampled)  # Сохраняем результат в новый DataFrame
print(
    "Обучающая выборка после undersampling: ", df_train_rus.shape
)  # Выводим размеры новой обучающей выборки
print(
    df_train_rus.tax_binned.value_counts()
)  # Выводим количество классов в новой обучающей выборке
Выбросы в столбце 'crim':
367    13.5222
371     9.2323
373    11.1081
374    18.4982
375    19.6091
        ...   
468    15.5757
469    13.0751
477    15.0234
478    10.2330
479    14.3337
Name: crim, Length: 66, dtype: float64

Выбросы в столбце 'zn':
39     75.0
40     75.0
54     75.0
55     90.0
56     85.0
       ... 
351    60.0
352    60.0
353    90.0
354    80.0
355    80.0
Name: zn, Length: 68, dtype: float64

Выбросы в столбце 'indus':
Series([], Name: indus, dtype: float64)

Выбросы в столбце 'chas':
142    1
152    1
154    1
155    1
160    1
162    1
163    1
208    1
209    1
210    1
211    1
212    1
216    1
218    1
219    1
220    1
221    1
222    1
234    1
236    1
269    1
273    1
274    1
276    1
277    1
282    1
283    1
356    1
357    1
358    1
363    1
364    1
369    1
370    1
372    1
Name: chas, dtype: int64

Выбросы в столбце 'nox':
Series([], Name: nox, dtype: float64)

Выбросы в столбце 'rm':
97     8.069
98     7.820
162    7.802
163    8.375
166    7.929
180    7.765
186    7.831
195    7.875
203    7.853
204    8.034
224    8.266
225    8.725
226    8.040
232    8.337
233    8.247
253    8.259
257    8.704
262    8.398
267    8.297
280    7.820
283    7.923
364    8.780
365    3.561
367    3.863
374    4.138
384    4.368
386    4.652
406    4.138
412    4.628
414    4.519
Name: rm, dtype: float64

Выбросы в столбце 'age':
Series([], Name: age, dtype: float64)

Выбросы в столбце 'dis':
351    10.7103
352    10.7103
353    12.1265
354    10.5857
355    10.5857
Name: dis, dtype: float64

Выбросы в столбце 'rad':
Series([], Name: rad, dtype: int64)

Выбросы в столбце 'tax':
Series([], Name: tax, dtype: int64)

Выбросы в столбце 'ptratio':
196    12.6
197    12.6
198    12.6
257    13.0
258    13.0
259    13.0
260    13.0
261    13.0
262    13.0
263    13.0
264    13.0
265    13.0
266    13.0
267    13.0
268    13.0
Name: ptratio, dtype: float64

Выбросы в столбце 'b':
18     288.99
25     303.42
27     306.38
32     232.60
34     248.31
        ...  
466     22.01
467    331.29
475    302.76
489    344.05
490    318.43
Name: b, Length: 77, dtype: float64

Выбросы в столбце 'lstat':
141    34.41
373    34.77
374    37.97
387    31.99
412    34.37
414    36.98
438    34.02
Name: lstat, dtype: float64

Выбросы в столбце 'medv':
97     38.7
98     43.8
157    41.3
161    50.0
162    50.0
163    50.0
166    50.0
179    37.2
180    39.8
182    37.9
186    50.0
190    37.0
195    50.0
202    42.3
203    48.5
204    50.0
224    44.8
225    50.0
226    37.6
228    46.7
232    41.7
233    48.3
253    42.8
256    44.0
257    50.0
261    43.1
262    48.8
267    50.0
268    43.5
280    45.4
282    46.0
283    50.0
291    37.3
368    50.0
369    50.0
370    50.0
371    50.0
372    50.0
398     5.0
405     5.0
Name: medv, dtype: float64

No description has been provided for this image
Просачивание данных: Высокая корреляция (0.91) между столбцами 'rad' и 'tax'
Просачивание данных: Высокая корреляция (0.91) между столбцами 'tax' и 'rad'
Обучающая выборка:  (300, 15)
Контрольная выборка:  (100, 15)
Тестовая выборка:  (101, 15)
tax_binned
Low          171
High          82
Medium        37
Very Low      10
Very High      0
Name: count, dtype: int64
Обучающая выборка после undersampling:  (40, 15)
tax_binned
Very Low     10
Low          10
Medium       10
High         10
Very High     0
Name: count, dtype: int64