Загрузка и предобработка данных различных форматов
Загрузка и предобработка данных - это первый и очень важный этап в любом проекте по анализу данных или машинному обучению. От качества данных напрямую зависит конечный результат. Поэтому я всегда уделяю много внимания этому процессу.
Данные могут храниться в различных форматах - CSV, JSON, XML, базах данных и др. Чаще всего мне приходится работать с форматами CSV и JSON.
Загрузка данных
Для загрузки CSV файлов в Python я использую модуль Pandas:
import pandas as pd
data = pd.read_csv('data.csv')
Pandas автоматически определит названия столбцов из первой строки файла и загрузит данные в объект DataFrame. Если файл не содержит заголовков, то можно передать параметр header=None
.
Для работы с JSON в Python есть встроенный модуль json. Загрузить JSON файл можно так:
import json
with open('data.json', 'r') as f:
data = json.load(f)
Данные из JSON файла будут представлены в виде вложенных словарей и списков Python.
Предобработка данных
После загрузки сырых данных обычно требуется их предобработка:
- Проверка на пропуски и некорректные значения. Пропущенные значения можно заполнить средним, медианой или удалить строки с пропусками.
- Кодирование категориальных признаков - преобразование строковых значений в числовые.
- Масштабирование числовых признаков, чтобы они имели нулевое среднее и единичную дисперсию. Это важно для многих алгоритмов машинного обучения.
- Создание новых признаков из имеющихся данных.
Pandas предоставляет множество функций для предобработки:
# Проверка на пропуски
data.isnull().sum()
# Заполнение пропусков средним значением
data.fillna(data.mean(), inplace=True)
# Кодирование категорий
data = pd.get_dummies(data, columns=['category'])
# Масштабирование
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data[numeric_cols] = scaler.fit_transform(data[numeric_cols])
Помимо Pandas, для предобработки данных часто используют библиотеку Scikit-learn.
Предобработка данных с помощью Scikit-learn
Импорт библиотек
Для начала нам понадобится импортировать необходимые библиотеки:
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
Данные
В качестве примера я буду использовать известный датасет "Boston Housing", который доступен в Scikit-learn. Этот датасет содержит информацию о ценах на жилье в Бостоне и различных характеристиках районов.
from sklearn.datasets import load_boston
boston = load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='MEDV')
Обработка пропущенных значений
Первым шагом в предобработке данных является обработка пропущенных значений. В нашем датасете пропущенных значений нет, но для примера я удалю несколько случайных значений.
# Удалим несколько случайных значений
X.iloc[3:7, 2] = None
X.iloc[10:15, 5] = None
# Проверим наличие пропущенных значений
print(X.isnull().sum())
Для заполнения пропущенных значений я использую SimpleImputer
из Scikit-learn. В данном случае я заполню пропущенные значения медианным значением для числовых признаков.
imputer = SimpleImputer(strategy='median')
X['LSTAT'] = imputer.fit_transform(X[['LSTAT']])
X['RM'] = imputer.fit_transform(X[['RM']])
Стандартизация данных
Многие алгоритмы машинного обучения работают лучше, если данные имеют нулевое среднее и единичную дисперсию. Для этого используется стандартизация данных.
scaler = StandardScaler()
X['LSTAT'] = scaler.fit_transform(X[['LSTAT']])
X['RM'] = scaler.fit_transform(X[['RM']])
Кодирование категориальных признаков
В нашем датасете нет категориальных признаков, но для примера я создам новый признак "SIZE", который будет принимать значения "small", "medium" и "large".
X['SIZE'] = ['small'] * 10 + ['medium'] * 20 + ['large'] * 30
Для кодирования категориальных признаков я использую OneHotEncoder
.
encoder = OneHotEncoder(sparse=False, handle_unknown='ignore')
transformed_X = encoder.fit_transform(X[['SIZE']])
encoded_X = pd.DataFrame(transformed_X, columns=encoder.get_feature_names(['SIZE']))
X = pd.concat([X, encoded_X], axis=1)
X.drop('SIZE', axis=1, inplace=True)
Создание пайплайна
Scikit-learn позволяет создавать пайплайны, которые последовательно применяют трансформации к данным. Это удобно, когда необходимо применить несколько шагов предобработки.
numeric_features = X.select_dtypes(include=[np.number]).columns
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
categorical_features = X.select_dtypes(include=['object']).columns
categorical_transformer = Pipeline(steps=[
('encoder', OneHotEncoder(sparse=False, handle_unknown='ignore'))
])
preprocessor = ColumnTransformer(transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
Применение пайплайна
Теперь мы можем применить созданный пайплайн к данным.
preprocessed_X = preprocessor.fit_transform(X)
Таким образом, работа с данными начинается с их загрузки из различных источников, приведения к удобному формату (чаще всего табличному) и очистки от шумов и некорректных значений. Только после тщательной предобработки данные готовы для дальнейшего анализа и построения моделей машинного обучения. От качества выполнения этого этапа во многом зависит успех всего проекта.