В предыдущем параграфе мы говорили о форматах хранения данных. Мы выяснили, что иногда в данных могут встречаться пропущенные значения. Они бывают:
- случайные;
- неслучайные;
- восстановимые
- потерянные.
В этом параграфе мы подробно поговорим о том, почему появляются пропущенные значения и как их правильно обрабатывать.
Причины появления пропущенных значений
🔍 Пропущенные значения – незаполненные, «пустые» ячейки в данных.
У вас может возникнуть вопрос, зачем мы обращаем на них внимание? Обрабатывать пропущенные значения важно по нескольким причинам:
- пропущенные значения могут исказить данные;
- если в данных много пропусков, результаты исследования будут казаться ненадежными читателю отчёта, даже если пропуски не искажают данные;
- пакеты с реализациями статистических моделей обычно не умеют обрабатывать пропущенные значения самостоятельно;
- ни один статистический тест не может быть математически вычислен с учётом пропущенных значений.
Как в данных появляются пропуски? Чаще всего — по невнимательности. Например, при обработке результатов опроса можно отвлечься и забыть перенести ответ респондента из бумажной анкеты в электронную таблицу.
Или допустить ошибку в коде, если мы собираем данные с какой-нибудь веб страницы. Допустим, мы собираем данные о судебных процессах в 2021 году. Но мы не учли, что ответчиков может быть несколько — в итоге наш парсер сохранял информацию, только если поле называлось «Ответчик», и пропускал, когда оно называлось «Ответчики».
Но эти проблемы можно решить. Общая логика тут такая: если мы собирали данные самостоятельно и обнаружили пропущенное значение, которое мы можем найти повторно, то можем обратиться к источнику данных ещё раз и восполнить пробел.
Впрочем, иногда значения восстановить невозможно — если в источнике их нет. Например, мы хотим проанализировать мнения пользователей Твиттера о новом телефоне. Нас будет интересовать не только текст поста с хештегом модели телефона, но и местоположение автора. Но не все пользователи указывают собственное местоположение, поэтому в соответствующей колонке у нас будут пропущенные значения. Восстановить их невозможно, поэтому мы потеряли часть данных.
В такой ситуации мы можем разделить пользователей на две отдельные выборки: пользователи с информацией о местоположении и без него.
Случайные и неслучайные пропуски
Условно пропуски делятся на случайные и неслучайные (закономерные). Давайте разберемся подробнее, что это означает.
🔍 Случайные пропущенные значения — не связаны с данными и их возникновение невозможно интерпретировать и проанализировать. Например, при участии в опросе, респондент пропустил вопрос из-за того, что не заметил его в анкете.
🔍 Закономерные пропущенные значения — связаны с особенностями данных. Например, если в опросе респонденты пропускали ответ на чувствительный для него вопрос.
Представим ситуацию: мы опрашиваем людей о том, жертвами каких преступлении они становились (такие опросы называются виктимизационными). Это чувствительная тема, многим респондентам говорить о ней неловко — поэтому если наши вопросы сформулированы неудачно, мы получим много пропусков в ответах.
Заново попросить пройти опрос человека и убедить его ответить практически невозможно. Ответы на вопросы анонимны, вы не знаете, кто конкретно не ответил на вопрос, у вас на руках есть только отдельные характеристики респондента. Нам остается только создать новую категорию «нет ответа» и попробовать заполнить её косвенными способами, о которых мы поговорим ниже.
Общие принципы обработки пропущенных значений
Не существует универсальной инструкции для работы с пропущенными значениями. Правда пропущенные значения — это не всегда проблема для исследователей.
Представьте набор данных из нескольких сот тысяч наблюдений. Если в нём случайно пропущенных значений меньше процента, и они не относятся к цели нашего исследования — можно их просто проигнорировать.
А если пропусков много, или нам важны эти данные, то вы можете обрабатывать одновременно пропущенные значения во всем наборе данных с помощью единственного метода или использовать для каждой переменной собственный метод анализа. Давайте подробнее рассмотрим типы данных, причины возникновения пропущенных значений и возможные способы их обработки.
Источник данных |
Вероятность возникновения пропусков (насколько заполнены данные) |
Причины возникновения пропусков |
Случайные/неслучайные |
Возможность восстановления через дополнительный сбор данных / автоматическая обработка |
Социальные сети / Веб-страницы |
Высокая |
Заполняемость людьми |
Случайные/неслучайные |
Автоматическая/сбор/отсутствие возможности восстановления |
СМИ и журналистика |
Низкая, обычно стандартное наполнение |
Разные годы издания/отличные способы оформления |
Случайные/неслучайные |
Дополнительный сбор / недоступность |
Статистика/опросы |
Высокая |
Заполняемость людьми |
Случайные/неслучайные |
Через автоматическую обработку |
Государственные данные |
Средняя |
Заполненность/отсутствие информации о чем-либо |
Случайные/неслучайные |
Дополнительный сбор / Удаление |
Административные данные |
Средняя |
Заполненность/отсутствие информации о чем-либо |
Неслучайные |
Дополнительный сбор / Удаление |
Известные компании: Google, Яндекс и т. д. |
Низкая |
Нарушение структуры |
Случайные |
Через автоматическую обработку / Удаление |
Как мы уже сказали, универсальной схемы для работы с пропущенными значениями не существует. Но вот примерный алгоритм:
- определить количество пропущенных значений в каждом столбце;
- понять, случайны они или нет;
- оценить возможность их восстановления через дополнительный сбор данных;
- применить один из методов обработки пропущенных значений.
Дальше речь будет идти о методах. Мы расскажем об удалении наблюдений и заполнении наблюдений на основе значений, которые есть в колонке с пропусками. Наконец, немножко поговорим о продвинутых способах заполнения пропущенных значений.
Удаление наблюдений
Удаление строк с пропущенными значениями необходимо производить аккуратно. Делать так можно в двух ситуациях:
- у вас много наблюдений и мало пропусков (нет смысла делать уже хорошие данные ещё лучше);
- вы делаете предварительный анализ, в котором вам не нужно быть совсем уж аккуратным.
Удалять пропущенные значения можно по строкам и по колонкам.
Выше у нас уже был пример с постами пользователей Твиттера, где раздел с информацией о местоположении пользователей был наименее заполненным столбцом, а в колонках с id, именами пользователей, текстом постов нет пропущенных значений. Если нам не важна информация о местоположении, то мы удаляем эту колонку из набора данных. Наоборот, если она важна, то как мы и говорили выше мы можем удалить строки, где она пропущена.
Присвоение пропускам специальной категории
Это довольно простой метод. Представьте, что у вас в данных есть пропуски. Вместо того чтобы оставлять пустое значение, мы можем записать в него специальное число или строку — ту, которую мы выберем сами.
Например, если переменная принимает значение от одного до 5, то -9 — хорошее число, которое мы можем подставить. Так вы можете быть уверенными, что все ячейки в данных заполнены, и у вас нет пропусков.
Замена с учётом других значений в столбце
Использование специальной категории — не единственный способ замены. Мы можем заполнить пропущенные значения, обращая внимание на другие наблюдения.
Например, мы анализируем опрос населения России, где есть вопрос об субъективном благополучии. Мы выявили десять пропущенных наблюдений из 1600. Ответы на вопрос были закодированы 10-ти бальной шкалой (1 – очень плохо, а 10 – очень хорошо).
Мы можем заменить пропущенные значения на среднюю оценку субъективного благополучия по другим наблюдениям. Так мы сможем проанализировать наблюдения, не исключая их. Помимо средней оценки, можно использовать медиану или моду.
Замена пропущенных значений на среднюю оценку, медиану или моду может привести к смещению распределения. Давайте попробуем разобраться почему. Мы использовали для заполнения пропусков предполагаемые ответы на вопрос, а не реальные. Предполагаемые ответы могут сильно расходится с реальными (если бы мы их знали).
Например, у нас есть пропущенное значение в таблице с двумя колонками: опыт работы в компании и заработная плата. В колонке с заработной платой у сотрудника с опытом работы менее одного года пропущено значение.
Опыт работы |
Заработная плата (тыс. рублей) |
Менее года |
Нет ответа |
От 2 до 3 лет |
60 |
От 3 до 4 лет |
80 |
От 4 до 5 лет |
100 |
От 6 и более |
120 |
Если мы заменим средним значением пропущенное значение, то получится, что зарплата для сотрудника с опытом работы менее одного года составляет 90 тысяч рублей. Заработная плата для сотрудника с опытом работы от двух до трех лет получится ниже, чем для сотрудника с опытом работы менее одного года.
Замена на среднее значение, медиану или моду — простой способ обработки пропущенных значений. Замена имеет ограниченную точность и плохо подходит для значений со строковыми переменными (вспомните, какие ограничения есть у моды).
Но есть и другие способы! Высокую точность даёт замена с учетом других столбцов с помощью множественной импутации. Мы расскажем о ней ниже и поймём, как писать код для её реализации, в следующем параграфе.
Множественная импутация данных
Метод, о котором мы поговорим — это многомерная оценка цепными уравнениями (Multivariate Imputation by Chained Equations — MICE).
Объяснение, как этот метод работает, требует знаний статистики, которые выходят за пределы этого учебника. Здесь мы попробуем объяснить его в общих чертах, а в следующем параграфе попрактикуемся его применять. Этот метод прогнозирует пропущенные значения на основе доступных значений переменной, в которой мы заполняем пропуски, и других переменных. Точность повышается, так как алгоритм генерирует несколько прогнозов, которые потом усредняются.
Вспомним пример с заменой пропущенных значений на среднюю оценку. Пропущенная заработная плата для сотрудника с опытом менее одного года после использования метода множественной импутации окажется не 90 тысяч, а 40. Результат окажется более реалистичен, так как модель учтет наличие связи между опытом и заработной платой.
Опыт работы |
Заработная плата |
Менее года |
40000 |
От 2 до 3 лет |
60000 |
От 3 до 4 лет |
80000 |
От 4 до 5 лет |
100000 |
От 6 и более |
120000 |
Множественная импутация работает с числовыми и категориальными типами данных. Она медленнее других методов, так как требует проведения вычислений, но позволяет осуществить более точную замену.
Теперь вы знаете, что делать с пропущенными значениями. В следующем параграфе вы научитесь применять эти знания на практике: мы разберёмся, как проводить в Python удаление, замену на специальную категорию и множественная импутацию.