При подготовке данных для машинного обучения вы часто будете сталкиваться с функциями со значениями, которые отделены от остальных, мы называем их выбросами. Такие значения являются проблемой для большинства моделей, поскольку они чувствительны к выбросам. Что ж, алгоритмы регрессии, такие как робастная регрессия, регрессоры XGBoost и некоторые другие, считаются «устойчивыми» к выбросам, но я понял, что это может быть не так, когда у нас довольно много выбросов. Данные из реальной жизни могут быть беспорядочными, и действительно беспорядочными, если на то пошло. Я наткнулся на такие данные, и, очищая и подготавливая их для машинного обучения, я понял, что целевая переменная имеет довольно много выбросов, что заставило меня время от времени исследовать, как это сделать.
Часто при работе с выбросами предлагаются два основных подхода.
- Вмените значения со средним значением или медианой.
- Отбросьте записи или переменные с выбросами.
- Нормализуйте свои данные (реже).
Ни один из вышеупомянутых методов не подходил для устранения выбросов в данных, которые у меня были. Теперь коротко о данных.
Сайт askamanager.org постоянно проводит Опрос о зарплате.
Основной вопрос, заданный в форме, - сколько денег вы зарабатываете, а также несколько дополнительных деталей, таких как отрасль, возраст, годы опыта и т. д. Детали собраны в таблицу Google, из которой я получил данные.
Хотел провести некоторое регрессионное моделирование, чтобы предсказать заработную плату с учетом предикторов, таких как многолетний опыт, пол, уровень образования и другие характеристики. После некоторой проверки я понял, что целевая переменная (annual_salary) имеет очень много выбросов. Думаю, теперь у вас достаточно сведений о деле, которым мы занимаемся, верно? прохладный !
Хватит болтать, а теперь давайте запачкаем руки!
Загрузка библиотек
library(data.table)
А потом данные
Я сделал статью об очистке данных для этих данных, проверьте это здесь. Таким образом, я просто загружу очищенные данные, чтобы мы сразу перешли к делу.
salarydata <- fread("./data/salary_data_cleaned.csv")
Проверка данных
Гистограмма или диаграмма не только помогают показать распределение данных, но и выбросы.
давайте выберем один из них и посмотрим, как распределяется наша целевая переменная.
boxplot(salarydata$annual_salary)
Что ж, надеюсь, теперь вы понимаете, что я имел в виду, говоря о стольких отклонениях, а? Я имею в виду, что их не два, не три, не четыре и даже не десять, так что мы приписываем им среднее значение или среднее значение, если хотите. Помните также, что мы имеем дело с его зарплатой. Нормально иметь заявки с товарищами, зарабатывающими намного выше обычного, и их может быть довольно много, что нормально :)
Теперь давайте немного подумаем о доступных вариантах.
1. Вменение с медианой/средним значением.
— Если бы мы говорили о 3 или 4 значениях, то это может быть компромиссом, но не с таким количеством значений, поскольку это будет дезинформировать алгоритм машинного обучения. Представьте, что куча заявок была от парней из отрасли x, с более чем десятилетним опытом и чьими заработками намного выше нормы, что ж, я думаю, было бы хорошо, если бы машина узнала, что если кто-то из отрасли x, и у них более десяти лет опыта, вы зарабатываете больше. Это может быть не так, если мы уменьшим значения до медианы/среднего значения.
2. Удаление записей с выпадающими значениями.
— Иногда выбросы возникают из-за ошибок измерения или записи, и их отбрасывание может сработать, но не так, как видно из наших данных, что, скорее всего, это не результат ошибки. Следовательно, сбрасывание их не подходит для этого случая, также я думаю, что это приведет к потере информации, которая может быть важна для обучения машины.
3. Нормализация.
— Мое понимание нормализации заключается в том, что она масштабирует значения в диапазоне, скажем, от 0 до 1, что, по сути, означает, что крайние значения по-прежнему будут лежать в пределах 0,9, тогда как другие значения составляют 0,000. И это на самом деле не решает проблему выброса!
И это то, что подводит нас к концепции винсоризации.
Согласно Википедии, этот термин определяется как преобразование статистики путем ограничения экстремальных значений в статистических данных, чтобы уменьшить влияние возможных ложных выбросов, другими словами, мы заменяем экстремальные значения менее экстремальными значениями.
Вот как вы это делаете в R. К счастью, для этого есть библиотека, которая делает нашу работу еще проще!
library(DescTools) # want to use the winsorize function winsorized.data <- salarydata[,.(winsorized.salary = Winsorize(annual_salary))] boxplot(winsorized.data$winsorized.salary)
Ух ты ! это было волшебство да? в любом случае наши данные выглядят намного лучше, по крайней мере, мы можем сказать, что график представляет собой прямоугольную диаграмму :)
Итак, по сути, функция Winsorize заменяет экстремальные значения 95-м значением квантиля наших данных. Что ж, во многом это сокращение, но это намного лучше, чем замена его медианой/средним значением. И наша машина все равно узнает, что ребята из отрасли x с более чем десятилетним опытом, как правило, зарабатывают больше, чем больше, чем на уровне реальных данных.
Использованная литература:
https://cxl.com/blog/outliers/