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

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

Содержание:

  1. Зачем разделять данные?
  2. Каким должен быть процент разделения?
  3. Разделение в самом начале
  4. Последовательное разделение
  5. Избегайте смещения выборки
  6. Ссылки

Вы можете найти коды, использованные в этой статье, в этом репозитории GitHub:



Если вы хотите бесплатно изучать науку о данных и машинное обучение, ознакомьтесь со следующими ресурсами:

  • Бесплатные интерактивные дорожные карты для самостоятельного изучения науки о данных и машинного обучения. Начните здесь: https://aigents.co/learn/roadmaps/intro
  • Поисковая система для учебных ресурсов Data Science (БЕСПЛАТНО). Добавляйте в закладки свои любимые ресурсы, отмечайте статьи как завершенные и добавляйте учебные заметки. https://aigents.co/learn
  • Хотите изучить науку о данных с нуля при поддержке наставника и учебного сообщества? Присоединяйтесь к этому учебному кружку бесплатно: https://community.aigents.co/spaces/9010170/

Если вы хотите начать карьеру в области науки о данных и искусственного интеллекта, но не знаете, как это сделать. Я предлагаю сеансы наставничества по науке о данных и долгосрочное наставничество по карьере:

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

1. Зачем вам разделять данные?

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

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

2. Каким должен быть процент разделения?

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

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

Тем не менее, есть некоторые общие проценты разделения:

  • Поезд: 80%, Тест: 20%
  • Поезд: 67%, Тест: 33%
  • Поезд: 50%, Тест: 50%
  • Тренировка 90 %, Тест: 10 %
  • Поезд 95%, тест 5%

3. Сплит в самом начале

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

4. Последовательное разделение

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

Теперь давайте определим функцию разделения, чтобы разделить данные на обучающий и тестовый наборы:

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

  • Одним из решений является сохранение набора тестов при первом запуске в отдельном файле, а затем загрузка его при последующих запусках.
  • Другой вариант — установить начальное число генератора случайных чисел (например, np.random.seed(42)) перед вызовом np.random.permutation(), чтобы он всегда генерировал одни и те же перемешанные индексы.

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

Вот возможная реализация:

К сожалению, в нашем наборе данных о жилье нет столбца идентификатора. Самое простое решение — использовать индекс строки в качестве идентификатора:

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

Scikit-Learn предоставляет несколько функций для разделения наборов данных на несколько подмножеств различными способами. Простейшей функцией является train_test_split, которая делает почти то же самое, что и определенная ранее функция split_train_test, но с несколькими дополнительными функциями. Во-первых, есть параметр random_state, который позволяет вам установить начальное число генератора случайных чисел, как объяснялось ранее, а во-вторых, вы можете передать его через несколько наборов данных с одинаковым количеством строк, и он разделит их по одним и тем же индексам (это очень удобно). полезно, например, если у вас есть отдельный DataFrame для меток):

5. Избегайте смещения выборки

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

Давайте рассмотрим исследовательскую компанию, которая решила обзвонить 1000 человек, чтобы задать им несколько вопросов. Они не выбирают 1000 человек случайным образом из телефонной книги. Они стараются сделать так, чтобы эти 1000 человек представляли все население. Например, население США состоит из 51,3% женщин и 48,7% мужчин, поэтому хорошо проведенный опрос в США постарается сохранить это соотношение в выборке: 513 женщин и 487 мужчин. Мы должны попытаться сделать то же самое при разделении нашего набора данных.

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

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

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

Мы видим, что большинство медианных значений дохода сгруппированы от 2 до 5 (т. е. 20 000–50 000 долл. США), но некоторые медианные доходы выходят далеко за пределы 6 (т. е. 60 000 долл. США). Важно иметь достаточное количество экземпляров в вашем наборе данных для каждой страты, иначе оценка важности страты может быть необъективной. Это означает, что у вас не должно быть слишком много слоев, и каждый слой должен быть достаточно большим.

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

Теперь вы готовы к стратифицированной выборке на основе категории дохода. Для этого мы будем использовать класс Scikit-Learn StratifiedShuffleSplit:

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

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

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

Использованная литература:

  1. Практическое машинное обучение с помощью Scikit-Learn, Keras и Tensorflow
  2. Коды, использованные в этой статье, можно найти в этом репозитории GitHub.


Спасибо за чтение! Если вам понравилась статья, не забудьте поставить аплодисменты (до 50!) и связаться со мной в LinkedIn и подписаться на меня в Medium, чтобы быть в курсе моих новых статей.