在R语言中根据厨师距离去除异常值

机器算法验证 r 回归 异常值 厨师距离
2022-02-08 15:24:46

我有这个用于线性回归的 R 代码:

fit <- lm(target ~ age+sales+income, data = new)

如何根据厨师的距离识别有影响的观察并从 R 中的数据中删除相同的观察?

1个回答

这篇文章在 2 年内有大约 6000 次浏览,所以我想一个答案是非常需要的。虽然我从参考资料中借鉴了很多想法,但我还是做了一些修改。我们将使用 中的cars数据base r

library(tidyverse)

# Inject outliers into data.
cars1 <- cars[1:30, ]  # original data
cars_outliers <- data.frame(speed=c(1,19), dist=c(198,199))  # introduce outliers.
cars2 <- rbind(cars1, cars_outliers)  # data with outliers.

让我们用异常值绘制数据,看看它们有多极端。

# Plot of data with outliers.

plot1 <- ggplot(data = cars1, aes(x = speed, y = dist)) +
        geom_point() + 
        geom_smooth(method = lm) +
        xlim(0, 20) + ylim(0, 220) + 
        ggtitle("No Outliers")
plot2 <- ggplot(data = cars2, aes(x = speed, y = dist)) +
        geom_point() + 
        geom_smooth(method = lm) +
        xlim(0, 20) + ylim(0, 220) + 
        ggtitle("With Outliers")

gridExtra::grid.arrange(plot1, plot2, ncol=2)

比较1

我们可以看到引入异常值后回归线拟合不佳。因此,让我们用库克的距离来识别它们。我正在使用传统的截止4n. 请注意,截止值只是帮助您思考数据有什么问题

mod <- lm(dist ~ speed, data = cars2)
cooksd <- cooks.distance(mod)

# Plot the Cook's Distance using the traditional 4/n criterion
sample_size <- nrow(cars2)
plot(cooksd, pch="*", cex=2, main="Influential Obs by Cooks distance")  # plot cook's distance
abline(h = 4/sample_size, col="red")  # add cutoff line
text(x=1:length(cooksd)+1, y=cooksd, labels=ifelse(cooksd>4/sample_size, names(cooksd),""), col="red")  # add labels

库克距离图

如参考中所述,有许多方法可以处理异常值。现在,我只想简单地删除它们。

# Removing Outliers
# influential row numbers
influential <- as.numeric(names(cooksd)[(cooksd > (4/sample_size))])

# Alternatively, you can try to remove the top x outliers to have a look
# top_x_outlier <- 2
# influential <- as.numeric(names(sort(cooksd, decreasing = TRUE)[1:top_x_outlier]))

cars2_screen <- cars2[-influential, ]

plot3 <- ggplot(data = cars2, aes(x = speed, y = dist)) +
        geom_point() + 
        geom_smooth(method = lm) +
        xlim(0, 20) + ylim(0, 220) + 
        ggtitle("Before")
plot4 <- ggplot(data = cars2_screen, aes(x = speed, y = dist)) +
        geom_point() + 
        geom_smooth(method = lm) +
        xlim(0, 20) + ylim(0, 220) + 
        ggtitle("After")

gridExtra::grid.arrange(plot3, plot4, ncol=2)

前后对比

万岁,我们已经成功去除了异常值~

优秀参考:异常值处理