1

假设我有一个N个人样本和一个随机变量X,代表他们的外币年收入。的一个例子X可能如下:

15000
11000
9000
4000
4000
3900
3800
3600
3400
1000
900
800
700
700
400
300
300
300
200
100

现在我应该“采样” 3个“有序”子组中的20组件X(不需要相同数量的组件),以便它们(大约)具有相同的基尼系数。

提醒一下基尼系数:只需计算每个收入占总收入的百分比(例如p1=1500/(1500+1100+...), p2=1100/(1500+1100+...), ..., p20=100/(1500+1100+...)),然后是累积百分比值(例如c1=0+p1, c2=p1+p2, ..., c20=p19+p20=1),然后计算下面的面积累积 ( A=(c1+...+c20-0.5)/(20)-0.5) ,因此是基尼系数G=2*A

这可以通过蛮力轻松完成:将样本一分为三,计算三个样本的基尼系数,并尝试从/移到中间样本的上下分量,以确定基尼系数的差异是改善还是恶化。但是,手动完成非常耗时(例如在 Excel 上),尤其是当我有一个非常大的数据集时。

我怀疑有一个更优雅的解决方案。我对Python和都持开放态度R

附加细节 输出将是这样的:X

        1         2         3 
     1500      3900       400
     1100      3800       300
     9000      3600       300
     4000      3400       300
               1000       200
                900       100
                800
                700
                700

对于G, 三个子组的实际基尼系数

        1         2         3 
      0.4      0.41      0.39 
4

2 回答 2

1

好的,这是 R 中的一种方法,它至少可以自动执行蛮力。它尝试了 1,000 种不同的总体随机排列,并在基尼系数具有最低标准偏差时选择一种。它适用于您的玩具数据集,并且几乎可以立即使用。

library(ineq)

x <-c(1500, 1100, 9000, 4000, 4000, 3900, 3800, 3600, 3400,
      1000, 900, 800, 700, 700, 400, 300, 300, 300, 200, 100)

Gini(x)
# 0.534

n <- length(x)


best_sd <- 1

for(i in 1:1000){
  grouping <- sample(1:3, n, replace = TRUE)
  ginis <- tapply(x, grouping, Gini)
  s <- sd(ginis)
  if(s < best_sd){
    best_sd <- s
    best_grouping <- grouping
    best_i <- i}
}

best_sd
# 0.000891497

tapply(x, best_grouping, Gini)
#         1         2         3 
# 0.5052780 0.5042017 0.5035088 

它不能保证是最好的,但它显然是相当接近的。一个更优雅的解决方案会找到方法来挑选和选择在接近时交换哪些点,但这可能会减慢计算速度,并且肯定会花费更多的开发时间!

使用包含 100,000 个观测值的更大数据集,在我的笔记本电脑上仍然只需要 12 秒,因此可以扩展。

于 2018-07-03T06:09:49.377 回答
0

回答自己的问题不是很礼貌,但我认为值得分享。这是我从上面的Peter Ellis 回答R中汲取灵感而写的。欢迎任何评论/改进想法:

library(ineq)
x <-c(15000, 11000, 9000, 4000, 4000, 3900, 3800, 3600, 3400,
      1000, 900, 800, 700, 700, 400, 300, 300, 300, 200, 100)
n <- length(x)

best_sd <- 1
for(d in 2:n-2) for(u in 3:n-2){
  g <- c(Gini(x[1:d]), Gini(x[d+1:u]), Gini(x[u+1:n]))
  s <- sd(g) 
  if(s < best_sd){
    best_sd <- s
    best_grouping <- c(d,u)
    best_g <- g
  }
}

best_sd
#[1] 0.005250825
best_grouping
#[1]  9 11
best_g
#[1] 0.3046409 0.3144654 0.3127660
于 2018-07-03T15:46:25.200 回答