Загрузка и предобработка данных различных форматов

Данные могут храниться в различных форматах - 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.

Предобработка данных

После загрузки сырых данных обычно требуется их предобработка:

  1. Проверка на пропуски и некорректные значения. Пропущенные значения можно заполнить средним, медианой или удалить строки с пропусками.
  2. Кодирование категориальных признаков - преобразование строковых значений в числовые.
  3. Масштабирование числовых признаков, чтобы они имели нулевое среднее и единичную дисперсию. Это важно для многих алгоритмов машинного обучения.
  4. Создание новых признаков из имеющихся данных.

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)

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