.. _sec_pandas: Предобработка данных ==================== До сих пор мы работали с синтетическими данными, которые уже были представлены в виде готовых тензоров. Однако для применения глубокого обучения на практике нам необходимо извлекать неструктурированные данные, хранящиеся в произвольных форматах, и предварительно обрабатывать их в соответствии с нашими требованиями. К счастью, библиотека *pandas* `library `__ может взять на себя большую часть этой работы. Этот раздел, хотя и не заменяет полноценного `tutorial `__ по *pandas*, даст вам краткий обзор наиболее часто используемых функций. Чтение набора данных -------------------- Файлы CSV (значения, разделённые запятыми), повсеместно используемые для хранения табличных (похожих на электронные таблицы) данных. В них каждая строка соответствует одной записи и состоит из нескольких (разделённых запятыми) полей, например: «Albert Einstein,March 14 1879,Ulm,Federal polytechnic school,field of gravitational physics». Чтобы продемонстрировать, как загружать CSV-файлы с помощью ``pandas``, мы создадим CSV-файл ниже ``../data/house_tiny.csv``. Этот файл представляет собой набор данных о домах, где каждая строка соответствует отдельному дому, а столбцы отражают количество комнат (``NumRooms``), тип крыши (``RoofType``) и цену (``Price``). .. raw:: latex \diilbookstyleinputcell .. code:: python import os os.makedirs(os.path.join('..', 'data'), exist_ok=True) data_file = os.path.join('..', 'data', 'house_tiny.csv') with open(data_file, 'w') as f: f.write('''NumRooms,RoofType,Price NA,NA,127500 2,NA,106000 4,Slate,178100 NA,NA,140000''') Теперь импортируем ``pandas`` и загрузим набор данных с помощью ``read_csv``. .. raw:: latex \diilbookstyleinputcell .. code:: python import pandas as pd data = pd.read_csv(data_file) print(data) Подготовка данных ----------------- В обучении с учителем мы обучаем модели предсказывать заданное *целевое* значение на основе некоторого набора *входных* значений. Наш первый шаг при обработке набора данных — разделить столбцы, соответствующие входным и целевым значениям. Мы можем выбирать столбцы как по имени, так и с помощью индексации на основе целочисленных позиций (``iloc``). Вы могли заметить, что ``pandas`` заменил все записи в CSV со значением ``NA`` на специальное значение ``NaN`` (*не число*). Это также происходит, когда какая-либо запись пуста, например, “3,,,270000”. Такие значения называются *пропущенными значениями*, и они являются «постельными клопами» науки о данных — постоянной угрозой, с которой вы столкнетесь на протяжении всей своей карьеры. В зависимости от контекста, пропущенные значения могут обрабатываться либо с помощью *импутации*, либо *удаления*. Импутация заменяет пропущенные значения оценками их значений, тогда как удаление просто отбрасывает строки или столбцы, содержащие пропущенные значения. Ниже приведены некоторые распространенные эвристики для импутации. Для категориальных входных признаков мы можем рассматривать ``NaN`` как категорию. Поскольку столбец ``RoofType`` принимает значения ``Slate`` и ``NaN``, ``pandas`` может преобразовать этот столбец в два столбца ``RoofType_Slate`` и ``RoofType_nan``. Для строки, у которой тип крыши ``Slate``, значения ``RoofType_Slate`` и ``RoofType_nan`` будут установлены в 1 и 0 соответственно. Для строки с пропущенным значением ``RoofType`` справедливо обратное. .. raw:: latex \diilbookstyleinputcell .. code:: python inputs, targets = data.iloc[:, 0:2], data.iloc[:, 2] inputs = pd.get_dummies(inputs, dummy_na=True) print(inputs) Для пропущенных числовых значений одним из распространённых эвристических подходов является замена ``NaN`` на среднее значение соответствующего столбца. .. raw:: latex \diilbookstyleinputcell .. code:: python inputs = inputs.fillna(inputs.mean()) print(inputs) Преобразование в формат тензора ------------------------------- Теперь, когда **все элементы в ``inputs`` и ``targets`` числовые, мы можем загрузить их в тензор** (напомним :numref:`sec_ndarray`). .. raw:: latex \diilbookstyleinputcell .. code:: python import torch X = torch.tensor(inputs.to_numpy(dtype=float)) y = torch.tensor(targets.to_numpy(dtype=float)) X, y Обсуждение ---------- Теперь вы знаете, как разбивать столбцы данных, заполнять пропущенные значения и загружать ``pandas`` данные в тензоры. В :numref:`sec_kaggle_house` вы освоите дополнительные навыки обработки данных. Хотя этот вводный курс упрощал материал, на практике обработка данных может быть довольно сложной. Например, вместо одного CSV-файла наш набор данных может быть распределен по нескольким файлам, извлеченным из реляционной базы данных. Так, в приложении электронной коммерции адреса клиентов могут храниться в одной таблице, а данные о покупках — в другой. Кроме того, специалисты сталкиваются с множеством типов данных, помимо категориальных и числовых, например, текстовыми строками, изображениями, аудиоданными и облаками точек. Часто для того, чтобы обработка данных не стала главным узким местом в конвейере машинного обучения, требуются продвинутые инструменты и эффективные алгоритмы. Эти проблемы возникнут, когда мы перейдем к компьютерному зрению и обработке естественного языка. Наконец, мы должны уделять внимание качеству данных. Реальные наборы данных часто страдают от выбросов, ошибочных показаний датчиков и ошибок записи, которые необходимо устранить перед подачей данных в любую модель. Инструменты визуализации данных, такие как `seaborn `__, `Bokeh `__ или `matplotlib `__, помогут вам вручную изучить данные и сформировать интуитивное понимание проблем, которые может потребоваться решить. Упражнения ---------- 1. Попробуйте загрузить наборы данных, например, Abalone из `UCI Machine Learning Repository `__, и изучите их свойства. Какая доля наблюдений содержит пропущенные значения? Какая доля переменных является числовой, категориальной или текстовой? 2. Попробуйте обращаться к столбцам данных по имени, а не по номеру. В документации pandas по `индексации `__ приведены дополнительные сведения о том, как это сделать. 3. Какой по объёму набор данных вы считаете возможным загрузить таким образом? Каковы могут быть ограничения? Подсказка: рассмотрите время чтения данных, их представление, обработку и объём потребляемой памяти. Попробуйте выполнить это на своём ноутбуке. Что произойдет, если вы попробуете это сделать на сервере? 4. Как вы будете работать с данными, имеющими очень большое количество категорий? Что делать, если все метки категорий уникальны? Следует ли включать последние? 5. Какие альтернативы pandas вы можете предложить? А что насчет `загрузки тензоров NumPy из файла `__? Ознакомьтесь с `Pillow `__, библиотекой для обработки изображений на Python. `Обсуждения `__