Рассчитать взвешенные статистические моменты в Python - PullRequest
1 голос
/ 30 апреля 2020

Я искал функцию или пакет, который позволил бы мне рассчитать асимметрию и скачок распределения взвешенным способом, поскольку у меня есть данные гистограммы.

Например, у меня есть данные

import numpy as np

np.array([[1, 2],
          [2, 5],
          [3, 6],
          [4,12],
          [5, 1])

, где первый столбец [1,2,3,4,5] - это значения, а второй столбец [2,5,6,12,1] - частоты значений.

Я узнал, как сделать первые два момента (среднее значение, стандартное отклонение) взвешенным способом, используя функцию weighted_avg_and_std, указанную в этой теме , но я был не совсем уверен как я мог бы распространить это как на перекос, так и на эксцесс, или даже на n-й статистический момент.

Я нашел сами определения здесь и мог бы вручную написать функции для реализации этого с нуля, но до того, как я go и сделал это, мне было интересно, существуют ли какие-либо существующие пакеты или функции который мог бы сделать это.

Спасибо

РЕДАКТИРОВАТЬ: я понял, следующий код работает (обратите внимание, что это для населения моменты)

skewnewss = np.average(((values-average)/np.sqrt(variance))**3, weights=weights)

и

kurtosis=np.average(((values-average)/np.sqrt(variance))**4-3, weights=weights)

1 Ответ

0 голосов
/ 30 апреля 2020

Я думаю, что вы уже перечислили все необходимые ингредиенты, следуя формулам, указанным в указанной вами ссылке:

import numpy as np

a = np.array([[1,2],[2,5],[3,6],[4,12],[5,1]])
values, weights = a.T

def n_weighted_moment(values, weights, n):

    assert n>0 & (values.shape == weights.shape)
    w_avg = np.average(values, weights = weights)
    w_var = np.sum(weights * (values - w_avg)**2)/np.sum(weights)

    if n==1:
        return w_avg
    elif n==2:
        return w_var
    else:
        w_std = np.sqrt(w_var)
        return np.sum(weights * ((values - w_avg)/w_std)**n)/np.sum(weights)
              #Same as np.average(((values - w_avg)/w_std)**n, weights=weights)

Что приводит к:

for n in range(1,5):
    print(f'Moment {n} value is {n_weighted_moment(values, weights, n)}')

Moment 1 value is 3.1923076923076925
Moment 2 value is 1.0784023668639053
Moment 3 value is -0.5962505715592139
Moment 4 value is 2.384432138280637

Обратите внимание, что пока Вы вычисляете избыточный эксцесс , формула, реализованная для общего c n-момента, не учитывает это.

...