Комплексное введение в работу с отсутствующими значениями

Исходный узел: 1121996

Эта статья была опубликована в рамках Блогатон по Data Science

Обзор

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

Содержание:

  1. Почему так важно обрабатывать отсутствующие значения?
  2. Причины отсутствия значений
  3. Типы отсутствующих значений
  4. Проверьте наличие отсутствующих значений в наборе данных
  5. Визуализация пропущенных значений
  6. Удаление строк с пропущенными значениями
  7. Удаление столбцов с пропущенными значениями
  8. Вменение для непрерывных переменных
    1. Вменение со средним
    2. Вменение с медианой
  9. Прогнозирование недостающих значений с помощью регрессии
  10. Отсутствующие значения в категориальных данных
  11. Отсутствующие значения в данных временного ряда
    1. Заполнение пропущенных значений вперед
    2. Заполнение пропущенных значений обратной стороной
    3. Линейная интерполяция
  12. Алгоритмы устойчивы к отсутствующим значениям
  13. Заключение

Почему так важно обрабатывать недостающие данные?

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

Причины отсутствующих значений

Вы когда-нибудь задумывались о причинах отсутствия данных в наборах данных?

Некоторые из возможных причин отсутствия данных:

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

Типы недостающих значений

Отсутствие данных может произойти по разным причинам. Мы можем разделить их на три основные группы: полностью отсутствующие случайным образом, отсутствующие случайным образом, отсутствующие случайным образом.

1. Отсутствует совершенно случайно (MCAR)

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

2. Случайно пропавшие без вести (MAR)

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

Например, давайте рассмотрим опрос о времени, проведенном в Интернете, в котором есть раздел о времени, проведенном на таких платформах, как Netflix, amazon prime. Замечено, что пожилые люди (старше 45 лет) реже заполняют его, чем молодые. Это пример MAR. Здесь параметр «Возраст» определяет, будут ли данные отсутствовать или нет. MAR встречается гораздо чаще, чем MCAR.

3. Не пропадают случайно (NMAR)

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

Теперь, когда мы увидели различные типы отсутствующих данных, давайте перейдем к различным способам их обработки.

Проверить отсутствующие значения

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

train = pd.read_csv ('../ input / titanic / train.csv') test = pd.read_csv ('../ input / titanic / test.csv') print ('Форма тренировочных данных:', train.shape ) print ('Тестирование формы данных:', test.shape) train.head ()

Данные о пропущенных значениях

Источник: Изображение из записной книжки автора Kaggle.

Теперь у нас есть обучающие и тестовые кадры титанических данных.

Как проверить, в каких столбцах и сколько отсутствуют данные?

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

недостающие_значения = train.isnull (). sum () print (missing_values)
PassengerId 0 Выжил 0 Pclass 0 Имя 0 Пол 0 Возраст 177 SibSp 0 Parch 0 Билет 0 Стоимость проезда 0 Кабина 687 Посадил 2 dtype: int64

Обратите внимание, что в 3 столбцах отсутствуют значения: Возраст, Кабина, Посадка.

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

mis_value_percent = 100 * train.isnull (). sum () / len (поезд) print (mis_value_percent)
PassengerId 0.000000 Выжил 0.000000 Pclass 0.000000 Имя 0.000000 Пол 0.000000 Возраст 19.865320 SibSp 0.000000 Parch 0.000000 Билет 0.000000 Стоимость проезда 0.000000 Кабина 77.104377 Посадка 0.224467 dtype: float64

Понятно, что отсутствует 77% столбца «Кабина», что является очень значительным процентом. В Age отсутствует около 19% данных, а в Embarked - только 0.2%. Это количественный анализ недостающих данных, которые у нас есть. А как насчет качественного? Продолжай читать!

Визуализация пропущенных значений с помощью Missingno

Угадай, что? У нас есть пакет python, специально предназначенный для визуализации и изучения недостающих данных в наборе данных. Пакет Python «Missingno». Идите и установите его быстро

pip install отсутствует

Используя это, мы можем делать визуализации в виде тепловых карт, гистограмм и матриц. Анализируя их распределение, вы можете сделать вывод, в какую категорию они попадают: MCAR, MAR или NMAR. Мы также можем найти корреляцию столбцов, содержащих недостающие, с целевым столбцом.

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

импорт отсутствует как msno msno.bar (поезд)

отсутствует | недостающие значенияИсточник: Изображение из записной книжки автора Kaggle.

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

msno.matrix (поезд)
панель шаблонов

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

Столбцы age и Cabin могли быть MAR. Но мы хотим, чтобы между ними не было корреляции.

Как это сделать?

К счастью для нас, пакет missingno также предоставляет функцию «тепловая карта». Используя это, мы можем определить, есть ли какие-либо корреляции между отсутствующими данными в разных столбцах.

msno.heatmap (поезд)

Показан результат!

тепловая карта | отсутствующее значение

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

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

Удаление строк с пропущенными значениями

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

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

print ('Dataset before:', len (train)) train.dropna (subset = ['Embarked'], how = 'any', inplace = True) print ('Dataset after:', len (train)) print ( 'пропущенные значения:', поезд ['В пути']. isnull (). sum ())
Набор данных до: 891 Набор данных после: 889 отсутствующих значений: 0

Представьте, если бы вы сделали то же самое для столбца «Возраст». Вы потеряете около 77% своих данных!

Удаление столбцов

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

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

Расчет для непрерывной переменной

train ['Возраст'] [: 10]
0 22.0 1 38.0 2 26.0 3 35.0 4 35.0 5 NaN 6 54.0 7 2.0 8 27.0 9 14.0 Имя: Возраст, dtype: float64
train ['Age'] = train ['Age']. replace (np.NaN, train ['Age']. mean ()) train ['Возраст'] [: 10]
0 22.000000 1 38.000000 2 26.000000 3 35.000000 4 35.000000 5 29.699118 6 54.000000 7 2.000000 8 27.000000 9 14.000000 Имя: Возраст, dtype: float64

Вы можете видеть, что NaN заменено на 29.699 (вычисленное среднее).

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

Вменение с медианой

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

train ['Age'] = train ['Age']. replace (np.NaN, train ['Age']. median ()) train ['Age'] [: 10]

вменение среднего

Вы можете заметить, что среднее значение (28.0) было заполнено вместо значений NaN.

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

Прогнозирование недостающих значений с помощью регрессии

Вместо того, чтобы заполнять одно среднее или медианное значение во всех местах, что, если мы сможем предсказать их с помощью других переменных, которые у нас есть?

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

Мы можем обработать данные для построения модели. Параметр «Возраст» будет целевой переменной.

х_поезд: Строки набора данных, в которых присутствует значение «Возраст», фильтруются. «Возраст» - это цель х_тест: Это столбец «Возраст» с ненулевыми значениями.

Ассоциация у_поезд будут иметь данные, в которых отсутствуют значения возраста, которые должны быть спрогнозированы (y_pred)

импортировать панды как pd data = pd.read_csv ('../ input / titanic / train.csv') data = data [[«Survived», «Pclass», «Sex», «SibSp», «Parch», «Fare» "," Возраст "]] данные [" Пол "] = [1, если x ==" мужской ", иначе 0 для x в данных [" Пол "]] test_data = данные [данные [" Возраст "]. Isnull ()] data.dropna (inplace = True) x_train = data.drop ("Возраст", ось = 1) x_test = test_data.drop ("Возраст", ось = 1) y_train = data ["Возраст"]

Давайте приспособим к этим данным модель линейной регрессии. Я буду использовать здесь библиотеку sklearn.

из sklearn.linear_model import LinearRegression model = LinearRegression () model.fit (X_train, y_train) y_pred = model.predict (X_test)

Теперь у нас есть нулевые значения столбца Age, предсказанные в y_pred.

Я распечатаю несколько примеров тестового ввода и прогнозируемого вывода для вашего лучшего понимания.

печать (x_test [: 10])
Выжившие Pclass Sex SibSp Parch Fare 5 0 3 1 0 0 8.4583 17 1 2 1 0 0 13.0000 19 1 3 0 0 0 7.2250 26 0 3 1 0 0 7.2250 28 1 3 0 0 0 7.8792 29 0 3 1 0 0 7.8958 31 1 1 0 1 0 146.5208 32 1 3 0 0 0 7.7500 36 1 3 1 0 0 7.2292 42 0 3 1 0 0 7.8958

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

печать (y_pred [: 10])
[29.07080066 30.10833306 22.44685065 29.08927347 22.43705181 29.07922599 32.43692984 22.43898701 22.15615704 29.07922599]

Ура! У нас есть ценности.

Отсутствующие значения в категориальных данных

До сих пор мы видели, как работать с недостающими числовыми данными. Что делать, если данные отсутствуют в случае категориального признака? Например, функция «Хижина» в наборе данных Титаника является категориальной. Здесь мы не можем вычислить среднее и медиану. Итак, мы можем заполнить отсутствующие значения режимом или наиболее часто встречающимся классом / категорией.

поезд ['Хижина'] = поезд ['Хижина']. fillna (поезд ['Хижина']. value_counts (). index [0])

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

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

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

поезд ['Хижина'] = поезд ['Хижина']. fillna ('Неизвестно') поезд ['Хижина'] [: 10]

КАБИНА РЯД | заполнить на

Он хорошо работает с небольшим набором данных. Это также сводит на нет потерю данных, добавляя уникальную категорию.

Как обрабатывать отсутствующие значения в данных временных рядов?

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

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

time = pd.date_range ("1", периоды = 01, freq = "W") df = pd.DataFrame (index = time); df ["Продано единиц"] = [2021, np.nan, np.nan, 10, np.nan, 5.0,4.0, np.nan, 1.0]; печать (df)

проданных единиц

Перейдем к методам

Заполнение пропущенных значений вперед

Значение следующей строки будет использовано для заполнения пропущенного значения. «Заполнение» означает «заполнение вперед». Реализовать очень просто. Вам просто нужно передать параметр «method» как «ffill» в функции fillna ().

forward_filled = df.fillna (method = 'ffill') print (forward_filled)

вперед заполненный

Заполнение пропущенных значений обратной стороной

Здесь мы используем значение предыдущей строки, чтобы заполнить отсутствующее значение. «bfill» означает обратное заполнение. Здесь вам нужно передать bfill в качестве параметра метода.

backward_filled = df.fillna (method = 'bfill') print (backward_filled)

задняя часть заполнена

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

Линейная интерполяция

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

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

interpolated = df.interpolate (limit_direction = "both") печать (с интерполяцией)

Линейная интерполяция пропущенных значений

Сравните эти значения с обратной и прямой заливкой и убедитесь сами, что хорошо!

Это несколько основных способов обработки пропущенных значений в данных временных рядов.

Алгоритмы устойчивы к отсутствующим значениям

Бывают случаи, когда ничего из вышеперечисленного не работает. Тем не менее, вам необходимо провести анализ. Затем вам следует выбрать алгоритмы, поддерживающие пропущенные значения. KNN (K ближайших соседей) - один из таких алгоритмов. Он будет учитывать пропущенные значения, выбирая большинство из K ближайших значений. Случайный лес также устойчив к категориальным данным с пропущенными значениями. Многие алгоритмы на основе дерева решений, такие как XGBoost, Catboost, поддерживают данные с пропущенными значениями.

Заключение

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

Надеюсь, вам понравилось чтение.

Вы можете связаться со мной по адресу: [электронная почта защищена]

LinkedIn: предварительная обработка данных

Медиа, показанные в этой статье, не принадлежат Analytics Vidhya и используются по усмотрению автора.

Источник: https://www.analyticsvidhya.com/blog/2021/10/end-to-end-introduction-to-handling-missing-values/

Отметка времени:

Больше от Аналитика Видхья