До сих пор мы предполагали, что датасет для машинного обучения уже имеется и удовлетворяет всем необходимым условиям, представлен в нужной нам форме, не имеет ошибок и аномалий. Но на практике вы не встретите таких идеальных данных. Как же подготовить данные для машинного обучения? В этой части учебника мы ответим на вопросы, связанные со сбором, анализом и предварительной обработкой данных.

Еще в самом начале книги мы говорили о том, что в машинном обучении самый главный и критичный компонент - сами данные, на которых проводится обучение. Качество данных напрямую влияет на эффективность и надежность получаемых моделей. Поэтому значительная часть работы аналитика - это сбор, очистка, анализ и улучшение данных. В реальных проектах на это уходит до 80% всего времени, затраченного на проект. И лишь оставшиеся 20% - это обучение и выбор моделей, диагностика и повышение их эффективности.

Конечно, работа с данными предваряет непосредственно моделирование. Поэтому во многих курсах с этого как раз начинают. Но как показывает опыт преподавания машинного обучения, очень сложно понять некоторые аспекты, важные для процесса предварительной обработки данных, без понимания того, для чего эти данные будут использоваться, каковы особенности разных моделей, то есть тех тем, которые мы рассматривали в предыдущих главах. Именно поэтому в этой части мы познакомимся с процессами и методами, которые предшествуют построению моделей машинного обучения. Здесь мы поговорим о сборе, анализе и обработке данных для моделирования.

Надо сказать, что мы не сможем описать все многообразие методов анализа данных. Здесь мы поговорим именно про подготовку данных для машинного обучения и про типичные задачи, которые надо решить для этого, главные вопросы, на которые нужно ответить. Но анализ данных в широком смысле гораздо обширнее и глубже этого, это целая отдельная дисциплина, основанная на математической статистике, численных методах и алгоритмах. Конечно, в первую очередь данные нужно собрать, а для этого нужно понять, какие данные нужны для решения конкретной задачи, определить требования к ним. Так что начнем мы с самого первого шага - сбора данных.

Сбор данных для обучения

Понятие чистых данных

А что вообще значит “качество данных”? В чем оно измеряется и для чего нужно? И в какой форме данные нужно иметь для начала их использования в машинном обучении? В этой главе мы рассмотрим требования, которым данные должны удовлетворять для того, чтобы считаться “хорошими” и подходить для машинного обучения.

В первую очередь необходимо зафиксировать, в какой форме собираются и хранятся данные для машинного обучения. Многое их этого мы уже видели и на примерах, и немного определяли математически, но сейчас пора явно сформулировать требования к представлению данных и их структуре. Обработка и анализ неструктурированной информации - это отдельная тема, которой мы не будем касаться. Для классического машинного обучения данные должны иметь вполне определенную структуру - чаще всего табличную.

Датасет - набор данных для машинного обучения - состоит из описания некоторого конечного множества объектов, экспериментов и измерений. Так как машинное обучение не привязано к какой-то определенной предметной области, данные могут описывать все, что угодно. Объекты недвижимости, определенных людей, финансовые транзакции, фотографии каких-то объектов, данные с телеметрии спутников. Но главное - что эта информация описывает набор каких-то отдельных объектов реального мира, элементарных сущностей той предметной области, которую мы моделируем. Еще эти объекты называют точками данных, или строками, так как в таблицах они всегда отображаются именно по строкам.

У каждого из этих объектов есть некоторые характеристики, которые описаны в датасете. Для всех объектов набор этих характеристик должен быть одинаковый. Эти характеристики реальных объектов называются атрибутами или колонками, опять же потому, что в табличном представлении они располагаются по столбцам. Иногда они же называются переменными, либо факторами. Соответственно, на пересечении столбца и строки находятся значения соответствующих характеристик определенного объекта.

По сути такое представление информации очень похоже на реляционную форму, которая используется в базах данных. Главное различие в том, что в машинном обучении датасет представляется в виде единой таблицы, а не набора связанных, как в реляционных базах данных. Такая таблица должна иметь внутреннюю согласованность, то есть описывать один вид наблюдений или экспериментов. Причем внутренняя согласованность должна проявляться и в содержании данных. В датасете должны использоваться одни обозначения, сокращения, форматы. Мало толку от таблицы, в которой часть объектов измерена в метрах, а остальные в футах. Если мы анализируем экономические показатели, то агрегаты должны измеряться за одни и те же периоды и так далее. Таких маленьких нюансов в данных может быть очень много и для их отслеживания необходимо знание предметной области.

Если датасет удовлетворяет этим базовым требованиям, то такие данные можно называть чистыми (tidy data). На практике к базовым добавляются еще два требований, которые почти всегда нужно соблюдать, иначе большинство моделей машинного обучения не смогут работать с такими данными. Во-первых, данные должны быть выражены в численном виде. Про то, как преобразовать данные в численный вид мы поговорим чуть позже, в главе про предобработку данных. Это требование объясняется тем, что большинство моделей основаны на численных функциях и математических преобразованиях. Поэтому на вход надо подавать набор численных значений, или вектор.

Во-вторых, в данных не должно быть отсутствующих значений, то есть пропусков. Все “ячейки” таблицы должны быть заполнены. Это тоже обосновано применением математических моделей, которые не умеют работать с отсутствием значения. Заполнению пропущенных значений тоже посвящена большая часть предобработки данных. Вообще, приведение данных к такому чистому виду - это основная цель предварительной обработки данных как этапа проекта по машинному обучению.

Чистые данные - это набор данных, который представлен в форме реляционной таблицы, все значения в которой выражены числом, не имеет пропущенных значений, имеет внутреннюю согласованность. Такие данные формально можно применять для использования в любых моделей машинного обучения.

Конечно, на практике бывают и исключения из этих правил. Существуют специальные области, в которых данные представляются в особой структуре и в особых форматах. Типичный пример - временные ряды. Это ряд чисел, которые характеризуют динамику одного и того же показателя во времени. То есть датасет в таком случае представляется не как набор взаимонезависимых объектов. Элементы в таком временном ряду имеют строгую последовательность, которую нельзя нарушать. В предыдущей главе мы уже говорили, что временные ряды нельзя разбивать на обучающую и тестовую выборки случайным образом. Точно также следует учитывать особенности природы исследуемых данных и в других случаях.

Еще один распространенный пример - нестандартные форматы данных. В машинном обучении часто встречается ситуация, когда отдельная точка данных представляет собой не численный вектор, а, например, картинку, текст, видеофрагмент или аудиоданные. Но и в таком случае, для моделирования эти данные преобразуются к численным векторам. Этот процесс называется векторизацией. Так можно векторизовать текст, для этого есть много разных методов. Картинки, очень естественно представляются как массив яркости пикселей, подобным же образом преобразуются и другие типы данных. Просто преобразование данных в этом случае не так тривиально и может быть предметом отдельного исследования.

Надо отметить, что в подобных задачах алгоритм векторизации данных может быть даже более важным для моделирования, чем сами модели машинного обучения. Так, в обработке текстов на естественных языках, существуют разные методы преобразования текста в вектор. Самые простые подсчитывают количество и наличие слов в тексте, более продвинутые - учитывают грамматическую форму и смысл слов и предложений текста. Так вот, для совершенно разных задач обработки текстов - будь то машинный перевод или вопрос-ответные системы, гораздо большее влияние на эффективность модели оказываем именно метод векторизации. Поэтому создание так называемых глубоких текстовых моделей, которые позволяют преобразовать текст в вектор так, чтобы в этом векторе сохранилась максимум информация о смысле текста, привело к одновременному прогрессу во многих прикладных задачах.

Вообще, для анализа такой специфической информации существуют и специальные методы и модели. Например, для анализа графической информации традиционно применяются так называемые алгоритмы сверток, которые учитывают пространственное расположение информации на картинке. А анализ временных рядов - это вообще отдельная дисциплина в математической статистике, эконометрике и анализе данных. Но мы в этой книге сконцентрируемся на анализе более традиционной, табличной формы данных. Тем более, что она наиболее распространена в прикладных экономических, производственных и технических задачах.

Итак, мы сформулировали основные требования к форме предоставления данных, которые мы можем использовать для моделирования. В следующих главах мы поговорим о том, как привести данные в соответствие с этими требованиями чистоты - то есть об очистке данных. Здесь мы говорим только о формальных вещах, не касаясь смысла данных. А это тоже важная часть - данные должны подходить под решаемую задачу, быть релевантными изучаемой предметной области. Но это очень индивидуально для каждой прикладной задачи.

Выводы:

  1. Датасет - это набор данных, используемый для обучения моделей. Данные представлены в виде единой таблицы.
  2. Объекты - это элементарные сущности, которые мы изучаем, объекты реального мира, измерения, наблюдения. В датасете представляются строками.
  3. Каждый объект характеризуется набором атрибутов. В датасете атрибуты представляются столбцами.
  4. Каждая таблица, файл представляет собой данные об одном виде наблюдений или экспериментов и должна иметь внутреннюю согласованность.
  5. Дополнительно: Все данные должны быть выражены в численном виде.
  6. Дополнительно: В данных не должно быть отсутствующих (пропущенных) значений.
  7. Существуют специальные структуры данных и форматы.

Оценка источников и объемов данных

А откуда данные вообще берутся? Как создать собственный датасет или воспользоваться готовым? На эти вопросы надо ответить вначале любого проекта по машинному обучению, которое невозможно без данных. В этой главе поговорим о самом первом этапе решения прикладной задачи при помощи машинного обучения - сбора данных.

Теперь, когда мы понимаем, в какой форме нам нужных данные пора задуматься о том, сколько их требуется и откуда их брать. Оценка необходимых объемов данных - очень сложная задача. Тем более, что этот вопрос очень напрашивается перед началом работы - сколько именно данных нужно для эффективного моделирования. Но ответить на него очень сложно, ведь алгоритмы машинного обучения не предъявляют требований к размеру выборки. Самый универсальный ответ, который можно использовать - чем больше, тем лучше. Мы уже знакомы с недо- и переобучением моделей, и поэтому знаем, что добавление большего количества точек данных может помочь в первом случае, но при этом во втором тоже не пойдет во вред. Поэтому если заранее не знать, то добавление данных - в любом случае не повредит. Но обычно нам доступны лишь ограниченные данные, а если нам нужно больше - придется прилагать определенные усилия по их поиску, добычи или генерации. Поэтому вопрос необходимого объема - не праздный. Если собрать маленькую выборку может быть относительно просто и быстро, то увеличить ее в сто раз может стоить очень дорого, как по ресурсам, так и по времени.

Под объемом датасета мы будем понимать количество точек в данных, а не объем информации в байтах. Количество точек или объектов - это ключевая характеристика наборов данных для машинного обучения.

В оценке требуемого объема данных следует в первую очередь ориентироваться на порядок сложности задачи, которую мы пытаемся решить. Чем задача сложнее, тем больше данных нам потребуется. Это интуитивно понятно - для описания принципов решения сложной задачи может понадобится больше примеров, чем для простой, чтобы модель смогла обобщить эти примеры и выдавать приемлемый результат. Проблема в том, что порядок сложности задачи тоже нелегко определить заранее. Тут поможет только сравнительный анализ. Прикладные задачи машинного обучения можно сравнивать между собой по сути моделируемого вопроса. Например, известно, что задача машинного перевода - достаточно сложная и требует очень сложной и вариативной модели и, как следствие, огромного количества данных. Поэтому если вы строите модель, которая решает сходные задачи, следует ожидать, что парой тысяч примеров не отделаться. С другой стороны, задача распознавания простых визуальных образов - существенно более простая, и здесь может не понадобится гигантских объемов выборки, можно для начала ограничится парой тысяч точек.

Тут загвоздка еще в том, что сложность задачи сама по себе зависит от состава имеющихся данных. Если какой-то атрибут позволяет с высокой долей уверенности предсказывать значение целевой переменной, это сильно понижает уровень сложности задачи. И, как следствие, может хватить гораздо меньшего по объему датасета. Если же между признаками и целевой переменная связь очень слабая, то сложность наоборот, растет, как растет и требование к количеству данных. Поэтому большие усилия исследователей направлены на повышение информативности и полезности признаков, извлекаемых из данных.

Соображения, учитывающие сложность задачи, кажутся запутанными и неконкретными. Поэтому есть еще один ориентир, который может помочь в оценке необходимого объема данных. Выборка должна быть репрезентативной, то есть представлять все возможные случаи из генеральной совокупности. Если известно, хотя бы примерно, какую именно информацию об объектах предметной области можно собирать (то есть, какие атрибуты будут в датасете), то можно порассуждать, какие комбинации значений этих атрибутов встречаются в реальной жизни. Они все должны быть представлены в наборе данных, причем, желательно, по нескольку раз, так как набор данных будет подвергаться дроблению и разделению.

Например, рассмотрим задачу определения эмоций по звуку голоса человека. Как может рассуждать исследователь, перед которым стоит задача сбора данных? Во-первых, нам нужно собрать в датасет образцы голоса для разных эмоций. При этом не существует какого-то единого классификатора или набора эмоций, здесь надо исходить из контекста задачи и доступных источников данных. Во-вторых, нужны образцы разных голосов - женские, мужские, высокие, низкие. Причем, на каждый голос нужно несколько примеров со всеми эмоциями. Нужны ли записи на разных языках? Можно выдвинуть гипотезу, что проявления эмоций в голосе не зависят от языка, поэтому можно ограничиться одним или двумя языками. Итого у нас получается, что надо собрать максимальное количество голосов разных людей и для каждого голоса включить в выборку несколько примеров на разные эмоции. Допустим, мы решили выбрать голоса 20 человек. В нашем исследовании мы распознаем 8 эмоций. И для надежности нужно по 10 звуковых фрагментов на каждую комбинацию. Получается 1600 фрагментов. Если добавить второй язык, то желаемый объем датасета приблизится к трем тысячам точек.

И это не значит, что при таком объеме модель точно будет работать эффективно, это лишь необходимый минимум, с которого можно начать. При таком подходе мы обеспечиваем минимальную репрезентативность выборки, а уже после первоначального обучения, проведя диагностику модели, можно сделать вывод, хватает нам данных или нужно собрать кратно больше. Это такой быстрый черновой расчет, который может подсказать хотя бы примерный порядок количества точек, при которых вообще может идти речь о целесообразности моделирования. Иначе вся дальнейшая работа будет просто бессмысленной: если мы оценили требуемый объем в миллион точек, а нам доступны только пять тысяч, то даже не стоит и начинать более глубокий анализ.

На практике стоит учитывать не только пожелания к объему данных, но и имеющиеся в распоряжении аналитика источники. Подбор и поиск источников данных тоже очень важен для любого практического проекта. В самой первой главе мы говорили, что поиск данных является основным сдерживающим фактором, который не позволяет использовать машинное обучение в некоторых сферах. Поэтому перед началом анализа и моделирования следует определить, откуда можно будет брать те самые данные. Причем эту работу стоит проводить параллельно с оценкой объемов, так как именно доступные источники подскажут, какую именно информацию удастся собрать, а это может повлиять на сложность задачи.

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

В первую очередь стоит помнить, что источники данных могут быть внешние и внутренние. Внутренние источники - это различные корпоративные информационные система, базы данных, базы знаний, хранилища данных. В первую очередь следует подумать, какие данные по стоящей перед нами задачи уже имеются у организации и могут быть использованы. Зачастую этого бывает вполне достаточно. Если же нет, то тогда приходится обращаться к внешним источникам. Существует огромное количество готовых датасетов для решения типичных задач машинного обучения - от распознавания картинок до моделирования временных рядов цен активов. Можно попробовать найти датасет по нужной или сходной тематике на таких сайтах ка Kaggle или PapersWithCode, где публикуются целые библиотеки датасетов по рубрикам. Также часто датасеты публикуются на сайтах образовательных, научных организаций и подразделений, которые ведут исследовательскую работу. В конце концов можно искать ссылки на данные в научных публикациях, которые можно найти в специализированных системах научного цитирования типа Google Scholar.

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

При этом внешние источники информации могут быть в ограниченном доступе - например, платные или по подписке. Достоинство внешних источников данных в том, что обычно там публикуются уже готовые датасеты, которые не требуют интенсивной очистки и анализа, возможно только минимальной доводки и проверки на чистоту. В то время как информация из внутренних баз данных обычно не предназначается для машинного обучения, поэтому ее обработка может занять большое количество времени.

При сборе данных следует разделять потоковые и статические данные. Статические, или пакетные данные - это информация, которая дана в полном объеме сразу. С ней работать гораздо легче. Потоковые данные - генерируются в реальном времени с определенной скоростью. Если вам необходимо работать именно с потоковыми данными, то для этого существуют специальные техники, такие как онлайн обучение, пассивно-агрессивные модели и конвейеризация обработки данных.

Данные вообще можно не только собирать. Довольно часто по какой-то конкретной задаче вообще нет необходимых данных, либо они присутствуют в совершенно недостаточном количестве. Тогда приходится задумываться о самостоятельной генерации таких данных. Например, если вы занимаетесь распознаванием определенной категории товаров по картинке для магазина, вполне можно сделать большое количество фотографий самостоятельно. Генерация данных - процесс, конечно, более трудоемкий, чем сбор уже существующих данных, но зато в итоге может получиться датасет, который специально подходит для поставленной конкретной задачи, и он позволит строить более точные модели именно для этой задачи.

Довольно часто бывает, что собранных данных категорически недостаточно для проведения моделирования. В таком случае может помочь один прием, которых называется аугментацией данных (data augmentation). Он позволяет из одной точки данных потенциально получить несколько и таким образом кратно увеличить объем имеющегося датасета. Например, мы рассматриваем задачу распознавания рукописных символов и собрали небольшой датасет из таких картинок, но пришли к выводу, что нам нужно в разы больше данных. Каждую картинку в датасете можно повернуть на небольшой угол, изменить размер, сместить. То есть придумать какие-то небольшие изменения, модификации, которые позволяют из одной имеющейся картинки получить, потенциально, несколько десятков вариантов. Если мы применим эти модификации, то увеличим количество точек данных в датасете в такое количество раз, сколько модификаций можно применить к каждой точке. Этот прием имеет еще один положительный эффект на процесс моделирования: если модель обучается на датасете, в котором присутствуют разные варианты одной и той же картинки с разными сдвигами, то модель получается более устойчива к таким сдвигам. То есть мы не просто увеличиваем объем датасета, но еще и получаем более надежные и качественные модели. Понятно, что стратегия аугментации данных очень сильно зависит от конкретной решаемой задачи: для распознавания картинок и определения цен на сложные товары сами модификации будут принципиально разные. Но на практике аугментация данных - это очень полезный прием.

Аугментация данных - это набор методов и приемов управляемой модификации объектов обучающей выборки для увеличения объема или обобщения моделей машинного обучения на новые свойства этих объектов.

Еще одна задача, с которой часто сталкиваются при сборе данных для моделирования - разметка данных. Для обучения с учителем, как мы знаем, в датасете должны присутствовать “правильные ответы” для каждой точки выборки. Но мы можем иметь доступ к таким данным, которые очень подходят для решения задачи, но в них отсутствует именно значения целевой переменной, или такие значения имеются лишь частично. Например, решаем задачу определения мошеннических транзакций. В организации есть достаточно большая история транзакций, которую можно было бы использовать для обучения. Но в ней нет информации, какие именно транзакции считаются “подозрительными”. Такие данные называются неразмеченными (unlabelled). Было бы жалко не использовать такие прекрасные данных. В таком случае можно задуматься о ручной разметке данных - то есть специалист, эксперт предметной области, должен указать, какие транзакции считаются подозрительными, а какие - обычными. Ручная разметка данных это очень трудозатратный процесс, который зачастую требует работы нескольких экспертов. Также следует помнить, что любые экспертные оценки могут содержать ошибки. Но в некоторых случаях ручная разметка данных - единственный способ получить необходимую обучающую выборку для решения определенной задачи.

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

  1. Сбор данных из внешних открытых источников
  2. Сбор данных из внутренних источников
  3. Аугментация данных
  4. Разметка данных
  5. Сбор данных из внешних закрытых и платных источников
  6. Генерация данных

В этом списке способы выстроены от менее затратных к более. Поэтому целесообразно рассматривать сначала первый вариант из списка и переходить к следующим только если он не дает нужного результата - достаточного количества данных. Конечно, этот список примерный, в реальных задачах порядок этих способов может меняться.

Сбор данных можно назвать принципиально важным этапом решению любой задачи по машинному обучению. Ведь если что-то пойдет не так здесь, все остальное может просто не состояться. Либо, что еще хуже, состоится, но будет полностью неэффективно. Поэтому именно на этом этапе большинство реальных проектов сразу заканчиваются. Невозможность собрать нужные и качественные данные, необходимые для решения поставленной задачи моделирования - основная причина провала большинства проектов.

Выводы:

  1. После постановки задачи машинного обучения первый этап моделирования - определение источников и объема данных, необходимых для эффективного обучения.
  2. Объем данных определяется порядком сложности задачи: чем больше данных, тем более сложные модели можно на них строить.
  3. В целом, чем больше данных можно собрать, тем лучше.
  4. Данные в датасете должны быть репрезентативной выборкой генеральной совокупности.
  5. Источники данных могут быть открытые и закрытые, платные, по подписке, внутренние и внешние.
  6. Данные могут быть пакетные и потоковые, с ними надо работать по разному.
  7. Данные можно не только собирать, но еще генерировать и модифицировать.
  8. Существующие данные может потребоваться размечать.

Интеграция данных

Чаще всего данные можно найти не в одном источнике, а в разных. Но для машинного обучения нужна одна таблица. Как же объединить разные данные в единый датасет? Этот, казалось бы, тривиальный вопрос не так прост, на этом этапе есть некоторые подводные камни и неочевидные решения, о которых мы и поговорим в этой главе.

Как мы говорили, для машинного обучения чем больше данных мы соберем, тем потенциально лучшие модели мы сможем получать. Поэтому следует собрать всю информацию о предметной области, которую возможно. При этом, напоминаем, что датасет для обучения модели должен быть представлен в виде одной таблицы. А после сбора информации мы можем иметь множество таблиц, особенно, если собирали информацию из разных источников. Но даже в одном источнике нужная информация может быть разнесена по нескольким таблицам, как в реляционной базе данных. Поэтому после сбора данных у нас может быть множество разных таблиц, файлов и хранилищ данных, которые потенциально могут быть полезны. Поэтому следующий этап - это интеграция данных, то есть сведение всех разрозненных кусочков информации в единый датасет.

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

Интеграция данных - это процесс в составе предварительной обработки данных, направленный на объединение данных, представленных в разных формах в единый датасет с максимально возможным соблюдением требований чистых данных. Интеграция данных чаще всего происходит попарно - два датасета объединяются в один.

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

id height size label
1 182 52 0
2 158 50 1
+
id height size wight label
3 180 48 74 0
4 153 46 73 1
=
id height size wight label
1 182 52 NaN 0
2 158 50 NaN 1
3 180 48 74 0
4 153 46 73 1

В этом примере мы склеиваем две таблицы по вертикали. При этом получается талица, которая состоит из всех строк первой плюс из всех строк второй. А что происходит со столбцами? Для общих столбцов, то есть таких, которые есть в обеих таблицах все просто - они переносятся в таблицу-результат. А что делать со столбцами, которые присутствуют только в одной из двух таблиц-“слагаемых”, надо решать аналитику. По умолчанию, в получившейся таблице будут присутствовать все столбцы из обеих исходных таблиц. Но в ячейках, которые относились к той таблице, в которой такого столбца нет, будут записаны пропуски. В нашем примере такой столбец один - “weight” из второй таблицы. В результате в тех ячейках этого столбца, который относились к первой таблице записано специальное значение “NaN” (Not a number) - специальное обозначение пропущенного значения.

В библиотеках работы с табличной и статистической информацией для простого склеивания таблиц, нужного для вертикального объединения данных существуют специальные методы, такие как append() или concat() в pandas.

Конечно, можно представить ситуацию, когда такие “непарные” столбцы имеются в обеих исходных таблицах. По сути такая ситуация происходит, когда в разных таблицах отражена немного разная информация об объектах предметной области. Такое постоянно случается при интеграции данных из разных источников. По желанию аналитика можно настроить метод объединения таблиц таким образом, чтобы такие “спорные” столбцы вообще не включались в итоговую таблицу. То есть в результате она будет содержать только те атрибуты, которые присутствовали в обеих исходных таблицах, но зато в ней гарантировано не будет пропусков (если только их не было в исходных таблицах).

Горизонтальное объединение данных нужно, когда в исходных таблицах содержится разная информация о примерно тех же объектах предметной области. То есть в исходных таблицах примерно те же строки, но совершенно разные столбцы. Такая ситуация тоже часто случается, но обычно при объединении данных из одного источника. Например, из корпоративных реляционных хранилищ данных.

Горизонтальное объединение данных более сложно по своей природе, чем вертикальное. Дело в том, что так таблицы нельзя просто склеить - надо следить за соответствием строк. Ведь в разных таблицах могут присутствовать немного разные строки, а те, что есть в обоих - храниться в разном порядке. В реляционных базах данных для таких случаев есть специальная операция - соединение таблиц (join). Рассмотрим в качестве примера две таблицы с информацией о ценах и объемах торгов двух разных акций на бирже:

date price volume
20/01 14.56 135
21/01 15.23 280
22/01 15.07 73
23/01 15.56 160
24/01 17.85 1450
+
date price volume
19/01 23 064 15 067 894
20/01 23 050 12 784 435
21/01 23 078 16 784 373
22/01 23 125 18 543 502
23/01 23 118 13 849 293
=
date price_x volume_x price_y volume_y
19/01 NaN NaN 23 064 15 067 894
20/01 14.56 135 23 050 12 784 435
21/01 15.23 280 23 078 16 784 373
22/01 15.07 73 23 125 18 543 502
23/01 15.56 160 23 125 18 543 502
24/01 17.85 1450 NaN NaN

заметим, что если мы просто склеим эти две таблицы горизонтально, то в одной строке получится информация за две разные даты, что, очевидно, неправильно. Для того, чтобы в итоговой таблице получилась правильная информация, надо. чтобы в обеих исходных таблицах присутствовал атрибут (столбец), который позволяет однозначно идентифицировать объект данных. В данном случае таким атрибутом выступит дата (выделена жирным). В реляционной алгебре это общее поле называется ключом, по которому происходит соединение таблиц.

Никогда не используйте простое склеивание (append() или concat() в pandas) для горизонтального объединения датасетов, только специальные реляционный оператор соединения, который в SQL называется JOIN. В том же pandas его аналоги - join() или merge().

Существует много разных видов соединений таблиц по ключу - внутреннее, внешнее, левое, правое, перекрестное. Самое консервативное (в том смысле, что не удаляет никакую информацию) - внешнее полное соединение. В результирующую таблицу будет записана информация по каждому значению ключа, который присутствует хотя бы в одной таблице. Также в нее войдут все столбцы из обеих таблиц (кроме ключа, который как общая часть войдет в результат только один раз). В ячейки таблицы будет записана информация, либо специальный индикатор отсутствия значения. На примере выше показано как раз полное внешнее соединение двух таблиц. Обратите внимание, что в итоге получилось больше строк, чем в исходных таблицах, а также в некоторых ячейках стоит специальное значение “NaN”. Затем эти пропуски можно уделить.

Если в результате горизонтального или вертикального объединения данных получается большое количество пропусков, это может происходить от того, что в таблицах присутствует очень разная информация о разных объектах. То есть мало совпадений как по строкам, так и по столбцам. В таком случае стоит задуматься о том, имеет ли смысл вообще объединять такие таблицы. Или, может быть, если у вас есть еще много других таблиц, вы выбрали неоптимальный порядок их объединения.

С помощью этих двух видов объединения данных можно практически любой разрозненное множество датасетов привести к форме из единой таблицы. Конечно, придется принять множество решений по сохранению или удалению части данных, выбрать оптимальный порядок объединения таблиц, поработать потом с отсутствующими значениями, которые появились в результате объединения.

Но самое сложное в процессе интеграции данных - следить за их соответствием и цельностью. В разных датасетах могут использоваться разные единицы измерения, разные обозначениях одних и тех же объектов, разные периоды измерений. Такие несоответствия - главная головная боль аналитика по данным. Чего стоит одна лишь работа с датами. В разных таблицах даты могут обозначаться тысячью разных способов. И если за этим не следить, то в итоге получится совершенно неприменимый на практике датасет. Существует множество типичных проблем, которые часто встречаются в данных, особенно в корпоративной среде. По опыту выполнения практических проектов можно выделить такие самые типичные примеры:

  1. Разные обозначения и сокращения в данных. Например, номенклатура продукции может записываться в разных справочниках по-разному. Самое противное в этой проблеме, что ее приходится решать, руками записывая таблицы соответствия разных обозначений, что очень долго.
  2. Разные группировки объектов. Например, в одном справочнике клиенты объединены по географическому принципу, а в другом - по суммарному чеку. В одной таблице могут быть сгруппированы объекты, которые в другой относятся к разным группам. В одной базе данных три наименее малочисленные группы объединены в “другое”, в соседней - десять товаров, которые имеют менее 1% объема продаж - объединены в “остальные”.
  3. Иерархические справочники. Очень многие объекты группируются в разные иерархии. Например, та же номенклатура продукции может группироваться в группы, которые объединяются в категории и классы. Проблема в том, что не каких-то таблицах идет разбивка по конкретным товарам, в других - по категориям, в третьих - суммарные или средние значения по товарным группам. Наверное, хорошо для учета, но очень неудобно для аналитики и машинного обучения.
  4. Разные периоды наблюдений. Как в примере выше - временные ряды могут часто не соотноситься по датам и времени измерений. В одной таблице измерения идут каждый день, в другой - только в рабочие дни. И приходится либо дополнять данные, либо выкидывать большой объем информации.
  5. Разные временные базы измерений. Даже в пределах одной организации повсеместно встречается, что некоторые параметры измеряются посуточно, другие - суммарно за неделю, а третьи - раз в месяц. Понятно, что без специальной обработки их нельзя просто сводить вместе.
  6. Отдельная проблема - всякие цифровые коды, индексы и классификаторы. Особенно - какие-нибудь 20-значные цифровые номера счетов, которые имеют определенную внутреннюю структуру. Эта структура обычно “очевидна” для специалистов, которые с ней работают, но совершенно секретна для аналитиков. Из-за этого приходится “парсить” численные значения, работать с ними как со строками. Но самое неприятное в том, что такие системы кодификации могут меняться со временем, что заставляет опять вводить сложные таблицы соответствия, причем это соответствие не всегда однозначно. Причем в разных таблицах опять же могут использоваться разные классификаторы, которые как-то “очевидно” между собой соотносятся. Кому интересно, можете познакомиться с такими понятиями, как ОГРН, ОКВЭД и ОКПО. А в специальных предметных отраслях подобных обозначений еще больше.
  7. Просто разные единицы измерений и обозначения дат. Это относительно простая проблема, потому что она решается автоматической конвертацией. Главное - вовремя ее заметить.

Это может касаться как технических деталей, так и сутевых, предметных аспектов. Например, при анализе эмоций в речи можно столкнуться с тем, что в разных наборах данных, которые можно собрать по данной теме, используется разный набор эмоций. То есть в разных датасетах разный набор значений целевой переменной. Это значит, что нельзя просто объединить их, нужно что-то делать с согласованностью значений. По сути, придется частично переразметить датасет. Конечно, это можно сделать автоматически, но важно просто не забыть про это, не пропустить этот этап. И ни в коем случае, нельзя предполагать, что в данных все хорошо и нет проблем. Это всегда надо проверять и тестировать.

В этом учебнике мы не рассматриваем различные стратегии преобразования и парсинга данных которые требуются, если исходная информация существует в виде, сильно отличном от табличной или реляционной формы. Это уже предмет не аналитики данных, а общего программирования - преобразовать данные в той форме, которая необходима для анализа.

Именно за счет таких мелких деталей, интеграция данных считается самым сложным и трудозатратным этапом машинного обучения. Несмотря на то, что здесь не используется крутая математика, этот этап не требует огромных вычислительных мощностей, на практике, он занимает до 80% всего времени работы над проектом по машинному обучению. Кроме того на этом этапе возникают большинство ошибок и артефактов в данных, которые критично сказываются на эффективности моделей. Поэтому не нужно недооценивать важность и продолжительность этого этапа. На сбор и интеграцию данных не стоит жалеть усилия и экономить ресурсы. Всегда помните про принцип “мусор на входе - мусор на выходе”, ведь объем и качество данных - самое важное для машинного обучения.

Чтобы иметь возможность исправить ошибки, которые неизбежно могут возникнуть на этом этапе, всегда сохраняйте исходные данные, даже после проведенной интеграции. По возможности можно хранить и промежуточные датасеты. Это будет критически важно, когда в результате последующего анализа вскроются какие-то ошибки и неточности, допущенные при интеграции.

Правильно проведенная интеграция данных способна сильно облегчить их дальнейшую обработку, очистку и анализ. И наоборот, ошибки, допущенные на этом этапе могут сильна “загрязнить” данные, вплоть до их полной непригодности для дальнейшего использования. Поэтому интеграция данных зачастую выполняется итеративно, несколько раз, пока не будет найден такой оптимальный способ интеграции, который дает наилучшее представление данных в итоге.

Выводы:

  1. Интеграция данных - это процесс объединения данных из нескольких источников в единый датасет.
  2. Объединение датасетов может происходить по горизонтали и по вертикали.
  3. Вертикальное объединение датасетов - это по сути просто склеивание двух однотипных наборов данных в один.
  4. Горизонтальное объединение датасетов происходит обязательно через аналог операции JOIN по ключу.
  5. При объединении данных из разных источников необходимо особенно тщательно следить за обозначениями, соглашениями, датами.
  6. Интеграция данных - самая трудная часть работы с машинным обучением.

Описательный анализ данных (EDA)

Можно ли использовать данные после сбора и интеграции? Еще нет, их обязательно надо проанализировать. На этом этапе надо проверить, удовлетворяют ли они всем требованиям чистых данных, обнаружить все возможные проблемы в них и исправить все, что обнаружили. Как это сделать, что именно искать и какие конкретно действия над данными нужно произвести, мы и поговорим в этой главе.

После завершения сбора и интеграции данных, то есть когда у вас уже есть единый датасет, который планируется использовать как обучающую выборку, приходит пора заняться его анализом и обработкой. Конечно, отдельные элементы анализа данных стоит проводить и на этапе сбора информации из различных источников, чтобы обнаружить критичные проблемы в данных, из-за которых данный источник стоит вообще “забраковать”. Но именно после получения готового датасета стоит заняться анализом и обработкой более системно, так как вы будете видеть всю доступную информацию и не придется повторять одни и те же процедуры на разных данных.

Многие термины, используемые в этом учебнике взаимозаменяемо, могут запутать читателя. В машинном обучении этап после завершения формирования датасета и до начала непосредственно обучения моделей состоит вперемешку из операций анализа и преобразования данных. Поэтому он может называться описательный анализ данных, предварительный анализ, предварительная обработка данных, преобразование данных, очистка данных. Конечно, между этими терминами можно провести формальное разграничение, но для целей машинного обучения нет анализа без обработки и обработки без анализа.

В первую очередь надо определиться, зачем вообще нужен предварительный анализ данных? Разве мы не говорили, что если информация подходит по форме под определение “чистых данных”, то ее можно использовать для моделирования? Да, но при сборе и интеграции данных можно обеспечить выполнение только основных требований чистых данных. Кроме этих обязательных, есть еще два условия, которые почти всегда стоит соблюсти. Это требование к отсутствию пропусков и требование к численному представлению данных.

Вообще, данные, полученные из реального мира могут содержать всяческие проблемы и ошибки, которые почти всегда негативно сказываются на эффективности применяемых моделей машинного обучения. Кроме пропусков и неправильных типов данных могут присутствовать просто ошибки, опечатки, некорректные данные, аномальные, непоказательные объекты и еще много всего. Так что главная цель предварительной обработки и анализа данных в первую очередь состоит в том, чтобы еще больше очистить данные, устранить все возможные проблемы (“артефакты”) в них.

Но механическая очистка данных - это еще не ве и не решение всех проблем. Мы уже несколько раз упоминали, что эффективная работа с данными невозможна без их глубокого понимания, погружения в предметную область. И поэтому вторая главная задача предварительного анализа данных - ближе познакомиться с этой самой информацией. Такой анализ может дать подсказки, какие именно методы предобработки лучше использовать. Ведь с теми же пропущенными значениями можно бороться несколькими принципиально разными способами. И вообще на этапе очистки данных приходится принимать множество потенциально важных для моделирования решений. Глубокий анализ данных позволяет выбрать наиболее эффективные методы как обработки данных, так и непосредственно моделирования.

Даже такая простая информация, как диапазон измерения тех или иных атрибутов, которую в pandas можно получить одной строкой может многое прояснить - шкалы измерения разных атрибутов, возможные ошибки в данных, значения, которые лежат вне разумных диапазонов, количество значений категориальных переменных. И это все может в будущем повлиять на методы обработки этих данных.

Еще раз подчеркнем, что в данной главе мы сосредоточимся на рассмотрении только главных этапов так называемого описательного анализа данных (exploratory data analysis, EDA) и предварительной обработки данных для их подготовки к использованию в моделях машинного обучения. Конечно, мы не можем даже обзорно рассмотреть все многообразие методов анализа и обработки данных. Поэтому далее рассмотрим шаги, которые являются критичными и самыми распространенными при анализе практически любых реальных данных. А при необходимости можно и даже нужно проводить более глубокий анализ данных, возможно, с привлечением статистических методов и критериев, проверки гипотез, математических доказательств и прочей тяжелой артиллерии.

Вообще, чем глубже проводить анализ данных, тем лучше. В большинстве случаем временные затраты на анализ используемой информации с лихвой компенсируются тем, что в процессе этого анализа можно обнаружить скрытые зависимости, тенденции, которые невозможно заметить при обычном беглом осмотре данных, а тем более при слепом использовании датасета в моделях. В конечном итоге подробный анализ данных приводит к получению более качественной информации. А в машинном обучении качество данных гораздо важнее “продвинутости” моделей и алгоритмов. Даже простые модели на хороших, подготовленных данных будут демонстрировать качественно боле высокую эффективность, чем самые крутые и глубокие нейросети на “грязных”, неочищенных и нерелевантных датасетах.

В данной части учебника мы будем рассматривать типичные задачи предварительного анализа и обработки данных отдельно. Но в реальности, это более взаимосвзяанный, итеративный процесс. Поэтому нет смысла рассматривать отдельно сначала анализ, затем обработку данных. Эти процессы переплетаются, ведь анализ может выявить проблемы в данных, которые нужно устранить, соответствующим образом преобразовав датасет. А преобразования данных зачастую требуют повторения определенных шагов анализа. Поэтому важно помнить про основные задачи этого этапа и решать их последовательно, перемежая исследование и изменение данных.

Выводы:

  1. Описательный анализ данных нужен для обнаружения проблем (артефактов) в данных и для выбора метода их устранения.
  2. EDA также может дать информацию о структуре данных, шкалах измерения переменных, которые потом повлияют на методы обработки данных.
  3. Также EDA может помочь при выборе признаков, выявлении зависимостей в данных.
  4. EDA - это обзорный анализ данных именно при их подготовке к процессу машинного обучения.
  5. При необходимости, можно провести более глубокий статистический анализ данных.
  6. Анализ и обработку данных обычно производят параллельно, это не изолированные процессы.

Анализ репрезентативности датасета

Не самым распространенным, но, несомненно, полезным этапом описательного анализа данных является анализ репрезентативности выборки. Конечно, не в каждой задаче исследователь имеет доступ к информации о генеральной совокупности объектов описываемой предметной области, однако, в случае наличия информации, даже простой подсчет, какой процент ГС описывает обучающий набор данных может дать представление о потенциальной обобщающей возможности модели машинного обучения. Кроме того, на данном этапе может выполняться проверка адекватности распределения признаков теоретическим или эмпирическим экспертным знаниям о предметной области.

Основные задачи:

Выводы:

  1. Для машинного обучения важно, чтобы датасет правильно отражал генеральную совокупность. Это дает модели обобщающую способность.
  2. Анализ соотношения выборки и генеральной совокупность не всегда возможно провести, но когда можно - нужно это делать.
  3. Самая простая метрика - процент ГС, который отражен в выборке.
  4. Важно понимать, как были собраны данные, по какому принципу они отбирались. Лучше - случайно.
  5. Может быть проведена проверка адекватности распределения признаков экспертным знаниям в области.
  6. На этом этапе принимается общее решение о целесообразности моделирования.
  7. Не следует забывать о предметной специфике.

Описание шкалы измерения атрибутов

Как начать анализ данных? В первую очередь на сами данные обязательно надо посмотреть - вывести первые несколько строк, познакомиться со структурой датасета - количеством строк и столбцов, названиями атрибутов. Для понимания всего набора данных в первую очередь необходимо понимать каждый атрибут в отдельности. Об этом и поговорим в этой главе.

Самый простой этап анализа данных - индивидуальное рассмотрение каждого атрибута в датасете. Для эффективной работы с информацией аналитик должен понимать смысл каждого столбца датасета, что он измеряет, какие значения может принимать, какие операции и преобразования с ним имеет смысл производить. Повторимся, что для моделирования важно понимать именно смысл используемых данных, не стоит ограничиваться формальным описанием.

Конечно, когда мы говорим про анализ каждого атрибута, имеется в виду каждый значимый атрибут. В простых задачах, когда количество столбцов в датасете ограничено единицами или максимум, десятками, можно подробно поработать с каждой колонкой, провести небольшой статистический анализ абсолютно каждого атрибута. В реальных задачах часто количество атрибутов идет на сотни и тысячи, что делает такую индивидуальную работу невозможной. Конечно, надо исходить из конкретной задачи. Во многих проектах можно сильно сократить количество атрибутов, удалив лишние просто по смыслу. В других - атрибуты представляют собой какие-то однородные данные. Как, например, в картинках, где каждый пиксель - это отдельный признак. Конечно, не идет речь о том, чтобы анализировать каждый пиксель картинки отдельно.

Пре работе в конкретными атрибутами самое главное, что нужно понимать - это различные типы шкал. Типы шкал активно изучаются в таком разделе науки, как метрология. Общепринято различают четыре главных типа шкал по Стивенсу. Для анализа данных очень полезно охарактеризовать шкалу измерения каждого атрибута. А особенно - понять тип этой шкалы. Но для этого надо уметь различать эти типы на практике, исходя из смысла каждого атрибута как характеристики объекта предметной области. Поэтому рассмотрим основные типы и их отличительные черты.

Шкала - это множество возможных значений переменной и совокупность операций и отношений, которые имеют смысл применительно к этой переменной.

flowchart TB; scales["Шкалы данных"] --> cat["Категориальные"] & num["Численные"]; cat --> bin["Бинарные"] & nom["Номинальные"] & ord["Порядковые"]; num --> int["Интервальные"] & abs["Абсолютные"] & log["Логарифмические"];

Самое главное разделение, которое надо знать - это разница между численными и категориальными атрибутами (признаками). Категориальный признак может принимать только одно из конечного набора значений. Категориальные признаки - это как классы в задачах классификации. Они часто выражаются каким-то текстовым называнием, меткой, обозначением. Численные признаки, соответственно, могут принимать значения из некоторого непрерывного интервала и всегда могут быть выражены числом. Категориальные переменные еще называются иногда дискретными, качественными или неметрическими, а численные - непрерывными, количественными или метрическими.

Мы уже говорили про разницу между этими типами шкал, когда определяли задачу регрессии и классификации. Но категориальной или численной может быть не только целевая переменная, а любой атрибут или признак в данных. Это разделение так важно потому, что работа с категориальными и численными данными принципиально различается. В частности, все категориальные признаки перед началом машинного обучения нужно будет обязательно преобразовать в численные.

Важно не путать тип шкалы измерения атрибута и тип данных в языке программирования. Это схожие вещи, но если вы будете полагаться на анализ только по типу данных, вы будете совершать существенные ошибки в анализе. Численные атрибуты спокойно могут существовать в данных в виде строки, например просто потому, что где-то в процессе получения данных они так считались. Уже не будем говорить о любимых в некоторых сферах суммах прописью. А категориальные атрибуты вполне могут быть выражены числом (как, например, класс обслуживания в знаменитом датасете “Титаник”).

Пойдем немного дальше. Категориальные шкалы измерения признаков, в свою очередь, делятся на номинальные и порядковые шкалы. Номинальная шкала (ее еще называют шкалой наименований) - это такая, про каждые два значения которой можно только сказать, равны они или нет. То есть единственная операция, которая имеет смысл с переменной, выраженной в номинальной шкале - это операция проверки на равенство. Более математически выражаясь, можно сказать, что в номинальной шкале определено только отношение эквивалентности (тождества). Номинальные шкалы - это почти самый простой тип шкалы, это именно такие шкалы, про которые люди интуитивно думают, когда представляют себе категориальную переменную.

Примером номинальной шкалы можно назвать различные объекты, которые можно распознавать на изображении, названия стран, марки телефонов, вообще любые названия - организаций, производителей, товаров, различные типы объектов. Кстати, не всегда категориальные или номинальные переменные обозначаются числом. Типичный пример - номера маршрутов общественного транспорта. Несмотря на то, что это именно номер, тип шкалы такой переменной - номинальная.

Порядковые шкалы (их еще называют ординальные или ранговые) - это тоже категориальные переменные, то есть принимающие определенные значения из конечного набора, но между значениями которых есть отношение как тождества, так и порядка. Другими словами, про каждые два значения из этой шкалы можно сказать, какое из них больше (либо они равны друг другу). Еще говорят, что значения из этой шкалы можно ранжировать - выстроить по порядку. Еще раз обращаем ваше внимание, что тип шкалы - это не про какие-то конкретные значения, это про смысл данной переменной, признака, характеристики. Типичными примерами порядковой шкалы будут балльные оценки: удовлетворительно, хорошо, отлично; уровень образования - начальный, средний, высший. Несмотря на то, что значения этой характеристики обозначаются текстом, их можно сравнивать между собой. То есть можно сказать, что высшее образование - это больше, чем среднее, а среднее - это больше, чем начальное. Кстати, отношение порядка по определению транзитивно. Так что из этого следует, что высшее - больше, чем начальное.

Среди категориальных шкал особое значение имеют так называемые бинарные переменные. Это такие атрибуты, которые могут принимать всего два значения. Они могут быть как порядковые, так и номинальные. Хотя отношение порядка в таких переменных носит довольно уловный характер. Типичный пример такой бинарной шкалы - пол. Почему эта шкала особенная? Именно в машинном обучении и анализе данных ее можно преобразовывать особым образом - представлять в виде булевой переменной со значениями 0 и 1. Причем порядок этих значений не играет роли. Вспомните бинарную классификацию и то, какую особую роль она играет. Бинарная шкала - это действительно самый простой тип шкалы.

Ключевое различие между порядковыми (ординальными) признаками и номинальными в том, как их можно преобразовывать в численную форму. Делов том, что номинальные признаки нельзя просто поименовать числами, как многие делают в анализе данных. Это большая ошибка, так как это преобразование привносит в данные искусственный порядок, которого в них не было (по определению номинальной шкалы). Допустим, у нас в датасете есть колонка “производитель телефона”. И для того, чтобы преобразовать эту категориальную переменную в число мы просто обозначили разные значения числами, например “Apple” - 0, “Samsung” - 1, “Sony” - 2 и так далее. После такого преобразования модель будет воспринимать эту переменную как численную. А это значит, что модель может в своих расчетах полагаться на то, что Sony - это в два раза больше, чем Samsung, что, очевидно, абсурд. Как именно преобразовывать такие переменные мы расскажем в следующих главах.

Здесь надо отметить, что часто к какой шкале отнести переменную зависит и от интерпретации задачи. Опять же, здесь надо исходить из смысла, а не формы. В том же примере с производителями телефонов можно придумать пример, в котором нам важна, например, рыночная доля каждого производителя. Тогда между ними действительно можно выстроить некоторый порядок. Так и в других примерах, в зависимости от нашего понимания и контекста задачи одна и та же характеристика объекта может быть отнесена к разным типам шкал. Но, надо признать, это довольно редкий и экзотический случай. Обычно тип шкалы полностью очевиден из смысла данной переменной.

Переходим к численным шкалам. Различие между конкретными видами численных шкал гораздо менее важно для машинного обучения, чем между номинальной и порядковой. Но для полноты изложения, приведем и их характеристики. Тем более, что они все-так могут пригодиться на практике. Среди численных шкал выделяют интервальную и абсолютную шкалу. Интервальная шкала (она же шкала разностей) - это такая, про два значения из которой всегда можно сказать, на сколько одно больше другого (кроме сравнения и эквивалентности, как в предыдущих шкалах). То есть в ней имеют смысл разницы между значениями. Типичный пример - даты. Для данной шкалы имеют смысл такие преобразования, как сдвиги. То есть можно, например, из даты рождения получить возраст человека. А вот умножать даты и возраст некорректно.

Наконец, абсолютная шкала (ее также называют шкалой отношений) - это такая, для любых двух значений которой можно еще сказать, во сколько раз одно значение больше другого. Опять же, именно эту шкалу интуитивно представляют, когда говорят о численных переменных. Это свойство шкале придает наличие абсолютного нуля - точки отсчета. Данная шкала допускает, кроме вех предыдущих еще и умножение на константу. Именно по абсолютной шкале измеряются все физические величины - вес, рост, длина, напряжение, а также стоимость, цена. Вообще, абсолютная шкала очень распространена.

Надо отметить еще один специальный тип шкалы, с которым надо работать особо, хотя формально, по Стивенсону, он относится к абсолютной шкале. Очень часто в экономических и физических задачах встречаются величины, которые могут принимать только положительные значения, от нуля до бесконечности и при этом их значения покрывают несколько порядков величины. У таких переменных имеет очень небольшой смысл разница между значениями, чаще нам важнее именно отношение. За счет того, что абсолютные значения в таких переменных очень сильно разнятся по величине, на практике очень удобно рассматривать логарифм этих значений. Поэтому такую шкалу будем называть логарифмической. Мы уже сталкивались с такой проблемой, когда рассматривали метрики эффективности регрессии.

Определение типа шкалы это важная часть работы с каждым отдельным атрибутом датасета. Но шкала измерения переменной не ограничивается только типом. Разные переменные могут измеряться по разным шкалам, даже относящимся к одному типу. Поэтому кроме типа необходимо рассмотреть еще несколько ключевых характеристик шкал. Во-первых, это так называемая мера центрального элемента или, простыми словами, среднее значение данной переменной. Проблема в том, что по разным типам шкал центральный элемент нужно определять разными способами. Для номинальных шкал единственное, что можно определить - моду, то есть такое значение, которое встречается в выборке чаще других. Для порядковой шкалы можно посчитать медиану - значение, больше которого и меньше которого одинаковое количество объектов в датасете. По шкале отношений самой адекватной мерой центрального элемента будет простое среднее арифметическое. Оно же часто используется и для абсолютной шкалы, но если мы имеем дело с логарифмической переменной, то более грамотно будет воспользоваться средним геометрическим.

Кроме центрального элемента интерес представляет в целом вопрос, как объекты выборки распределяются по разным значениям из шкалы данной переменной. Для категориальных признаков можно узнать все значения (их же конечное количество) то, сколько объектов датасета имеет каждое конкретное значение. Это и есть дискретное распределение (причем эмпирическое, ведь мы говорим о реальных данных). А для численных шкал очень полезно узнать диапазон значений (минимальное и максимальное значение) и то, какие интервалы внутри него более “популярны”, а какие менее. Для этого можно строить таблицы, процентили и квартили. Но самым удобным и наглядным инструментом будет гистограмма. Она покажет общий вид распределения объектов выборки по значениям любого признака - как категориального, так и численного. Но надо помнить, что для переменных, в которых присутствует порядок (то есть с порядковых и дальше) значения в гистограмме было бы логично и более наглядно упорядочить именно в этом, естественном порядке. Что, в общем, справедливо и для других инструментов анализа - и графических и табличных.

Простая гистограмма настолько популярный и полезный инструмент анализа, что ее построение встроено в библиотеку pandas и может быть сделано вызовом всего одного метода у столбца (то есть серии):

1
training_set['Age'].plot.hist(bins=30)

Это гистограмма распределения пассажиров по возрасту в популярном тренировочном наборе данных “Титаник”. По ней мы видим, что явно аномальных значений нет. Средний возраст - 20-30 лет, минимальный - 0, максимальный - 80 лет. Присутствует небольшой всплеск на малых значениях возраста, что вполне объяснимо тем, что люди предпочитают путешествовать с детьми. В остальном можно предполагать, что данные распределены близко к нормальному закону.

Даже простой анализ шкалы распределения может показать очень многое - можно выявить аномалии в данных, значения вне разумного диапазона, банальные опечатки или артефакты преобразования данных (в программном коде, который осуществляет сбор, интеграцию и преобразование данных тоже могут содержаться ошибки). Можно сделать предположение о виде распределения каждой переменной - равномерное ли оно, похоже ли на нормальное, экспоненциальное или какое-то другое из известных статистических распределений. Особенно странно смотрятся мультимодальные распределения, а также необъяснимые “провалы” на гистограммах. Все такие аномалии и странности нужно попытаться проинтерпретировать, объяснить. Самые странные артефакты - ошибки, опечатки, “странные” единичные значения можно попробовать удалить из датасета. Но опять же, в каждом конкретном случае надо руководствоваться пониманием предметной области и контекста задачи.

Выводы:

  1. Шкалы атрибутов показывают, какие значения может принимать этот атрибут и как его можно интерпретировать и сравнивать.
  2. Все атрибуты подразделяются на численные (непрерывные) и категориальные (дискретные).
  3. Категориальные переменные потом придется преобразовать в численные.
  4. Номинальная шкала - это признак, для которого имеет смысл только равенство. Пример - метка класса.
  5. Порядковая шкала - это когда наряду с равенством мы можем выстроить значения по порядку, который имеет смысл. Пример - класс обслуживания.
  6. Интервалая шкала - это когда еще имеет смысл говорить о разнице между двумя значениями. Пример - даты.
  7. Абсолютная шкала - это когда еще можно говорить о том, во сколько раз одно значение больше другого. Пример - сумма денег.
  8. Особенные типы шкал - бинарная и логарифмическая.
  9. Кроме типа шкала характеризуется диапазоном или набором значений, мерой центрального элемента и разброса, распределением.
  10. Самый полезный инструмент для характеристики шкалы - гистограммы.

Визуализация распределения атрибутов

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

Выводы:

  1. Оценка эмпирического распределения атрибутов дает ценную информацию, которая определяет дальнейшую работу с этим атрибутом.
  2. Можно использовать статистические методы, но обычно достаточно визуально оценить распределение по графику.
  3. Категориальные переменные обычно изображают на графике, или списком в порядке убывания количества объектов.
  4. Для численных переменных обычно строят график плотности распределения, хотя иногда - тоже гистограмму.
  5. Для категориальных переменных оценивают долю каждого класса в датасете, сбалансированность распределения, моду.
  6. Для численных переменных оценивают минимальное и максимальное значение, меры центрального элемента и разброса.
  7. Для численных переменные еще оценивают вид распределения - равномерное, нормальное, логнормальное, экспоненциальное и т.д.

Проблема несбалансированных классов

Дисбаланс классов Источник: analyticsvidhya.com.

Множественный дисбаланс Источник: ResearchGate.

К чему приводит дисбаланс Источник: DSSE.

Выводы:

  1. Сбалансированность классов - это равномерность распределения целевой переменной в задачах классификации.
  2. Сильно несбалансированные классы плохо сказываются на эффективности обучения, так как модель подстраивается под мажоритарный класс.
  3. Самый простой способ устранения - удаление случайной части объектов мажоритарного класса, но это приводит к кратному уменьшения датасета.
  4. Можно попробовать добавить объектов миноритарных классов, но это не всегда возможно.
  5. С несбалансированными классами неплохо справляются иерархические классификаторы.
  6. Можно попробовать модифицировать алгоритм обучения, придав классам веса.
  7. Если ничего не помогает, возможно следует пересмотреть постановку задачи, разбить мажоритарный класс, переформулировать проблему.
  8. Нужно проводить анализ ошибок

Оценка влияния атрибутов на целевую переменную

При решении задач обучения с учителем весьма полезно оценить форму совместного распределения целевой переменной с каждым признаком в отдельности. Это позволяет сделать первичное эмпирическое предположение о влиянии каждого фактора на результирующую переменную. Если распределение какого-то конкретного признака разное при разных значениях целевой переменной - это точный индикатор того, что признак влияет на значение целевой переменной

Здесь, как и в статистике, мы понимаем понятие “влияние” в чисто математическом, количественном смысле. Говорят, что переменная А влияет на переменную В, если при разных значениях переменной А переменная В принимает в среднем также разные значения. Это совершенно не подразумевает влияния в повседневном смысле, когда изменение одной величины является причиной изменения другой. Как говорят в статистике, “корреляция не подразумевает причинности”.

Для того, чтобы визуально оценить степень влияния каждого атрибута на целевую переменную, необходимо построить визуализацию их совместного распределения. Для этого используют разные виды диаграмм и графиков. Какой именно вид диаграммы лучше всего использовать прежде всего зависит от типа шкал измерения данного признака и целевой переменной.

Если и признак и целевая переменная носят категориальный характер, то можно построить обычную таблицу, в которой по строкам будут перечисленны все возможные значения целевой переменной, а по столбцам - признака (можно и наоборот, это не принципиально). В ячейках нужно привести количество объектов обучающей выборки, обладающих такой комбинацией значений. Вместо абсолютного количества еще удобнее изображать долю, но считать ее только из количества объектов с данным значением признака. При этом ячейки в таблице можно автоматически раскрасить, чтобы различия в значениях были еще более заметны.

Если при разных значениях целевой переменной эти доли отличаются, это указывает на наличие связи между признаком и целевой переменной. Причем чем больше отличие, тем сильнее связь. Если значений не очень много, то очень наглядно будет изобразить это распределение на гистограмме с несколькими столбцами. Для примера приведет совместное распределение пассажиров все того же “Титаника” по полу и целевой переменной, которая характеризует, выжил пассажир или нет:

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

Если же признак и целевая переменная имеют разные типы шкал, например, признак - количественный, а целевая переменная - категориальная, то можно строить оценки плотности. Это график наподобие гистограммы, только сглаженный и представленный в виде линии. Он показывает, сколько объектов выборки лежат в данном диапазоне значений. Вот пример распределения пассажиров по возрасту в зависимости от того, выжил пассажир или нет:

Из этой визуализации видно, что два распределения в целом похожи (их относительная высота не очень важна, имеет значение именно форма распределения), но среди выживших значительно больше детей - в возрасте до 10 лет. Это тоже вполне объяснимо, учитывая что речь идет о кораблекрушении. Поэтому мы можем сделать вывод, что возраст пассажира тоже оказывает некоторое влияние на целевую переменную, хотя и не такое явное как возраст, в значительно меньшей степени.

Если же оба показателя выражаются по непрерывной шкале, то очевидным выбором визуализации может служить диаграмма рассеяния, например, такая:

В таком графике очень легко обнаружить наличие связи между изображенными переменными. Если связи нет, то облако точек будет иметь круглую форму, либо вытянутую в направлении одной из осей. Если же облако имеет выраженный тренд, то это говорит о наличии связи. Достоинством анализа графика совместного распределения является то, что на ней можно увидеть не только линейную, но и более сложные типы связей.

Совершенно не нужно ограничиваться именно упомянутыми здесь типами визуализаций. Это всего лишь советы для начинающих, какие типы графиков можно использовать в разных ситуациях. На самом деле же их гораздо больше и выбирать следует ту, которая наиболее явно выражает нужную зависимость в данных. Важную роль играет и разнообразие средств визуализации. Помните, что любое графическое представление информации нужно только для того, чтобы более ясно увидеть что-то, скрытое в данных. За подробным описанием различных типов графиков и диаграмм следует обратиться к документации к таким библиотекам как matplotlib и seaborn.

В дополнении к построению совместного распределения отдельных признаков и целевой переменной иногда следует построить совместное распределение пары признаков и целевой переменной. Может быть такое, что каждый признак в отдельности не сильно влияет на целевую переменную, а они два вместе - влияют явно. Это, конечно, более сложный случай и анализировать это уже не так интуитивно понятно и очевидно. В качестве простого инструмента такого многомерного анализа можно посоветовать уже упомянутые таблицы с группировками:

Также можно экспериментировать с разными типами графиков, которые наглядно изображают одновременно три переменные. Опять же, приходится учитывать тип этих переменных. Нет смысла перечислять рекомендуемые типы визуализаций при всех возможных комбинациях типов шкал трех и более признаков. Даже сам поиск необходимой визуализации может привести к тому, что на каких-то графиках открываются неожиданные аспекты данных, поэтому такой поиск ценен сам по себе.

Ну и конечно же не стоит относиться к визуализации данных механически, формально. Нет никакого смысла строить кучу однотипных графиков, просто чтобы охватить все комбинации признаков и целевой переменной. К анализу данных надо подходить вдумчиво и осознанно, ни на секунду не забывая про предметную область и реальный смысл исследуемых данных и признаков. В таком случае и результаты анализа будут более содержательны и полезны, и само моделирование будет более эффективным. Ведь в результате предварительного анализа данных часто возникаю идеи, как наилучшим образом эти данные преобразовать, какие признаки добавить, какие исключить, какие атрибуты переделать, модифицировать и как именно. Эта деятельность называется инжиниринг признаков. И в сложных задачах именно работа с признаками может дать наибольшее увеличение эффективности моделей машинного обучения.

Инжиниринг признаков - это преобразование данных, направленной на создание из атрибутов таких признаков, которые будут наиболее полезны и релевантны при моделировании.

Очень полезный и часто применяемый метод исследования влияния признаков - корреляционная матрица. Это матрица, в которой по горизонтали и по вертикали отложены столбцы набора данных (как правило вместе с целевой переменной). В ячейках матрицы указаны коэффициенты парной линейной корреляции между данными величинами.

Корреляция - это статистическая взаимосвязь нескольких (как правило двух) переменных, когда изменения значения одной из них сопутствуют изменению другой (в среднем). Коэффициент корреляции выражает силу этой взаимосвязи численно. Измеряется в диапазоне от -1 до 1, где 0 - полное отсутствие связи, 1 - полная прямая связь, -1 - полная обратная связь (увеличение одной переменной влечет уменьшение другой).

Корреляционная матрица показывает сразу очень большой объем информации обо всех признаках, входящих в датасет. А с помощью современных библиотечных средств ее можно построить буквально в одну строку кода. Поэтому ее так часто применяют в анализе данных для машинного обучения. Вот как корреляционная матрица выглядит для датасета “Титаник”:

При анализе корреляционной матрицы нам интересны ячейки, которые сильно отличаются от 0, то есть близки к -1, либо 1. Вообще, знак коэффициента корреляции нам здесь не важен, так как он показывает именно направление связи. Можно легко заметить, что матрица корреляции симметрична относительно своей главной диагонали. А на самой главной диагонали все коэффициенты равны 1. Это очевидно, так как корреляция любой переменной с самой собой всегда стопроцентная.

Что же интересного мы видим в этой матрице? Какие пары столбцов коррелируют сильнее других? В первую очередь нужно обратить внимание на строку (или столбец), соответствующий целевой переменной. Высокие корреляции с ней показывают признаки, демонстрирующие большое влияние, а следовательно, значимость для модели. В нашем примере это пол, класс обслуживания, цена билета.

Еще стоит обратить внимание на признаки, которые сильно коррелируют друг с другом. Это явление называется мультиколлинеарность признаков и для некоторых моделей как раз, скорее, негативно сказывается на эффективности моделей. В примере мы можем обнаружить высокую корреляцию между классом обслуживания и ценой билета. Это очень понятно по смыслу. Причем связь именно обратная: чем класс выше (то есть число меньше, ведь первый класс - самый высокий), тем выше и цена. В таком случае стоит задуматься об исключении одного из таких признаков из модели, так как они по сути взаимозаменяемы. Причем чем выше корреляция, тем скорее можно выбросить один из признаков.

Главным недостатком корреляционной матрицы является то, что она способна показать наличие только линейной связи между переменными. Если предполагается, что может быть сильная, но нелинейная связь, можно воспользоваться следующим методом.

При анализе важности признаков применяют еще один прием, который называется feature_importance. Он заключается в обучении простой интерпретируемой модели на имеющихся данных для того, что бы получить вектор относительной важности всех признаков. Обучение модели здесь проводится не для того, чтобы получить эффективную модель, которая может качественно предсказывать целевую переменную, а лишь для того, чтобы модель показала, какие признаки были ей полезны при построении предсказания, а какие - не очень. Вот пример обучения такой вспомогательной модели для извлечения feature_importance:

1
2
3
4
5
from sklearn.ensemble import RandomForestClassifier
importances = RandomForestClassifier().fit(X, y).feature_importances_

forest_importances = pd.Series(importances, index=X.columns).sort_values()
forest_importances.plot.bar(yerr=std, ax=ax)

Не всякая модель подойдет для такого. Для анализа относительной важности признаков используют именно интерпретируемые модели, после обучения которых, по внутренним параметрам можно проанализировать эту самую важность признаков. Для этих целей чаще всего применяют линейную либо логистическую регрессию, деревья решений или случайный лес (это ансамбль из нескольких деревьев). Конечно, интерпретировать модель вручную не нужно, библиотечные реализации включают в себя специальный атрибут, в который записывается эта относительная важность. Относительную важность обычно изображают на гистограмме:

В этом очень показательном примере мы видим, что три признака оказывают очень сильное влияние на целевую переменную - это возраст, пол и цена билета. Эта информация в общем-то согласуется с смыслом данных характеристик, анализом предметной области и здравым смыслом. Но можно заметить некоторые противоречия с корреляционной матрицей. Например, по матрице, класс обслуживания сильнее влиял на целевую переменную. А возраст - вообще не показывал взаимосвязи. Это можно объяснить тем, что эта взаимосвязь получилась нелинейной. Поэтому в целом вектору относительной важность доверять можно чуть больше, чем матрице корреляций.

Выводы:

  1. Очень полезно оценить влияние каждого атрибута на целевую переменную.
  2. Для этого обычно строят совместное распределение атрибута и целевой переменной. Какой тип визуализации использовать - зависит от шкал.
  3. Если обе переменные численные - строят диаграмму рассеяния.
  4. Если обе переменные категориальные - можно строить гистограммы с несколькими столбцами или таблицы (часто раскрашивают).
  5. При необходимости можно строить графики совместного распределения двух атрибутов и целевой переменной. Но они уже более сложные.
  6. Этот этап может дать информацию о том, какие атрибуты важны, а какие можно и удалить из модели.
  7. Очень полезно строить корреляционную матрицу и оценивать по ней взаимовлияние признаков и целевой переменной.
  8. Можно строить простые модели, чтобы анализировать feature importance.

Построение корреляционной матрицы

Построение корреляционной матрицы дает очень наглядное и полное представление о влиянии каждого атрибута как на целевую переменную, так и на другие факторы, поэтому многие исследователи используют ее как завершающий этап описательного анализа данных. Однако, недостатком корреляционной матрицы можно является учет только факторов, выраженных в числовых шкалах. Корреляционная матрица прекрасно выявляет мультиколлинеарность факторов и является первой диагностикой для исключения факторов из дальнейшего моделирования.

Основные задачи:

Выводы:

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

Обнаружение аномальных объектов в датасете

Задача обнаружения аномалий сама по себе представляет собой область машинного обучения. Методы и инструменты данной сферы иногда применяются для предварительного анализа данных в целях идентификации выбросов, выбивающихся из общего ряда наблюдений значений конкретного признака. Несмотря на то, что задача обнаружения выбросов, несомненно, полезна для анализа данных, использование такого сложного и затратного инструмента редко может быть оправдано.

Основные задачи:

Выводы:

  1. Аномальные объекты - это те, которые по своим значениям сильно отличаются от большинства.
  2. Часто аномалии означают ошибки в данных, опечатки, значения вне разумного диапазона для атрибута.
  3. Выбросы (единичные значения атрибута, далеко отстоящие от всех соседей) - почти всегда свидетельствуют об ошибках в данных.
  4. Аномалии можно увидеть на графиках, но если атрибутов слишком много, не все аномалии могут быть выявлены.
  5. Обнаружение аномалий - сама по себе задача машинного обучения, которая может выявить аномалии не только по одному измерению, а по всем.

Преобразование и очистка данных

Удаление непоказательных объектов

Выводы:

  1. Аномальные объекты часто удаляются из датасета, чтобы не искажать результаты обучения.
  2. Если можно исправить выброс, можно попытаться это сделать.
  3. Следует анализировать, показателен ли объект для предметной области. Если нет - можно смело удалять.
  4. После удаления множества объектов может понадобиться повторить анализ сбалансированности классов.

Удаление лишних признаков (feature selection)

Выводы:

  1. Выбор признаков - важная часть преобразования данных, ведь чем точнее мы определим необходимую для моделирования информацию, тем эффективнее будет проходить обучение.
  2. Не стоит оставлять в датасете ненужные признаки - это повышает вариативность моделей и может приводить к переобучению.
  3. Для выбора признаком часто используют выводы из EDA, обучение простых моделей (DT, RF) или здравый смысл.
  4. Выбор признаков можно автоматизировать - применять алгоритм очередного удаления или добавления признаков.
  5. Выбор признаков менее актуален, если обучаются нейронные сети, они способны сами отбирать признаки.
  6. Регуляризация обычно работает лучше отбора признаков.
  7. Совсем лишние данные все равно надо убирать.

Заполнение отсутствующих значений

Самая распространенная проблема в данных, с которой приходится бороться при их подготовке к машинному обучению - отсутствующие значения или пропуски в данных. Пропуски могут возникать по самым разным причинам. Часто просто нет информации о значении данной характеристики у данного объекта - это точечные пропуски. Часто пропуски возникают вследствие программной ошибки или потере данных. Причиной пропусков может стать и человеческий фактор, ведь иногда данных заполняются, перепечатываются или переносятся вручную. Мы видели, что пропуски также могут возникать и в процессе интеграции данных из разных источников.

Пропуски в данных - это прямое нарушение требований чистоты данных. Что же с ними делать? Есть много путей решения этой проблемы и в этой главе мы как раз поговорим о том, как их применять и как выбрать наилучший в каждой конкретной ситуации.

Помните, что пропуски нужно исправлять во всех частях датасета - и в обучающем и в тестовом наборе. Вообще, это, как и другие действия с данными, которые описываются в этой главе, нужно делать на общем датасете. Разделение выборки на обучающую, тестовую и валидационную, применение кросс-валидации происходит непосредственно перед или уже во время машинного обучения

В любом случае, для использования данных как обучающей выборки, в них не должно быть отсутствующих значений. Не зря одно из условий чистоты данных - отсутствие пропусков. Поэтому с этим артефактом данных надо бороться. Существует несколько применяемых на практике способов исправления пропущенных значений. Среди них нет одного, самого лучшего во всех ситуациях. Для выбора метода борьбы с пропусками необходимо знать, сколько их, где и как они расположены в датасете.

Для начала следует обнаружить пропуски в данных, либо убедиться, что таковых нет. Это обязательная часть подготовки данных, которую нужно проводить абсолютно всегда. Чаще всего пропуски в данных существуют просто как отсутствие значения. В pandas для обнаружения таких отсутствующих значений можно применять специальный метод is_na(), который подсчитывает количество пропущенных значений в каждом столбце. Еще существует метод info(), который показывает, наоборот, количество имеющихся данных в каждой колонке датасета:

Некоторые пропуски не отображаются так просто при автоматизированном анализе. Иногда они “зашифрованы” в данных через какие-то специальные значения. Например часто встречаются значения “N/A” (Not available), “-“ (прочерк), все варианты слов “нет” и “неизвестно” на разных языках, а также строки, обозначающие отсутствие значения в разных языках программирования: “None”, “Null”, “undefined” и так далее. Поэтому важно проверять имеющиеся значения каждого атрибута в датасете. Часто такие специальные значения обнаруживаются только при построении гистограмм, когда становится понятно по смыслу, что в данных, оказывается, есть пропущенные значения. В особо коварных случаях пропуски могут обозначаться просто численным нулем. Это обнаружить сложнее всего.

как выглядят пропуски Источник: Data Analytics.

Визуально оценить распределение пропущенных значений можно с помощью тепловой карты, которую можно построить, например так:

1
sns.heatmap(training_set.isnull(), yticklabels=False, cbar=False, cmap='viridis')

Этот график покажет не только, в каких столбцах больше всего пропусков, но и то, как они располагаются по строкам:

Эта информация очень важна для выбора способа исправления этих отсутствующих значений. Напомним, что в итоге, после очистки данных ни одного пропуска в них не должно остаться. Значит с каждым их них нужно что-то сделать. На графике выше мы видим, что большинство пропущенных значений расположено в одном столбце. В таком случае нужно задуматься, так ли он нужен для моделирования. В данном примере в этом столбце неизвестна большая часть значений, даже больше, чем заполненных. Надо полагать, что такой признак не будет очень эффективен для предсказания целевой переменной. Поэтому можно удалить весь этот столбец.

В других случая часто бывает так, что много пропусков, наоборот у какого-то одного объекта. Или в датасете присутствует несколько объектов, про которых известно меньше, чем про остальные. В таком случае, можно предложить удалить такие объекты как непоказательные. Опять же, как и в первом случае, при принятии решения об удалении данных их датасета всегда следует исходить их контекста задачи. Но объект, про которого практически ничего не известно вряд ли будет ценным обучающим примером.

Удаление строк и столбцов с отсутствующими значениями, конечно, самый простой способ борьбы с пропусками данных. Но его нельзя применять механически. Часто бывает, что если удалить из датасета все проблемные строки и столбцы, в нем вообще мало что останется. На практике встречались случаи, когда обучающая выборка сокращалась после удаления пропусков в сотни раз. Это очень неэффективно. Но если не удалять пропуски, их нужно чем-то заполнять.

Самый простой способ, который чаще всего применяется на практике - заполнение средним значением. Логично рассуждать, что раз мы не знаем значение признака в данной точке, то предположим, что его значение не сильно отклоняется от среднего значения. Это среднее рассчитывается по всем объектам, для которых известно (то есть заполнено) значение данного признака.

У этого простого метода есть только один недостаток: он сильно изменяет форму распределения данного признака. Для примера приведем гистограмму того же признака “возраст”, что и в предыдущей главе. Как можно видеть на одном из предыдущих рисунков, более 150 из почти 900 значений возраста не заполнены. Здесь мы все отсутствующие значения заполнили средним:

Очевидно, как сильно исказилось распределение теперь мы наблюдаем совершенно искусственный огромный пик на значении около 30 лет. Это и есть тот самый средний возраст. Теперь распределение очень далеко от нормального. Такая ситуация плохо скажется на эффективности модели, так как теперь она будет полагаться на тот факт, что почти все пассажиры одного возраста. А в реальности это не так.

Получается, что заполнение средним может использоваться только если пропусков в данном столбце очень мало. А что делать, если их достаточно много, чтобы заполнение средним уже было вредным, но не настолько много, чтобы удалять весь столбец? Можно заполнить случайным значением. Кажется, что это не имеет смысла, но на самом деле случайно значение также не несет никакой информации, как и пропущенное. Но в отличие от заполнения средним оно не приведет к появлению искажений распределения. Особенно если генерировать это случайное значение из распределения, близкого к имеющихся в данных значениям. Например, если на предыдущем этапе анализа данных мы пришли к выводу, что признак распределен примерно нормально, то и генерировать случайные значения для заполнения пропусков можно их нормального распределения с выборочным средним и дисперсией. Если же признак распределен равномерно - то из равномерного распределения с известными минимумом и максимумом.

Еще один прием, который применяется на практике - заполнение групповым средним. Делов том, что среди объектов обучающей выборки можно выделить определенные группы (по значениям других признаков), в которых можно посчитать средние значения данного признака для заполнения. Например, в том же датасете “Титаник” в имени пассажира есть так называемая именная форма, вежливое обращение. Его можно использовать для заполнения возраста. Если пассажир, у которого неизвестен возраст, именуется “Миссис”, мы заполняем это значение не средним возрастом всех пассажиров, а средним возрастом всех Миссис. И для других категорий: возраст “Мистеров” заполняем средним для “Мистеров”, также для “Мисс”, “Мастеров” (в викторианские времена так обращались к маленьким детям). Этот способ даже точнее “угадывает” пропущенное, так как это вежливое обращение коррелирует с возрастом. И чем больше взаимосвязь между признаком группировки и признаком, который ма заполняем, тем лучше. Этот способ также частично решает проблему искусственного пика. Один огромный пик на гистограмме по сути заменяется несколькими пиками поменьше, соответствующим групповым средним.

При заполнении пропусков в категориальных переменных можно воспользоваться простым, но действенным приемом - использованием специального значения, которое обозначает “отсутствие значения”. Этот, казалось бы примитивный способ, является самым грамотным решением с точки зрения теории информации. Он не привносит никакой новой информации в данные, никак не искажает имеющиеся распределения. Он лишь сообщает модели, что имеется особый класс объектов. К сожалению этот способ не подходит для численных признаков, потому что какое бы специальное значение мы бы не выбрали, оно всегда будет находиться в отношении порядка с другими значениями. Поэтому численные признаки всегда надо заполнять каким-то числом, которое максимально близко к возможному истинному значению данной характеристики объекта.

Выводы:

  1. При выборе стратегии борьбы с пропусками в данных следует проанализировать, сколько пропусков и где они расположены.
  2. Пропуски могут “маскироваться”, их нужно обнаруживать анализируя данные, в том числе вручную.
  3. Если по одному из признаков большинство значений пропущено, можно задуматься об удалении этого признака из датасета.
  4. Если наоборот, по одному объекту много неизвестных атрибутов, можно удалить объект.
  5. Следует следить, чтобы от датасета что-то осталось после массового удаления.
  6. Самый простой способ заполнить пропуски - заполнить их средним значением, но это сильно искажает форму распределения признака.
  7. Зачастую можно считать групповое среднее, более “индивидуальную” оценку атрибута данного объекта, с учетом значений других атрибутов.
  8. Иногда применяют заполнение случайным значением. Его лучше всего генерировать из распределения данного признака.
  9. Самое корректное решение по категориальным признакам - заполнение специальным значением.

Преобразование численных атрибутов в категориальные

Довольно часто исследователи проводят анализ количества объектов в обучающем наборе данных, удовлетворяющим каким-либо условиям, вытекающим из описания предметной области, например, попадающим в определенный промежуток значений, обладающих уникальным набором характеристик, соответствующих конкретным значениям количественной характеристики (чаще всего, 0 или 1). Такой анализ позволяет выявить и исключить из выборки нерелевантные объекты.

Основные задачи:

Выводы:

  1. Иногда бывает целесообразно сгруппировать объекты датасета по значению какого-то признака и заменить его названием группы.
  2. В таком случае, мы удаляет часть информации из модели, но это может быть лишняя вариативность.
  3. Показательный пример - группы населения по возрасту.
  4. Такое нужно делать, только если есть уверенность, что объекты внутри группы одинаково относятся к целевой переменной.
  5. Границы групп выбирают вручную, от этого многое зависит.

Преобразование категориальных атрибутов

Еще одно требование к чистоте данных, которое обязательно должно быть удовлетворено для использования датасета для машинного обучения - все признаки должны быть выражены в численном виде. В реальности же достаточно часто встречаются категориальные атрибуты. Они могут быть выражены как угодно, но чаще всего - текстом, то есть строкой, которая характеризует название класса, конкретное значение признака. Такие атрибуты не могут быть использованы во многих моделях, так как эти самые модели совершают арифметические операции над признаками. Поэтому такие признаки обязательно надо преобразовывать в численный вид. Есть несколько способов такого преобразования и в каждом случае нужно использовать наиболее подходящий.

Кроме категориальных признаков преобразованию в численный вид подлежат все другие типы данных. В машинном обучении часто идет речь об анализе графической информации, текстов на естественных языках, видео, звукового потока. Все это в конечном итоге представляется в виде численных векторов. Эта операция называется векторизация. Здесь мы подробно про нее не будет говорить, потому что это очень обширная тема. Здесь мы сконцентрируемся на анализе табличных данных. Тем более, что такое представление информации чаще других встречается в экономических и технических приложениях.

Существует два принципиально разных подхода к кодированию категориальных признаков в численные. Первый более прост - он заключается в том, что разным значениям категориального признака ставятся в соответствие разные числа. По сути, мы просто пронумеровываем значения и заменяем его номером. В библиотеке sklearn такое преобразование называется LabelEncoder. Этот метод читает датасет построчно и присваивает первому встреченному значению данного признака номер 0, второму - 1 и так далее:

id quality price
1 good 100
2 excellent 150
3 good 110
4 poor 30
5 poor 23
6 satisfactory 62
7 excellent 130
8 good 95
9 good 90
id quality price
1 0 100
2 1 150
3 0 110
4 2 30
5 2 23
6 3 62
7 1 130
8 0 95
9 0 90

Но этим способом надо пользоваться аккуратнее. Дело в том, что такое изменение шкалы измерения признака вносит в него новую информацию - порядок значений. Как мы говорили, в номинальных шкалах отношения порядка не существует, есть только равенство или неравенство. Поэтому когда мы преобразуем, например, названия производителей телефонов в числа, у нас получается, что одни производители как бы “больше” других. Эта новая информация может существенно исказить результаты моделирования, так как численные модели работают с арифметическими операциями и полагаются на упорядоченность числовых значений.

Но в ординальных шкалах присутствует естественный порядок. Получается, что признаки, выраженные по порядковой шкале можно преобразовывать таким образом? Вообще да, но здесь есть нюанс. Дело в том, что в автоматическом режиме LabelEncoder расставляет номера в порядке упоминания значений в датасете. Обратите внимание в примере выше, что значению “excellent” соответствует 1, “good” - 0 а “poor” - 2. Это не соответствует тому самому естественному порядку, который присутствует в значениях данного атрибута. Преобразование нужно делать именно в нужном порядке, например так:

id quality price
1 good 100
2 excellent 150
3 good 110
4 poor 30
5 poor 23
6 satisfactory 62
7 excellent 130
8 good 95
9 good 90
id quality price
1 2 100
2 3 150
3 2 110
4 0 30
5 0 23
6 1 62
7 3 130
8 2 95
9 2 90

Или наоборот, в обратном порядке, это не имеет значения. Важно лишь то, что порядок численных значений должен соответствовать смыслу этих значений, а не порядку появления в датасете. К сожалению, это означает, что такое преобразование скорее всего придется делать руками, с помощью такого метода как replace(), что может быть неудобно, если в атрибуте очень много значений.

Самый простой случай - бинарная шкала. Вот ее можно преобразовывать и автоматически, потому как для двух значений их порядок обычно не очень осмыслен. Самый типичный пример - пол. Как бы он не был обозначен в исходных данных, его можно обозначать 0 или 1 (причем неважно, какой пол обозначать 0, а какой - 1):

id gender
1 male
2 male
3 female
4 male
5 female
6 female
7 female
8 male
9 male
id gender
1 0
2 0
3 1
4 0
5 1
6 1
7 1
8 0
9 0

А что делать с категориальными атрибутами с номинальной шкалой? Такие тоже очень часто встречаются. С ними сложнее, ведь их вообще нельзя просто заменить на какие-то числа, это неизбежно привнесет несвойственный данным порядок в значения. Рассмотрим для примера один из атрибутов в датасете “Титаник” - порт отправки. Пассажиры Титаника садились на борт в одном из трех городов, что и записано в данном признаке

PassengerId Embarked
1 S
2 C
3 S
4 S
5 S
6 Q
7 S
8 S
9 S
10 C

Для преобразования подобных данных используется другой метод кодировки - в sklearn он называется OneHotEncoder. В датасете вместо одного столбца данного признака создается по одному на каждое его значение. И для конкретного объекта в столбце, соответствующем значению атрибута для этого объекта ставится 0, а в остальных - 1. Вот как это выглядит:

PassengerId Embarked_S Embarked_C Embarked_Q
1 1 0 0
2 0 1 0
3 1 0 0
4 1 0 0
5 1 0 0
6 0 0 1
7 1 0 0
8 1 0 0
9 1 0 0
10 0 1 0

Получается, что атрибут разбивается сразу на несколько бинарных признаков. Причем только в одном из них может стоять 1, а в остальных будут нули. Именно поэтому такой способ кодирования называется “One hot”. Такие новые суррогатные признаки еще называются “dummy”, то есть глупые признаки. В pandas есть специальный метод, который позволяет автоматически кодировать все текстовые столбцы датафрейма - get_dummies().

Надо только помнить, что не всегда численный тип переменной означает численный тип шкалы данного признака. Поэтому get_dummies() надо использовать с осторожностью и всегда проверять, правильно ли произошло преобразование. Да, в 90% случаев категориальные признаки выражаются строками, а численные - числами. Но именно за счет оставшихся 10% возникают ошибки и потери в эффективности моделей. Помните, что вдумчивый анализ и преобразование данных более результативно, чем крутые сложные модели.

Метод OneHotEncoder является универсальным. Так можно преобразовывать любые категориальные переменные. Даже порядковые или бинарные. Но для этих типов шкал такое преобразование просто излишне. Например, вот как преобразовывается бинарная переменная методом OneHotEncoder:

id gender
1 male
2 male
3 female
4 male
5 female
6 female
7 female
8 male
9 male
id gender_male gender_female
1 1 0
2 1 0
3 0 1
4 1 0
5 0 1
6 0 1
7 0 1
8 1 0
9 1 0

Очевидно, что последний столбец является просто инверсией предыдущего. То есть по значению одного столбца однозначно можно вычислить значение другого. Это означает, что эти столбцы полностью коррелируют друг с другом (коэффициент будет равен 1). А значит, как мы говорили в предыдущей главе, один из них можно удалить. Причем в таком случае абсолютной связи убрать можно и даже нужно абсолютно любой из них, потому что один столбец уже несет полную информацию о значении признака. А оставляя один из этих двух столбцов - это практически то же самое, что поименовать значения этого бинарного признака числами.

Вообще, при использовании OneHotEncoder неизбежно возникает некоторое дублирование данных. Как в нашем примере с портами отплытия Титаника - по любым двум столбцам можно однозначно вычислить третий. Это значит, что любой из этих трех столбцов можно безболезненно удалить. Но на практике это обычно не делают, так как наличие этого столбца никак не вредит модели.

Использование OneHotEncoder имеет один очевидный существенный недостаток - после него количество столбцов в датасете может многократно вырасти. Особенно это проявляется, если в данных есть признаки с очень большим количеством значений. Почему это может быть проблемой? Во-первых, сложность анализа и визуализации данных. Поэтому большую часть предварительного анализа предпочитают делать до такого преобразования. Во-вторых, большое количество малозначащих признаков может привести к переобучению модели. Но с этой проблемой мы знаем как бороться - используя регуляризацию, отбор признаков и другие техники, которые мы обсуждали в предыдущей главе.

Но все равно, неконтролируемый рост количества признаков надо стремиться ограничить. Помогает опять же вдумчивый анализ тех атрибутов, которые порождают большое количество признаков. Возможно некоторые значения можно объединить, то есть провести группировку по данному атрибуту. Особенно это целесообразно в том случае, когда распределение значений очень неравномерно и на маленькую часть объектов приходится огромное количество вариантов значений. Тогда можно их объединить в одно значение “Другое”. Это очень распространенный прием обработки данных.

Выводы:

  1. Категориальные признаки часто выражаются строковыми данными и не подходят для использования в машинном обучении, их преобразуют в численные.
  2. Самый простой кодировщик - LabelEncoder - просто нумерует все значения категориального признака.
  3. Он вводит порядок в значения категорий, которого раньше не было, поэтому можно исказить результаты обучения.
  4. Исключение - бинарные признаки, их можно кодировать как 0 и 1.
  5. Более продвинутый кодировщик - OneHotEncoder - преобразует один признак во множество.
  6. Новые признаки соответствуют значениям исходного и кодируются бинарно. Этот способ более универсален и рекомендуется применять по умолчанию.
  7. В принципе, один из получившихся признаков можно удалить, но это не обязательно.
  8. Да, из одного признака может получиться тысяча.

Создание суррогатных признаков (feature engineering)

Выводы:

  1. Инжиниринг признаков - сложная и творческа работа, но зачастую именно в ней кроется секрет существенного повышения эффективности моделей.
  2. Суррогатные признаки - это как вычислимые поля в базах данных, они создаются на основе уже присутствующих в датасете атрибутов.
  3. При создании новых признаков нужно руководствоваться здравым смыслом и знанием предметной области.
  4. Зачастую новые признаки - это часть существующих, которые потом удаляются.
  5. Например, из фамилии можно получить список родственников, из даты рождения - возраст и так далее.
  6. После введения суррогатных признаков следует повторить EDA, хотя бы частично.

Нормализация и решкалирование признаков

Минимаксная нормализация - это изменение входных данных по следующей формуле:

\[x' = \frac{x - x_{min}}{x_{max} - x_{min}}\]

После преобразования все значения будут лежать в диапазоне $x \in [0; 1]$.

Z-оценки или стандартизация производится по формуле:

\[x' = \frac{x - M[x]}{\sigma_x}\]

В таком случае данный признак приводится к стандартному распределению, то есть такому, у которого среднее 0, а дисперсия - 1.

scaler Источник: TDS.

Выводы:

  1. Нормализация признаков нужна для ускорения обучения и сходимости градиентного спуска.
  2. Во многих реализациях моделей нормализация уже встроена и применяется по умолчанию.
  3. Основная идея нормализации - это сделать так, чтобы все признаки измерялись по одной шкале, то есть лежали в одних пределах.
  4. Обычно для этого выбирают шкалу от 0 до 1. Тогда каждое значение нужно разделить на максимальное.
  5. Еще применяют стандартизацию - приведение к стандартному распределению.
  6. Нормализация - это параметрическое преобразование, нужно запоминать, на что делили или что отнимали.
  7. О отдельных случая применяются более крутые алгоритмы решкалирования с автоматическим устранением выбросов.

Краткий сценарий анализа данных

Выводы:

  1. Интеграция и очистка данных.
  2. Подробное описание каждого признака, шкалы, вида распределения.
  3. Исследование отсутствующих значений, заполнение или удаление.
  4. Описание вида распределения каждого значимого признака и целевой переменной.
  5. Преобразования категориальных признаков в численные.

Подробный сценарий анализа данных

Выводы:

  1. Оценка источников и объемов данных
  2. Анализ репрезентативности и однородности разделения выборки.
  3. Гипотезы о виде распределения каждого признака и выявление аномалий, визуализация.
  4. Выявление и исправление несбалансированности классов.
  5. Корреляционная матрица, выявление мультиколлинеарности, важность признаков.
  6. Отбор признаков, инжиниринг признаков, возможная группировка значений.

Воспроизводимость преобразования данных

Выводы:

  1. Алгоритм, по которому выполнялось преобразование обучающей выборки необходимо сохранить, так как именно такое же преобразование нужно будет проделать над тестовой.
  2. Да, преобразование данных обычно проводят уже после разделения выборки на обучающую и тестовую.
  3. При параметрических преобразованиях все значения параметров подбираются именно по обучающей выборке.
  4. Это может означать, что в тестовой после нормализации признак может быть больше 1 (или меньше 0), это нормально, так и надо.
  5. Если используется преобразование данных, то модель будет работать на преобразованных данных, а из реального мира будут приходить исходные.
  6. Обычно преобразование данных оформляется как функция или (в sklearn) как обучаемая модель.
  7. Преобразование данных используется в составе конвейеров.
  8. В процессе исследования бывает необходимо попробовать разные методы преобразования данных в комбинации с разными моделями обучения.

В данной главе мы рассмотрели только самые критически важные аспекты предварительного анализа и преобразования данных для целей машинного обучения. Анализ данных в широком смысле - это очень обширная дисциплина, основывающаяся на математической статистике. Невозможно в этой книге описать все приемы анализа и обработки данных. Но те методы и приемы, которые мы изучили, являются необходимым минимумом для любого проекта по машинному обучению.

Главное при анализе данных - учитывать специфику предметной области, обращать внимание на малейшие странности, аномалии, несоответствия. Как мы уже говорили не раз, именно качественный анализ данных является самой важной частью работы специалиста по машинному обучению.

Реальные данные всегда содержат ошибки, аномалии, пропуски, и прочие артефакты. Данные могут быть нерелевантны, искажены и просто неверны. Качество данных очень разнится от одного набора данных к другому, от одной задачи к другой. Поэтому не рассчитывайте, что данные будут хорошими и причесанными. Чем хуже качество данных, тем больше усилий и времени придется потратить на их анализ и очистку. И в любом случае, необходимо проверить данные. Даже если они идеальны, в этом надо убедиться, провести все необходимые проверки. Но хорошие качественные данные стоят всех этих усилий, именно качество данных - залог эффективного моделирования.

Предварительный анализ и обработка данных

Предварительный анализ и обработка данных