10

サンプルのジニ係数を計算する 1 つの方法は、ジニ係数の 2 倍である相対平均差 (RMD) を使用することです。RMD は、以下によって与えられる平均差に依存します。

ここに画像の説明を入力

したがって、 sample 内の要素のペア間のそれぞれの差を計算する必要があります(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

効率的だが簡単に一般化できるものはありますか? たとえば、3 つのインデックスを合計するにはどうすればよいでしょうか。

これは私が使用していたサンプルです:

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^2)の代わりにO(N*Log(N))を達成できます

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)

多くの場合、これらを高速化するために動的プログラミングまたはその他の手法を使用する必要がありますが、「1 つの方法ですべてに適合する」ソリューションがあるかどうかはわかりません。

于 2012-12-27T00:54:48.343 に答える