Если вы действительно хотите сделать это (удалить самые большие (абсолютные) невязки), то мы можем использовать линейную модель для оценки решения наименьших квадратов и связанных невязок, а затем выбрать среднее значение n% отданные.Вот пример:
Во-первых, сгенерируйте фиктивные данные:
require(MASS) ## for mvrnorm()
set.seed(1)
dat <- mvrnorm(1000, mu = c(4,5), Sigma = matrix(c(1,0.8,1,0.8), ncol = 2))
dat <- data.frame(dat)
names(dat) <- c("X","Y")
plot(dat)
Далее мы подгоняем линейную модель и извлекаем остатки:
res <- resid(mod <- lm(Y ~ X, data = dat))
The *Функция 1011 * может дать нам требуемые квантили остатков.Вы предложили сохранить 90% данных, поэтому мы хотим, чтобы верхний и нижний квантили 0,05:
res.qt <- quantile(res, probs = c(0.05,0.95))
Выберите те наблюдения с остатками в середине 90% данных:
want <- which(res >= res.qt[1] & res <= res.qt[2])
Затем мы можем визуализировать это, используя красные точки, которые мы сохраним:
plot(dat, type = "n")
points(dat[-want,], col = "black", pch = 21, bg = "black", cex = 0.8)
points(dat[want,], col = "red", pch = 21, bg = "red", cex = 0.8)
abline(mod, col = "blue", lwd = 2)
Корреляции для полных данных и выбранного подмножества:
> cor(dat)
X Y
X 1.0000000 0.8935235
Y 0.8935235 1.0000000
> cor(dat[want,])
X Y
X 1.0000000 0.9272109
Y 0.9272109 1.0000000
> cor(dat[-want,])
X Y
X 1.000000 0.739972
Y 0.739972 1.000000
Имейте в виду, что здесь мы могли бы выбрасывать совершенно хорошие данные, потому что мы просто выбираем 5% с наибольшим положительным остатком и 5% с наибольшим отрицательным.Альтернативой является выбор 90% с наименьшими абсолютными остатками:
ares <- abs(res)
absres.qt <- quantile(ares, prob = c(.9))
abswant <- which(ares <= absres.qt)
## plot - virtually the same, but not quite
plot(dat, type = "n")
points(dat[-abswant,], col = "black", pch = 21, bg = "black", cex = 0.8)
points(dat[abswant,], col = "red", pch = 21, bg = "red", cex = 0.8)
abline(mod, col = "blue", lwd = 2)
С этим немного другим подмножеством корреляция немного ниже:
> cor(dat[abswant,])
X Y
X 1.0000000 0.9272032
Y 0.9272032 1.0000000
ДругойДело в том, что даже тогда мы выбрасываем хорошие данные.Возможно, вы захотите посмотреть на расстояние Кука как меру силы выбросов и отбросить только те значения, которые превышают определенное пороговое расстояние Кука. Википедия содержит информацию о расстоянии Кука и предлагаемых порогах.Функцию cooks.distance()
можно использовать для получения значений из mod
:
> head(cooks.distance(mod))
1 2 3 4 5 6
7.738789e-04 6.056810e-04 6.375505e-04 4.338566e-04 1.163721e-05 1.740565e-03
и если вы вычисляете пороговые значения, предложенные в Википедии, и удаляете только те, которые превышают пороговое значение.Для этих данных:
> any(cooks.distance(mod) > 1)
[1] FALSE
> any(cooks.distance(mod) > (4 * nrow(dat)))
[1] FALSE
ни одно из расстояний Кука не превышает предложенных порогов (неудивительно, учитывая то, как я генерировал данные.)
Сказав все это, зачем вамсделать это?Если вы просто пытаетесь избавиться от данных, чтобы улучшить корреляцию или создать значительную связь, это звучит немного странно и немного похоже на то, как данные мне нужны.