«Выбросы» в данных. Быстрое избавление

Опубликовано Опубликовано в рубрике Рецепты

Допустим, у вас есть данные. Ну, скажем такие:


x <- c(
  4.27296076175273, 4.3253044335640, 4.55202839528403, 
  4.33285651824668, 4.0128340310945, 4.07155452370293, 
  4.04113475664987, 2.7753693269563, 2.49186430883914, 
  2.39823431758359, 2.3789955162936, 2.14825292752989, 
  2.19583315284264, 2.1947104626036, 2.14216783486566, 
  2.28399128121205, 2.3048696257819, 2.23703873535593, 
  2.28669486582313, 2.4163169738317, 2.03782758779637, 
  2.61237703056071, 3.47620332697605
)
y <- c(
  9.097731,9.512591,9.740439,9.910364,9.865059,9.935519,
  9.972640,9.920197,10.367693,10.680861,10.999012,11.246248,
  10.532816,11.144033,11.261961,11.400160,11.080695,11.173922,
  11.506877,11.105483,10.807685,6.489205,4.882802)
)

Которые выглядят вот так:

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


boxplot(y)


Ну точно - две точки выброса!

Теперь самое главное - надо от них избавится в данных и все будет хорошо.
Легко конечно сказать, но если не знать как - очень сложно будет. Более того - на самом деле - теория Outliers Detection весьма глубока и рассматривает огромное количество случаев, но ее применение требует неплохого знания математического и статистического аппарата.
Мы же хотим "по-быстрому давайте удалим эти две точки и все". Ну, как вы помните мы пришли сюда из Экселя в конце концов 🙂

И такой способ "по-быстрому" есть. И основан он на том, что boxplot не только рисует картинку, но и сохраняет все ее параметры в объекте. Из которого мы можем достать их. Например выбросы хранятся тут: boxplot.stats(y)$out

Давайте получим индексы точек выбросов в наших векторах:
ind <- which(y %in% boxplot.stats(y)$out)
Сохраним координаты точек выбросов в отдельном dataframe (вообще не обязательный шаг, можно было обойтись еще парой векторов)
outler <- data.frame(x=x[ind], y=y[ind])
А теперь давайте проверим - те ли вообще точки мы нашли?
plot(x,y,col='blue', pch=20, ylim=c(0,max(y)))
points(outler$x, outler$y, col='red',pch=19)


Хм, как будто все правильно.

Дальше очистим данные от выбросов, проверим, что статистических выбросов не наблюдается и посмотрим на наши новые "чистые" данные.


x <- x[-ind]
y <- y[-ind]
boxplot(y)
plot(x,y,col='blue', pch=20, ylim=c(0,max(y)))

Всё чисто!

«Выбросы» в данных. Быстрое избавление: 1 комментарий

  1. Хороший совет, давно пользуюсь этим способом. Для себя написал функцию, которая проверяет выборку на нормальность несколькими тестами, после чего для нормально распределенных данных использует метод «трех сигм», для всех остальных — метод, описанный в этом посте. На языке R реализуется элементарно, для быстрой очистки от выбросов вполне подходит. Спасибо за интересный блог!

Добавить комментарий