Лаб. работа "Предобработка данных"
Лабораторная работа: Методы предобработки данных в интеллектуальных системах
Цель работы
Изучение и практическое применение основных методов предобработки данных: обработка пропусков, кодирование категориальных признаков, масштабирование числовых признаков и работа с выбросами. Формирование навыков подготовки наборов данных для их использования в моделях машинного обучения.
Краткие теоретические сведения
Предобработка данных (Data Preprocessing) — это этап подготовки “сырых” данных к анализу и построению моделей. Качество данных напрямую влияет на производительность и точность интеллектуальных систем. Основные задачи предобработки включают:
Обработка пропущенных значений: Данные могут отсутствовать по разным причинам. Основные стратегии:
- Удаление: Удаление строк или столбцов с пропусками. Целесообразно, если пропусков мало или столбец неинформативен.
- Заполнение (Imputation): Замена пропусков некоторым значением:
- Среднее (mean): Для числовых признаков без сильных выбросов.
- Медиана (median): Для числовых признаков с выбросами, так как медиана более устойчива к ним.
- Мода (mode): Для категориальных признаков (заполнение наиболее часто встречающимся значением).
- Константа: Заполнение нулем, строкой “unknown” и т.д.
Кодирование категориальных признаков: Большинство моделей машинного обучения работают с числами, поэтому текстовые категории нужно преобразовать.
- Label Encoding (Порядковое кодирование): Каждой уникальной категории присваивается целое число (0, 1, 2…). Подходит для порядковых признаков, где есть естественная иерархия (например, “плохо”, “хорошо”, “отлично”).
- One-Hot Encoding (Прямое кодирование): Для каждой категории создается новый бинарный столбец (0 или 1). Подходит для номинальных признаков, где нет порядка (например, “красный”, “зеленый”, “синий”).
Исходный признак Label Encoding One-Hot Encoding (color_red, color_green) red 0 1, 0 green 1 0, 1 red 0 1, 0 Масштабирование числовых признаков: Признаки с разными диапазонами значений (например, возраст от 0 до 100 и доход от 20 000 до 200 000) могут некорректно влиять на модели, основанные на расстоянии (kNN, SVM) или градиентном спуске.
- Стандартизация (Standardization): Приводит данные к распределению со средним $0$ и стандартным отклонением $1$. $$ Z = \frac{x - \mu}{\sigma} $$ где $\mu$ — среднее значение, $\sigma$ — стандартное отклонение.
- Нормализация (Normalization): Масштабирует данные в заданный диапазон, обычно $[0, 1]$. $$ X_{norm} = \frac{x - x_{min}}{x_{max} - x_{min}} $$ где $x_{min}$ и $x_{max}$ — минимальное и максимальное значения признака.
Обработка выбросов (Outliers): Выбросы — это значения, которые сильно отличаются от основной массы данных. Они могут искажать результаты обучения. Один из популярных методов их обнаружения — метод межквартильного размаха (IQR). Выбросами считаются значения, выходящие за пределы:
- Нижняя граница: $Q_1 - 1.5 \times IQR$
- Верхняя граница: $Q_3 + 1.5 \times IQR$ где $Q_1$ — первый квартиль (25-й перцентиль), $Q_3$ — третий квартиль (75-й перцентиль), $IQR = Q_3 - Q_1$.
Порядок выполнения работы
Работа выполняется в среде Python с использованием библиотек pandas, numpy, scikit-learn и matplotlib/seaborn.
Подготовка окружения. Установите необходимые библиотеки, если они отсутствуют:
1pip install pandas numpy scikit-learn matplotlib seabornЗагрузка и первичное исследование данных. Мы будем использовать классический набор данных “Титаник”, который содержит пропуски, категориальные и числовые признаки.
1import pandas as pd 2import numpy as np 3import seaborn as sns 4import matplotlib.pyplot as plt 5 6# Загружаем датасет из библиотеки seaborn 7df = sns.load_dataset('titanic') 8 9# Выводим общую информацию о датасете 10print("Информация о датасете:") 11df.info() 12 13# Выводим первые 5 строк 14print("\nПервые 5 строк датасета:") 15print(df.head()) 16 17# Статистика по числовым признакам 18print("\nСтатистика по числовым признакам:") 19print(df.describe())Обработка пропущенных значений. Найдем столбцы с пропущенными значениями.
1print("\nКоличество пропусков в каждом столбце:") 2print(df.isnull().sum())age(возраст): Заполним пропуски медианным значением, так как распределение возраста может быть скошенным.embarked(порт посадки): Это категориальный признак. Заполним пропуски модой.deck(палуба): Слишком много пропусков. Этот столбец проще удалить.embark_town: Дублирует информациюembarked, его тоже можно удалить.
1# Заполнение 'age' медианой 2median_age = df['age'].median() 3df['age'].fillna(median_age, inplace=True) 4 5# Заполнение 'embarked' модой 6mode_embarked = df['embarked'].mode()[0] 7df['embarked'].fillna(mode_embarked, inplace=True) 8 9# Удаление столбцов 10df.drop(['deck', 'embark_town'], axis=1, inplace=True) 11 12# Проверяем, что пропусков не осталось (кроме 'age' и 'embarked') 13print("\nКоличество пропусков после обработки:") 14print(df.isnull().sum())Кодирование категориальных признаков. Преобразуем столбцы
sex,embarked,class,who,adult_male,alive,alone. Для примера используем One-Hot Encoding дляsexиembarked.1# Применение One-Hot Encoding к 'sex' и 'embarked' 2df_processed = pd.get_dummies(df, columns=['sex', 'embarked'], drop_first=True) 3 4# Удалим и другие некатегориальные, но не числовые столбцы для упрощения 5# Или те, что не несут пользы для гипотетической модели 6df_processed.drop(['pclass', 'who', 'adult_male', 'class', 'alive', 'alone'], axis=1, inplace=True) 7 8 9print("\nДатасет после One-Hot Encoding:") 10print(df_processed.head())drop_first=Trueиспользуется для удаления одного из новых столбцов, чтобы избежать мультиколлинеарности (избыточности).Масштабирование числовых признаков. Применим стандартизацию к признакам
ageиfare.1from sklearn.preprocessing import StandardScaler 2 3scaler = StandardScaler() 4# Выбираем столбцы для масштабирования 5cols_to_scale = ['age', 'fare'] 6df_processed[cols_to_scale] = scaler.fit_transform(df_processed[cols_to_scale]) 7 8print("\nДатасет после масштабирования 'age' и 'fare':") 9print(df_processed.head())Работа с выбросами (на примере
fare). Визуализируем признакfareдо и после обработки выбросов.1plt.figure(figsize=(10, 4)) 2plt.subplot(1, 2, 1) 3sns.boxplot(y=df_processed['fare']) 4plt.title('Boxplot для Fare (до обработки выбросов)') 5 6# Расчет IQR для 'fare' 7Q1 = df_processed['fare'].quantile(0.25) 8Q3 = df_processed['fare'].quantile(0.75) 9IQR = Q3 - Q1 10lower_bound = Q1 - 1.5 * IQR 11upper_bound = Q3 + 1.5 * IQR 12 13# Ограничение выбросов (Capping) 14df_processed['fare'] = np.where(df_processed['fare'] > upper_bound, upper_bound, df_processed['fare']) 15df_processed['fare'] = np.where(df_processed['fare'] < lower_bound, lower_bound, df_processed['fare']) 16 17plt.subplot(1, 2, 2) 18sns.boxplot(y=df_processed['fare']) 19plt.title('Boxplot для Fare (после обработки выбросов)') 20plt.tight_layout() 21plt.show() 22 23print("\nФинальный вид обработанного датасета:") 24print(df_processed.head())
Задания для самостоятельной работы
Задание 1
- Повторить все шаги, описанные в разделе “Порядок выполнения работы”.
- В отчете подробно описать каждый шаг, приложить фрагменты кода и результаты его выполнения (вывод
info,head,describe, графики). - В заключении ответить на вопрос: почему для заполнения
ageбыла выбрана медиана, а не среднее?
Задание 2
- Загрузить датасет “Титаник”.
- Для обработки пропусков в столбце
ageиспользовать среднее значение. - Для кодирования признака
sexприменить Label Encoding вместо One-Hot Encoding. - Масштабировать признаки
ageиfareс помощью нормализации (MinMaxScaler). - Сравнить статистические показатели (
describe()) датасета до и после масштабирования. - В заключении проанализировать, в каких случаях применение Label Encoding для признака
sexможет быть некорректным.
Задание 3
- Загрузить датасет “Титаник”.
- Столбец
ageс пропусками не заполнять, а удалить все строки, где возраст не указан. Сравнить размер датасета до и после удаления. - Категориальные признаки
sexиembarkedзакодировать с помощью One-Hot Encoding. - Выполнить стандартизацию для признака
fare. - Найти и удалить выбросы в признаке
fareпо методу IQR (удалить строки, а не ограничить значения). - В заключении оценить, какой подход к обработке пропусков в
age(удаление строк или заполнение медианой) привел к большей потере данных.
Требования к отчету
Отчет по лабораторной работе должен содержать:
Цель работы.
Постановка задачи в соответствии с вариантом.
Ход работы: последовательное описание выполненных шагов с приведением ключевых фрагментов кода, скриншотов и/или таблиц с результатами (например, вывод
.info(),.describe(),.head()).Графики и их анализ (например, boxplot для выбросов).
Выводы по работе, включающие ответы на вопросы из задания по варианту и общую оценку проделанной работы.
Контрольные вопросы
- Зачем нужна предобработка данных? Какие проблемы она решает?
- В чем разница между заполнением пропусков средним, медианой и модой? Когда какой метод предпочтительнее?
- Объясните разницу между стандартизацией и нормализацией. Для каких алгоритмов масштабирование признаков критически важно?
- В чем принципиальное отличие One-Hot Encoding от Label Encoding? Приведите примеры признаков, для которых подходит каждый из этих методов.
- Что такое выбросы и какими методами их можно обнаружить и обработать?