Найти 3 подвыборки с одинаковым (приблизительно) коэффициентом Джини - PullRequest
0 голосов
/ 03 июля 2018

Допустим, у меня есть выборка из N физических лиц и случайная величина X, которая представляет их годовой доход в иностранной валюте. Пример X может быть следующим:

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

Теперь я должен "сэмплировать" 20 компоненты X в 3 "упорядоченных" подгруппах (необязательно с одинаковым количеством компонентов), чтобы они имели (приблизительно) один и тот же коэффициент Джини.

В качестве напоминания для коэффициента Джини : просто рассчитайте% каждого дохода от общего дохода (например, 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.

Это легко сделать с помощью грубой силы: разделите выборку на 3, рассчитайте Джини для трех выборок и попробуйте перейти от / к средней верхней и нижней компонентам выборки, чтобы определить, улучшаются или ухудшаются различия в показателях Джини. выкл. Тем не менее, это занимает очень много времени, чтобы сделать это вручную (например, в 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 

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Не очень вежливо отвечать на свой вопрос, но я думаю, что стоит поделиться им. Это то, что я написал в 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
0 голосов
/ 03 июля 2018

Хорошо, вот метод в R, который по крайней мере автоматизирует грубую силу. Он пробует 1000 различных случайных перестановок населения и выбирает случай, когда коэффициенты Джини имеют самое низкое стандартное отклонение. Он работает хорошо и практически мгновенно с вашим набором игрушечных данных.

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 секунд на моем ноутбуке, поэтому он масштабируется нормально.

...