Как удалить выбросы в Python
Выброс — это наблюдение, которое лежит аномально далеко от других значений в наборе данных. Выбросы могут быть проблематичными, поскольку они могут повлиять на результаты анализа.
В этом руководстве объясняется, как идентифицировать и удалять выбросы в Python.
Как идентифицировать выбросы в Python
Прежде чем вы сможете удалить выбросы, вы должны сначала решить, что вы считаете выбросом. Есть два распространенных способа сделать это:
1. Используйте межквартильный диапазон.
Межквартильный размах (IQR) — это разница между 75-м процентилем (Q3) и 25-м процентилем (Q1) в наборе данных. Он измеряет разброс средних 50% значений.
Вы можете определить наблюдение как выброс, если оно в 1,5 раза превышает межквартильный размах, превышающий третий квартиль (Q3), или в 1,5 раза превышает межквартильный размах, меньше первого квартиля (Q1).
Выбросы = наблюдения > Q3 + 1,5*IQR или Q1 – 1,5*IQR
2. Используйте z-значения.
Z-оценка показывает, сколько стандартных отклонений данного значения от среднего. Мы используем следующую формулу для расчета z-показателя:
z = (X — μ) / σ
- X — это одно необработанное значение данных.
- μ — среднее значение населения
- σ — стандартное отклонение населения
Вы можете определить наблюдение как выброс, если его z-оценка меньше -3 или больше 3.
Выбросы = наблюдения с z-показателями> 3 или
Как удалить выбросы в Python
Как только вы решите, что вы считаете выбросом, вы можете идентифицировать и удалить их из набора данных. Чтобы проиллюстрировать, как это сделать, мы будем использовать следующий кадр данных pandas:
import numpy as np import pandas as pd import scipy.stats as stats #create dataframe with three columns 'A', 'B', 'C' np.random.seed(10) data = pd.DataFrame(np.random.randint(0, 10, size=(100, 3)), columns=['A', 'B', 'C']) #view first 10 rows data[:10] A B C 0 13.315865 7.152790 -15.454003 1 -0.083838 6.213360 -7.200856 2 2.655116 1.085485 0.042914 3 -1.746002 4.330262 12.030374 4 -9.650657 10.282741 2.286301 5 4.451376 -11.366022 1.351369 6 14.845370 -10.798049 -19.777283 7 -17.433723 2.660702 23.849673 8 11.236913 16.726222 0.991492 9 13.979964 -2.712480 6.132042
Затем мы можем определить и удалить выбросы, используя метод z-оценки или метод межквартильного диапазона:
Метод Z-оценки:
#find absolute value of z-score for each observation z = np.abs(stats.zscore(data)) #only keep rows in dataframe with all z-scores less than absolute value of 3 data_clean = data[(z<3).all(axis=1)] #find how many rows are left in the dataframe data_clean.shape (99,3)
Метод межквартильного диапазона:
#find Q1, Q3, and interquartile range for each column Q1 = data.quantile(q=.25) Q3 = data.quantile(q=.75) IQR = data.apply(stats.iqr) #only keep rows in dataframe that have values within 1.5\*IQR of Q1 and Q3 data_clean = data[~((data < (Q1-1.5\*IQR)) | (data >(Q3+1.5\*IQR))).any(axis=1)] #find how many rows are left in the dataframe data_clean.shape (89,3)
Мы можем видеть, что метод z-показателя идентифицировал и удалил одно наблюдение как выброс, в то время как метод межквартильного диапазона идентифицировал и удалил 11 наблюдений как выбросы.
Когда удалять выбросы
Если в ваших данных присутствует один или несколько выбросов, вы должны сначала убедиться, что они не являются результатом ошибки ввода данных. Иногда человек просто вводит неправильное значение данных при записи данных.
Если выброс оказался результатом ошибки ввода данных, вы можете решить присвоить ему новое значение, такое как среднее значение или медиана набора данных.
Если значение является истинным выбросом, вы можете удалить его, если оно окажет значительное влияние на общий анализ. Просто не забудьте упомянуть в своем окончательном отчете или анализе, что вы удалили выброс.
Дополнительные ресурсы
Если вы работаете с несколькими переменными одновременно, вы можете использовать расстояние Махаланобиса для обнаружения выбросов.
Выбросы на датасете
Detecting outliers.
plt.figure(figsize=(18, 2)) plt.boxplot(df[['MEDV']], vert=False) plt.show()
Пытаюсь анализировать "Boston House Price" датасет. Но не могу уточнит: мы можем ли сказать что там есть выбросы?
Отслеживать
25k 4 4 золотых знака 20 20 серебряных знаков 36 36 бронзовых знаков
задан 24 дек 2021 в 19:48
да, мы можем сказать, что есть выбросы. дальше-то что? вам же это надо как-то программно определить, я подозреваю.
24 дек 2021 в 21:52
1 ответ 1
Сортировка: Сброс на вариант по умолчанию

Точки, которые вы видите за пределами концов усов и есть выбросы.
Отслеживать
ответ дан 24 дек 2021 в 21:57
MaxU - stand with Ukraine MaxU - stand with Ukraine
149k 12 12 золотых знаков 59 59 серебряных знаков 132 132 бронзовых знака
- python
- dataframe
- машинное-обучение
- анализ-данных
- scikit-learn
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.11.15.1019
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Обнаружение выбросов с помощью Python
Обнаружение выбросов в машинном обучении с помощью проверки гипотез.
В этой статье я расскажу вам об обнаружении выбросов в машинном обучении. Выбросы – это термин, обычно используемый аналитиками и специалистами по обработке данных, поскольку он требует особого внимания. Если его игнорировать, это может привести к совершенно неверным оценкам.
Проще говоря, обнаружение выброса – это наблюдение, которое выбивается из общей картины в выборке и расходится с ней.
Что такое выброс?
Выброс – это наблюдение, которое численно отличается от остальных данных или, в двух словах, представляет собой значение, выходящее за пределы допустимого диапазона. Давайте рассмотрим конкретный пример, чтобы посмотреть, что происходит с набором данных без выбросов.
Данные без выбросов
Данные с выбросами
1, 2, 3, 3, 4, 5, 400
59.714
150.057
Как видите, набор данных с выбросами имеет существенно отличающееся среднее значение и стандартное отклонение. В первом сценарии мы скажем, что среднее значение составляет 3,14. Но с выбросом среднее значение достигнет 59,71. Это полностью изменило бы оценку.
Возьмем конкретный пример выброса. В компании из 50 сотрудников 45 человек с ежемесячной зарплатой 6,000 рупий, 5 опытных специалистов с ежемесячной зарплатой 100,000 рупий каждый. Если посчитать среднее значение, то среднемесячная зарплата сотрудников компании составляет 14,500 рупий, и это даст нам искривленную общую картину.
Но если взять медиану зарплаты, то это будет 6000 рупий, что гораздо лучше усредненного значения. По этой причине медиана здесь является подходящей мерой для оценки среднего. И вы можете увидеть эффект выброса.
А теперь давайте кратко рассмотрим основные причины выбросов, прежде чем приступить к задаче обнаружения выбросов:
- Ошибки ввода данных: человеческие ошибки, например, ошибки, вызванные во время сбора, записи или ввода данных, могут вызвать выбросы в данных.
- Ошибки измерения: самый частый источник выбросов. Это происходит, когда используемый измерительный прибор оказывается неисправным.
- Естественные выбросы: когда выброс не является искусственным (из-за ошибки), он является естественным. К этой категории относится большинство реальных данных.
Обнаружение выбросов в машинном обучении с помощью проверки гипотез
Теперь я буду использовать язык программирования Python для задачи обнаружения выбросов в машинном обучении.
Выбросы могут быть двух типов: одномерные и многомерные. Выше мы обсуждали пример с одномерным выбросом. Эти выбросы можно найти, когда мы посмотрим на распределение одной переменной. Многомерные выбросы – это выбросы в n-мерном пространстве.
Проверка гипотез – распространенный метод обнаружения выбросов в машинном обучении. Проверка гипотез – это метод проверки утверждения или гипотезы о параметре в совокупности с использованием данных, измеренных в выборке. В этом методе мы проверяем гипотезу, определяя вероятность того, что статистическая величина выборки могла бы быть выбрана, если бы гипотеза относительно параметра общей совокупности была бы верной.
Цель проверки гипотезы – определить вероятность того, что параметр совокупности, такой как среднее значение, вероятно, будет истинным. Проверка гипотез состоит из четырех этапов:
- Формулировка предположения.
- Определение критериев для принятия решения.
- Расчет статистики теста.
- Принятие решения.
Теперь давайте посмотрим, как использовать язык программирования Python для реализации проверки гипотез для задачи обнаружения выбросов в машинном обучении:
import numpy as np import scipy.stats as stats x = np.array([12,13,14,19,21,23]) y = np.array([12,13,14,19,21,23,45]) def grubbs_test(x): n = len(x) mean_x = np.mean(x) sd_x = np.std(x) numerator = max(abs(x-mean_x)) g_calculated = numerator/sd_x print("Grubbs Calculated Value:",g_calculated) t_value = stats.t.ppf(1 - 0.05 / (2 * n), n - 2) g_critical = ((n - 1) * np.sqrt(np.square(t_value))) / (np.sqrt(n) * np.sqrt(n - 2 + np.square(t_value))) print("Grubbs Critical Value:",g_critical) if g_critical > g_calculated: print("From grubbs_test we observe that calculated value is lesser than critical value, Accept null hypothesis and conclude that there is no outliers\n") else: print("From grubbs_test we observe that calculated value is greater than critical value, Reject null hypothesis and conclude that there is an outliers\n") grubbs_test(x) grubbs_test(y)
Результат:
Вычисленное значение Grubbs: 1.4274928542926593
Критическое значение Grubbs: 1.887145117792422
Из grubbs_test мы видим, что вычисленное значение меньше критического значения, принимаем нулевую гипотезу и делаем вывод об отсутствии выбросов
Вычисленное значение Grubbs: 2.2765147221587774
Критическое значение Grubbs: 2,019968507680656
Из grubbs_test мы видим, что вычисленное значение больше критического значения, отклоняем нулевую гипотезу и делаем вывод, что есть выбросы
Одна из основных проблем машинного обучения – выбросы. Если вы не будете учитывать выбросы в данных, это приведет к снижению производительности вашей модели машинного обучения.
Надеюсь, вам понравилась эта статья о задаче обнаружения выбросов в машинном обучении с использованием проверки гипотез и языка программирования Python.
Обнаружение статистических выбросов в Python
Параллельно с выходом материала «Обнаружение выбросов в R» предлагаем посмотреть, как те же методы обнаружения выбросов реализовать в Python.
Данные
Для наглядности эксперимента возьмём тот же пакет данных mpg — скачать его в виде csv-таблицы можно с GitHub. Импортируем библиотеки и читаем таблицу в DataFrame:
import pandas as pd import matplotlib.pyplot as plt import numpy as np df = pd.read_csv('mpg.csv')
Минимальные и максимальные значения
Тут всё просто. Выводим описание всего датасета методом describe():
df.describe()

Гистограмма
Такой график тоже можно построить в одну строку, используя внутренние средства библиотеки pandas:
df.hwy.plot(kind='hist', density=1, bins=20, stacked=False, alpha=.5, color='grey')

Box plot
В случае ящика с усами далеко идти тоже не приходится — в pandas есть метод и для этого:
_, bp = df.hwy.plot.box(return_type='both')

Получим точки с графика и выведем их в таблице, используя объект bp:
outliers = [flier.get_ydata() for flier in bp["fliers"]][0] df[df.hwy.isin(outliers)]

Процентили
При помощи метода quantile получаем соответствующую нижнюю и верхнюю границы, а затем выводим всё, что выходит за их рамки:
lower_bound = df.hwy.quantile(q=0.025) upper_bound = df.hwy.quantile(q=0.975) df[(df.hwy < lower_bound) | (df.hwy >upper_bound)]

Фильтр Хэмпеля
Мы используем реализацию фильтра Хэмпеля, найденную на StackOverflow
Опишем функцию, которая заменяет на nan все значения, у которых разница с медианой больше, чем три медианных абсолютных отклонения.
def hampel(vals_orig): vals = vals_orig.copy() difference = np.abs(vals.median()-vals) median_abs_deviation = difference.median() threshold = 3 * median_abs_deviation outlier_idx = difference > threshold vals[outlier_idx] = np.nan return(vals)
И применим к нашему набору данных:
hampel(df.hwy) 0 29.0 1 29.0 2 31.0 3 30.0 4 26.0 . 229 28.0 230 29.0 231 26.0 232 26.0 233 26.0 Name: hwy, Length: 234, dtype: float64
В выводе нет nan-значений, а значит и выбросов фильтр Хэмпеля не обнаружил.
Тест Граббса
Автор реализации теста Граббса и теста Рознера для Python
Опишем три функции: первая находит значение критерия Граббса и максимальное значение в наборе данных, вторая — критическое значение с учётом объёма выборки и уровня значимости, а третья проверяет, является ли значение с максимальным индексом выбросом:
import numpy as np from scipy import stats def grubbs_stat(y): std_dev = np.std(y) avg_y = np.mean(y) abs_val_minus_avg = abs(y - avg_y) max_of_deviations = max(abs_val_minus_avg) max_ind = np.argmax(abs_val_minus_avg) Gcal = max_of_deviations / std_dev print(f"Grubbs Statistics Value: ") return Gcal, max_ind def calculate_critical_value(size, alpha): t_dist = stats.t.ppf(1 - alpha / (2 * size), size - 2) numerator = (size - 1) * np.sqrt(np.square(t_dist)) denominator = np.sqrt(size) * np.sqrt(size - 2 + np.square(t_dist)) critical_value = numerator / denominator print(f"Grubbs Critical Value: ") return critical_value def check_G_values(Gs, Gc, inp, max_index): if Gs > Gc: print(f" is an outlier") else: print(f" is not an outlier")
Заменим значение в 34 строке на 212:
df.hwy[34] = 212
И выполним три функции:
Gcritical = calculate_critical_value(len(df.hwy), 0.05) Gstat, max_index = grubbs_stat(df.hwy) check_G_values(Gstat, Gcritical, df.hwy, max_index) Grubbs Critical Value: 3.652090929984981 Grubbs Statistics Value: 13.745808761040397 212 is an outlier
Тест Рознера
Для теста Рознера достаточно дописать одну функцию, которая принимает набор данных, уровень значимости и число потенциальных выбросов:
def ESD_test(input_series, alpha, max_outliers): for iteration in range(max_outliers): Gcritical = calculate_critical_value(len(input_series), alpha) Gstat, max_index = grubbs_stat(input_series) check_G_values(Gstat, Gcritical, input_series, max_index) input_series = np.delete(input_series, max_index)
Используя функцию на нашем наборе данных получаем, что значение 212 является выбросом, а 44 — нет:
ESD_test(np.array(df.hwy), 0.05, 3) Grubbs Critical Value: 3.652090929984981 Grubbs Statistics Value: 13.745808761040408 212 is an outlier Grubbs Critical Value: 3.6508358337727187 Grubbs Statistics Value: 3.455960616168714 44 is not an outlier Grubbs Critical Value: 3.649574509044683 Grubbs Statistics Value: 3.5561478280392245 44 is not an outlier
