如何使用库克距离识别有影响力的数据点
库克距离(通常表示为Di)在回归分析中用于识别可能对回归模型产生负面影响的有影响力的数据点。
库克距离的公式为:
d i = (r i 2 / p*MSE) * (h ii / (1-h ii ) 2 )
金子:
- r i是第 i个残基
- p是回归模型中的系数数量
- MSE是均方误差
- h ii为第 i个杠杆值
尽管这个公式看起来有点复杂,但好消息是大多数统计软件都可以轻松地为您计算出来。
本质上,库克距离做了一件事:它测量当第 i个数据点被删除时,所有模型的拟合值发生了多少变化。
库克距离值较高的数据点表明它对拟合值影响很大。一般规则是,库克距离大于 4/n(其中 n 是数据点总数)的任何点都被视为异常值。
值得注意的是,库克距离通常用于识别有影响力的数据点。仅仅因为一个数据点有影响力并不一定意味着它应该被删除。您应该首先检查数据点是否只是错误记录,或者数据点是否存在可能表明有趣发现的奇怪情况。
如何计算R中的库克距离
以下示例说明了如何计算 R 中的库克距离。
首先,我们将加载本示例所需的两个库:
library(ggplot2) library(gridExtra)
接下来,我们将定义两个数据框:一个有两个异常值,一个没有异常值。
#create data frame with no outliers no_outliers <- data.frame(x = c(1, 2, 2, 3, 4, 5, 7, 3, 2, 12, 11, 15, 14, 17, 22), y = c(22, 23, 24, 23, 19, 34, 35, 36, 36, 34, 32, 38, 41, 42, 44)) #create data frame with two outliers outliers <- data.frame(x = c(1, 2, 2, 3, 4, 5, 7, 3, 2, 12, 11, 15, 14, 17, 22), y = c( 190 , 23, 24, 23, 19, 34, 35, 36, 36, 34, 32, 38, 41, 42, 180 ))
接下来,我们将创建一个散点图来并排显示两个数据框:
#create scatterplot for data frame with no outliers no_outliers_plot <- ggplot(data = no_outliers, aes(x = x, y = y)) + geom_point() + geom_smooth(method = lm) + ylim(0, 200) + ggtitle("No Outliers") #create scatterplot for data frame with outliers outliers_plot <- ggplot(data = outliers, aes(x = x, y = y)) + geom_point() + geom_smooth(method = lm) + ylim(0, 200) + ggtitle("With Outliers") #plot the two scatterplots side by side gridExtra::grid.arrange(no_outliers_plot, outliers_plot, ncol=2)
我们可以看到异常值如何对第二张图中回归线的拟合产生负面影响。
为了识别第二个数据集中的影响点,我们可以计算数据集中每个观测值的库克距离,然后绘制这些距离以查看哪些观测值高于传统阈值 4/n:
#fit the linear regression model to the dataset with outliers model <- lm(y ~ x, data = outliers) #find Cook's distance for each observation in the dataset cooksD <- cooks.distance(model) # Plot Cook's Distance with a horizontal line at 4/n to see which observations #exceed this threshold n <- nrow(outliers) plot(cooksD, main = "Cooks Distance for Influential Obs") abline(h = 4/n, lty = 2, col = "steelblue") # add cutoff line
我们可以清楚地看到数据集中的第一个和最后一个观察值超过了 4/n 阈值。因此,我们将这两个观察结果确定为对回归模型产生负面影响的有影响力的数据点。
如果我们想删除所有超过 4/n 阈值的观测值,我们可以使用以下代码来实现:
#identify influential points influential_obs <- as.numeric(names(cooksD)[(cooksD > (4/n))]) #define new data frame with influential points removed outliers_removed <- outliers[-influential_obs, ]
然后我们可以比较两个散点图:一个显示存在影响点的回归线,另一个显示删除影响点的回归线:
#create scatterplot with outliers present outliers_present <- ggplot(data = outliers, aes(x = x, y = y)) + geom_point() + geom_smooth(method = lm) + ylim(0, 200) + ggtitle("Outliers Present") #create scatterplot with outliers removed outliers_removed <- ggplot(data = outliers_removed, aes(x = x, y = y)) + geom_point() + geom_smooth(method = lm) + ylim(0, 200) + ggtitle("Outliers Removed") #plot both scatterplots side by side gridExtra::grid.arrange(outliers_present, outliers_removed, ncol = 2)
一旦移除两个有影响的数据点,我们可以清楚地看到回归线对数据的拟合效果如何。
技术说明
- 大多数统计软件都能够轻松计算数据集中每个观测值的库克距离。
- 请记住,库克距离只是一种识别影响点的方法。
- 处理有影响的点的方法有很多,包括:删除这些点,用平均值或中位数等值替换这些点,或者简单地将这些点保留在模型中,但在报告结果回归时仔细记下它们。