r - 为什么匹配的结果取决于数据的顺序(MatchIt 包)?
问题描述
当使用 matchit-function 进行完全匹配时,结果因输入数据帧的顺序而异。也就是说,如果数据的顺序发生变化,结果也会发生变化。这是令人惊讶的,因为在我的理解中,最优的完整算法应该只产生一个单一的最佳解决方案。
我错过了什么还是这是一个错误?
最佳算法也会出现类似的差异。
您可以在下面找到一个可重现的示例。两个数据集的子类应该相同,但事实并非如此。谢谢您的帮助!
# create data
nr <- c(1:100)
x1 <- rnorm(100, mean=50, sd=20)
x2 <- c(rep("a", 20),rep("b", 60), rep("c", 20))
x3 <- rnorm(100, mean=230, sd=2)
outcome <- rnorm(100, mean=500, sd=20)
group <- c(rep(0, 50),rep(1, 50))
df <- data.frame(x1=x1, x2=x2, outcome=outcome, group=group, row.names=nr, nr=nr)
df_neworder <- df[order(outcome),] # re-order data.frame
# perform matching
model_oldorder <- matchit(group~x1, data=df, method="full", distance ="logit")
model_neworder <- matchit(group~x1, data=df_neworder, method="full", distance ="logit")
# store matching results
matcheddata_oldorder <- match.data(model_oldorder, distance="pscore")
matcheddata_neworder <- match.data(model_neworder, distance="pscore")
# Results based on original data.frame
head(matcheddata_oldorder[order(nr),], 10)
x1 x2 outcome group nr pscore weights subclass
1 69.773776 a 489.1769 0 1 0.5409943 1.0 27
2 63.949637 a 529.2733 0 2 0.5283582 1.0 32
3 52.217666 a 526.7928 0 3 0.5028106 0.5 17
4 48.936397 a 492.9255 0 4 0.4956569 1.0 9
5 36.501507 a 512.9301 0 5 0.4685876 1.0 16
# Results based on re-ordered data.frame
head(matcheddata_neworder[order(matcheddata_neworder$nr),], 10)
x1 x2 outcome group nr pscore weights subclass
1 69.773776 a 489.1769 0 1 0.5409943 1.0 25
2 63.949637 a 529.2733 0 2 0.5283582 1.0 31
3 52.217666 a 526.7928 0 3 0.5028106 0.5 15
4 48.936397 a 492.9255 0 4 0.4956569 1.0 7
5 36.501507 a 512.9301 0 5 0.4685876 2.0 14
显然,将对象分配给子类是不同的。在我的理解中,情况不应该如此。
解决方案
optmatch 包(matchit 函数调用)的开发人员提供了有用的帮助:
我认为我们在这里看到的是 fullmatch 具有的容差论点的结果。匹配算法需要整数距离,所以我们必须缩放然后截断浮点距离。对于给定的一组整数距离,可能有多个匹配达到最小值,因此求解器可以在这些非唯一解中自由选择。
Developing your example a little more:
> library(optmatch)
> nr <- c(1:100) x1 <- rnorm(100, mean=50, sd=20)
> outcome <- rnorm(100, mean=500, sd=20) group <- c(rep(0, 50),rep(1, 50))
> df_oldorder <- data.frame(x1=x1, outcome=outcome, group=group, row.names=nr, nr=nr) > df_neworder <- df_oldorder[order(outcome),] # > re-order data.frame
> glm_oldorder <- match_on(glm(group~x1, > data=df_oldorder), data = df_oldorder)
> glm_neworder <- > match_on(glm(group~x1, data=df_neworder), data = df_neworder)
> fm_old <- fullmatch(glm_oldorder, data=df_oldorder)
> fm_new <- fullmatch(glm_neworder, data=df_neworder)
> mean(sapply(matched.distances(fm_old, glm_oldorder), mean))
> ## 0.06216174
> mean(sapply(matched.distances(fm_new, glm_neworder), mean))
> ## 0.062058 mean(sapply(matched.distances(fm_old, glm_oldorder), mean)) -
> mean(sapply(matched.distances(fm_new, glm_neworder), mean))
> ## 0.00010373
我们可以看到它小于默认容差 0.001。您始终可以降低容差水平,这可能
需要增加运行时间,以便更接近真正的浮动看跌期权最小值。我们发现 0.001 在实践中似乎效果很好,但这个值并没有什么特别之处。
推荐阅读
- rust - 相互交织的范围如何创建“数据竞赛”?
- angular - Angular 9:LocalStorage 未定义
- angular - Angular 9 <- 如何订阅 Observable 并显示其值
- c - c 进程间通信编译
- python - 如何遍历excel中的每个单元格以检查单元格是否包含日期,然后将日期转换为字符串
- c# - 将物理电话上的 Xamarin.forms 应用程序连接到 Asp.net REST API 时出现 StatusCode 400“错误请求”
- c++ - 类成员的动态分配和值
- excel - Excel 2013 中未定义 Eval
- pointers - 为什么我必须在取消引用之前复制字符串?
- python - 在 qTimeEdit 中找不到 valueChanged