10

计算样本基尼系数的一种方法是使用相对平均差 (RMD),它是基尼系数的 2 倍。RMD 取决于由下式给出的平均差:

在此处输入图像描述

所以我需要计算样本中一对元素之间的每个差异(yi - yj)。我花了很多时间才想出一种方法来做到这一点,但我想知道是否有一个函数可以为你做到这一点。

起初我试过这个,但我敢打赌它在大数据集中非常慢(顺便说一下,s 是样本):

In [124]:

%%timeit
from itertools import permutations
k = 0
for i, j in list(permutations(s,2)):
    k += abs(i-j)
MD = k/float(len(s)**2)
G = MD / float(mean(s))
G = G/2
G
10000 loops, best of 3: 78 us per loop

然后我尝试了以下不太容易理解但更快的方法:

In [126]:
%%timeit
m = abs(s - s.reshape(len(s), 1))
MD = np.sum(m)/float((len(s)**2))
G = MD / float(mean(s))
G = G/2
G
10000 loops, best of 3: 46.8 us per loop

有什么有效但易于概括的东西吗?例如,如果我想对三个索引求和怎么办?

这是我使用的示例:

sample = array([5487574374,     686306,    5092789,   17264231,   41733014,
         60870152,   82204091,  227787612,  264942911,  716909668,
        679759369, 1336605253,  788028471,  331434695,  146295398,
         88673463,  224589748,  128576176,  346121028])

gini(sample)
Out[155]:
0.2692307692307692

谢谢!

4

1 回答 1

1

对于您给出的MD示例,可以通过排序来利用它,您可以实现O(N * Log(N))而不是O(N ^ 2)

y = [2,3,2,34]

def slow(y):
    tot = 0
    for i in range(len(y)):
        for j in range(len(y)):
            if i != j:
                tot += abs(y[i] - y[j])
    return float(tot)/len(y)**2

print slow(y)

def fast(y):
    sorted_y = sorted(y)
    tot = 0
    for i, yi in enumerate(sorted_y):
        smaller = i
        bigger = len(y) - i - 1
        tot += smaller * yi - bigger * yi
    return float(2*tot)/len(y)**2

print fast(y)

通常您将不得不使用动态编程或其他技术来使这些更快,我不确定是否有“一种方法适合所有人”的解决方案。

于 2012-12-27T00:54:48.343 回答