Algoritmos “on-line” (iterador) para estimar mediana estatística, modo, assimetria, curtose?


86

Existe um algoritmo para estimar a mediana, modo, assimetria e / ou curtose de um conjunto de valores, mas isso NÃO exige o armazenamento de todos os valores na memória de uma vez?

Eu gostaria de calcular as estatísticas básicas:

  • média: média aritmética
  • variância: média dos desvios quadrados da média
  • desvio padrão: raiz quadrada da variância
  • mediana: valor que separa a metade maior dos números da metade menor
  • modo: valor mais frequente encontrado no conjunto
  • assimetria: tl; dr
  • curtose: tl; dr

A fórmula básica para calcular qualquer um desses é a aritmética do ensino fundamental, e eu as conheço. Existem muitas bibliotecas de estatísticas que as implementam também.

Meu problema é o grande número (bilhões) de valores nos conjuntos que estou lidando: Trabalhando em Python, não posso simplesmente fazer uma lista ou hash com bilhões de elementos. Mesmo se eu escrever isso em C, os arrays de bilhões de elementos não são muito práticos.

Os dados não são classificados. É produzido aleatoriamente, em tempo real, por outros processos. O tamanho de cada conjunto é altamente variável e os tamanhos não serão conhecidos com antecedência.

Já descobri como lidar muito bem com a média e a variância, iterando cada valor no conjunto em qualquer ordem. (Na verdade, no meu caso, eu os considero na ordem em que são gerados.) Aqui está o algoritmo que estou usando, cortesia http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm :

  • Inicialize três variáveis: count, sum e sum_of_squares
  • Para cada valor:
    • Contagem de incremento.
    • Adicione o valor à soma.
    • Adicione o quadrado do valor a sum_of_squares.
  • Divida a soma pela contagem, armazenando como a média variável.
  • Divida sum_of_squares por count, armazenando como a variável mean_of_squares.
  • Média quadrada, armazenando como quadrada_de_média.
  • Subtraia square_of_mean de mean_of_squares, armazenando como variância.
  • Média e variação da saída.

Este algoritmo "on-line" tem pontos fracos (por exemplo, problemas de precisão, pois sum_of_squares cresce rapidamente além do intervalo inteiro ou precisão flutuante), mas basicamente me dá o que preciso, sem ter que armazenar todos os valores em cada conjunto.

Mas não sei se existem técnicas semelhantes para estimar as estatísticas adicionais (mediana, modo, assimetria, curtose). Eu poderia conviver com um estimador tendencioso, ou mesmo um método que comprometa a precisão até certo ponto, desde que a memória necessária para processar N valores seja substancialmente menor que O (N).

Indicar uma biblioteca de estatísticas existente também ajudará se a biblioteca tiver funções para calcular uma ou mais dessas operações "on-line".


os dados serão passados ​​ordenados e você saberá com antecedência o número de entradas?
chillysapien


São dados inteiros ou dados flutuantes? Você tem um valor máximo ou mínimo?
stephan

dmckee: Na verdade, estou usando o método de Welford para o desvio padrão. Mas não vejo nada nesse link sobre modo, mediana, curtose ou assimetria ... Estou faltando alguma coisa?
Ryan B. Lynch

stephan: Alguns conjuntos de dados são inteiros, outros são flutuantes. A distribuição da população é muito próxima do normal (Gaussiana), portanto, podemos estabelecer um intervalo de confiança, mas não há limite de faixa rígido (exceto x> 0, em alguns casos).
Ryan B. Lynch

Respostas:


53

Assimetria e curtose

Para os algoritmos on-line para assimetria e curtose (ao longo das linhas da variância), consulte na mesma página wiki aqui os algoritmos paralelos para estatísticas de momento superior.

Mediana

A mediana é difícil sem dados classificados. Se você sabe quantos pontos de dados você possui, em teoria você só precisa classificar parcialmente, por exemplo, usando um algoritmo de seleção . No entanto, isso não ajuda muito com bilhões de valores. Eu sugeriria o uso de contagens de frequência, consulte a próxima seção.

Mediana e modo com contagens de frequência

Se forem inteiros, eu contaria as frequências , provavelmente cortando os valores mais altos e mais baixos além de algum valor onde tenho certeza de que não é mais relevante. Para floats (ou muitos inteiros), provavelmente criaria baldes / intervalos e, em seguida, usaria a mesma abordagem que para inteiros. O modo (aproximado) e o cálculo da mediana ficam mais fáceis, com base na tabela de frequências.

Variáveis ​​Aleatórias Normalmente Distribuídas

Se for normalmente distribuído, eu usaria a média , variância , assimetria e curtose da amostra populacional como estimadores de máxima verossimilhança para um pequeno subconjunto. Os algoritmos (on-line) para calcular aqueles, você já. Por exemplo, leia algumas centenas de milhares ou milhões de pontos de dados, até que o erro de estimativa fique pequeno o suficiente. Apenas certifique-se de escolher aleatoriamente de seu conjunto (por exemplo, para não introduzir um viés escolhendo os primeiros 100.000 valores). A mesma abordagem também pode ser usada para estimar modo e mediana para o caso normal (para ambos, a média da amostra é um estimador).

Comentários adicionais

Todos os algoritmos acima podem ser executados em paralelo (incluindo muitos algoritmos de classificação e seleção, por exemplo, QuickSort e QuickSelect), se isso ajudar.

Sempre presumi (com exceção da seção sobre a distribuição normal) que falamos de momentos, mediana e moda de amostra, e não de estimadores para momentos teóricos, dada uma distribuição conhecida.

Em geral, a amostragem dos dados (ou seja, apenas olhando para um subconjunto) deve ser bem sucedida dada a quantidade de dados, desde que todas as observações sejam realizações da mesma variável aleatória (têm as mesmas distribuições) e os momentos, modo e mediana realmente existe para esta distribuição. A última ressalva não é inócua. Por exemplo, a média (e todos os momentos superiores) para a Distribuição de Cauchy não existem. Nesse caso, a média da amostra de um subconjunto "pequeno" pode estar muito diferente da média da amostra de toda a amostra.


57

Eu uso esses estimadores de média e mediana incrementais / recursivos, que usam armazenamento constante:

mean += eta * (sample - mean)
median += eta * sgn(sample - median)

onde eta é um pequeno parâmetro de taxa de aprendizagem (por exemplo, 0,001) e sgn () é a função signum que retorna um de {-1, 0, 1}. (Use uma constante eta se os dados não forem estacionários e você quiser rastrear as mudanças ao longo do tempo; caso contrário, para fontes estacionárias, você pode usar algo como eta = 1 / n para o estimador médio, onde n é o número de amostras vistas longe ... infelizmente, isso não parece funcionar para o estimador mediano.)

Este tipo de estimador de média incremental parece ser usado em todo lugar, por exemplo, em regras de aprendizagem de rede neural não supervisionada, mas a versão mediana parece muito menos comum, apesar de seus benefícios (robustez para outliers). Parece que a versão mediana pode ser usada como um substituto para o estimador médio em muitas aplicações.

Eu adoraria ver um estimador de modo incremental de uma forma semelhante ...

ATUALIZAR

Acabei de modificar o estimador mediano incremental para estimar quantis arbitrários. Em geral, uma função quantil ( http://en.wikipedia.org/wiki/Quantile_function ) informa o valor que divide os dados em duas frações: pe 1-p. O seguinte estima esse valor de forma incremental:

quantile += eta * (sgn(sample - quantile) + 2.0 * p - 1.0)

O valor p deve estar entre [0,1]. Isso essencialmente muda a saída simétrica da função sgn () {-1,0,1} para inclinar para um lado, particionando as amostras de dados em dois compartimentos de tamanhos desiguais (frações pe 1-p dos dados são menores que / maiores que a estimativa do quantil, respectivamente). Observe que para p = 0,5, isso se reduz ao estimador da mediana.


3
Este estimador mediano é ótimo. Você sabe se existem estimadores semelhantes para quantis 0,25 / 0,75?
Gacek

1
@Gacek, claro: divida o fluxo de entrada em Lohalf <median e Hihalf> mediano e use a mediana em execução em cada metade.
denis

2
@Gacek: Acabei de atualizar minha resposta com um método incremental para estimar qualquer quantil, onde você pode definir p como 0,25, 0,75 ou qualquer valor dentro de [0,1].
Tyler Streeter

10
Isso funciona muito bem para a média, mas não estou vendo como isso produz algo remotamente próximo da média. Pegue uma sequência de carimbos de data / hora em milissegundos, por exemplo: [1328083200000, 981014400000, -628444800000, 318240000000, 949392000000]que têm uma mediana de 318240000000. Esta equação muda a mediana anterior em +/- etada qual era o valor recomendado 0.001. Isso não fará nada para números grandes como esses e pode ser muito grande para números realmente pequenos. Como você escolheria um etaque realmente desse a resposta certa sem saber a resposta a priori?
mckamey

9
Imagine que os números têm unidades, por exemplo, milímetros. Então fica claro que eta (para a estimativa da mediana) tem que ter as mesmas unidades das medidas, e então um valor genérico como 0,001 simplesmente não faz sentido. Uma abordagem aparentemente melhor é definir eta a partir de uma estimativa em execução do desvio absoluto: para cada novo valor sample, atualizar cumadev += abs(sample-median). Em seguida eta = 1.5*cumadev/(k*k), defina , onde kestá o número de amostras vistas até agora.
tholy,

12

Implementei o algoritmo P-Square para cálculo dinâmico de quantis e histogramas sem armazenar observações em um módulo Python bacana que escrevi chamado LiveStats . Deve resolver seu problema de forma bastante eficaz. A biblioteca oferece suporte a todas as estatísticas mencionadas, exceto o modo. Ainda não encontrei uma solução satisfatória para a estimativa de modo.


FYI: o algoritmo p-quadrado é no impulso C ++: <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>.
Neil G

7

Ryan, temo que você não esteja fazendo a média e a variância direito ... Isso surgiu há algumas semanas aqui . E um dos pontos fortes da versão online (que na verdade atende pelo nome de método de Welford) é o fato de ser especialmente precisa e estável, veja a discussão aqui . Um dos pontos fortes é o fato de você não precisar armazenar a soma total ou a soma total dos quadrados ...

Não consigo pensar em nenhuma abordagem on-line para o modo e a mediana, o que parece exigir a consideração de toda a lista de uma vez. Mas pode muito bem ser que uma abordagem semelhante à da variância e da média funcione também para a assimetria e curtose ...


re: skewness and kurtosissim. Veja este artigo: johndcook.com/blog/skewness_kurtosis
Jesse Chisholm

3

O artigo da Wikipedia citado na pergunta contém as fórmulas para calcular a assimetria e curtose on-line.

Para o modo - eu acredito - não há como fazer isso on-line. Por quê? Suponha que todos os valores de sua entrada sejam diferentes, exceto o último que duplica o anterior. Nesse caso, você deve lembrar de todos os valores já vistos na entrada para detectar que o último valor duplica um valor visto antes e o torna o mais frequente.

Para a mediana é quase o mesmo - até a última entrada você não sabe qual valor se tornará a mediana se todos os valores de entrada forem diferentes, porque pode ser antes ou depois da mediana atual. Se você souber o comprimento da entrada, poderá encontrar a mediana sem armazenar todos os valores na memória, mas ainda terá que armazenar muitos deles (acho que em torno da metade) porque uma sequência de entrada incorreta pode alterar fortemente a mediana no segunda metade possivelmente fazendo qualquer valor da primeira metade da mediana.

(Observe que estou me referindo apenas ao cálculo exato.)


2

Se você tem bilhões de pontos de dados, não é provável que precise de respostas exatas, ao contrário de respostas aproximadas. Geralmente, se você tiver bilhões de pontos de dados, o processo subjacente que os gera provavelmente obedecerá a algum tipo de propriedade estatística de estacionariedade / ergodicidade / mistura. Também pode ser importante se você espera que as distribuições sejam razoavelmente contínuas ou não.

Nessas circunstâncias, existem algoritmos para memória baixa on-line, estimativa de quantis (a mediana é um caso especial de 0,5 quantis), bem como modos, se você não precisar de respostas exatas. Este é um campo ativo de estatísticas.

exemplo de estimativa de quantil: http://www.computer.org/portal/web/csdl/doi/10.1109/WSC.2006.323014

exemplo de estimativa de modo: Bickel DR. Estimadores robustos do modo e assimetria de dados contínuos. Estatística Computacional e Análise de Dados. 2002; 39: 153–163. doi: 10.1016 / S0167-9473 (01) 00057-3.

Esses são campos ativos de estatísticas computacionais. Você está entrando em campos onde não existe um único algoritmo de melhor exatidão, mas uma diversidade deles (estimadores estatísticos, na verdade), que têm propriedades, suposições e desempenho diferentes. É matemática experimental. Provavelmente, existem centenas a milhares de artigos sobre o assunto.

A questão final é se você realmente precisa de assimetria e curtose por si só, ou mais provavelmente alguns outros parâmetros que podem ser mais confiáveis ​​para caracterizar a distribuição de probabilidade (assumindo que você tenha uma distribuição de probabilidade!). Você está esperando um gaussiano?

Você tem maneiras de limpar / pré-processar os dados para torná-los mais gaussianos? (por exemplo, os valores das transações financeiras são freqüentemente um tanto gaussianos após a obtenção de logaritmos). Você espera desvios-padrão finitos? Você espera caudas grossas? As quantidades de que você gosta estão na cauda ou no volume?


2

Todo mundo vive dizendo que você não pode fazer o modo online, mas isso simplesmente não é verdade. Aqui está um artigo que descreve um algoritmo para resolver esse problema inventado em 1982 por Michael E. Fischer e Steven L. Salzberg, da Universidade de Yale. Do artigo:

O algoritmo de determinação da maioria usa um de seus registradores para armazenamento temporário de um único item do fluxo; este item é o atual candidato a elemento majoritário. O segundo registrador é um contador inicializado em 0. Para cada elemento do fluxo, pedimos ao algoritmo que execute a seguinte rotina. Se o contador ler 0, instale o elemento stream atual como o novo candidato da maioria (substituindo qualquer outro elemento que já possa estar no registro). Então, se o elemento atual corresponder ao candidato da maioria, aumente o contador; caso contrário, diminua o contador. Neste ponto do ciclo, se a parte do fluxo visto até agora tem um elemento majoritário, esse elemento está no registro candidato e o contador mantém um valor maior que 0. E se não houver um elemento majoritário? Sem fazer uma segunda passagem pelos dados - o que não é possível em um ambiente de fluxo - o algoritmo nem sempre pode dar uma resposta inequívoca nessa circunstância. Ele meramente promete identificar corretamente o elemento majoritário, se houver.

Ele também pode ser estendido para encontrar o N superior com mais memória, mas isso deve resolver o problema para o modo.


4
Esse é um algoritmo interessante, mas a menos que esteja faltando alguma coisa, embora todos os valores majoritários sejam modos, nem todos os modos serão valores majoritários.
jkebinger

O link morreu, então fico feliz que a descrição esteja incluída. MAS, conforme descrito, o contador só aumenta se a 2ª ocorrência do candidato majoritário for adjacente à 1ª ocorrência. Qual IMPLIES classificou os dados. O que NÃO é garantido no caso de dados online (streaming). Com dados ordenados aleatoriamente, é improvável que encontre algum modo.
Jesse Chisholm

1

Em última análise, se você não tem nenhum conhecimento paramétrico a priori da distribuição, acho que você tem que armazenar todos os valores.

Dito isso, a menos que você esteja lidando com algum tipo de situação patológica, o remédio (Rousseuw e Bassett 1990) pode muito bem ser bom o suficiente para seus propósitos.

Muito simplesmente, envolve o cálculo da mediana dos lotes de medianas.


0

a mediana e o modo não podem ser calculados online usando apenas o espaço constante disponível. No entanto, como a mediana e a moda são mais "descritivas" do que "quantitativas", você pode estimá-los, por exemplo, amostrando o conjunto de dados.

Se os dados tiverem distribuição normal no longo prazo, você poderá apenas usar sua média para estimar a mediana.

Você também pode estimar a mediana usando a seguinte técnica: estabelecer uma estimativa da mediana M [i] para cada, digamos, 1.000.000 de entradas no fluxo de dados, de modo que M [0] seja a mediana do primeiro milhão de entradas, M [1] mediana do segundo um milhão de entradas, etc. Em seguida, use a mediana de M [0] ... M [k] como o estimador da mediana. É claro que isso economiza espaço e você pode controlar o quanto deseja usar o espaço "ajustando" o parâmetro 1.000.000. Isso também pode ser generalizado recursivamente.


0

OK cara, tente estes:

para c ++:

double skew(double* v, unsigned long n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow((v[i] - mu)/sigma, 3);
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

double kurt(double* v, double n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow( ((v[i] - mu[i]) / sigma) , 4) - 3;
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

onde você diz que já pode calcular a variância da amostra (svar) e a média (avg), você aponta essas para suas funções para fazer isso.

Além disso, dê uma olhada na aproximação de Pearson. em um conjunto de dados tão grande, seria muito semelhante. 3 (média - mediana) / desvio padrão, você tem a mediana como máx - min / 2

para floats, o modo não tem significado. normalmente, colocá-los em caixas de um tamanho significativo (como 1/100 * (máx. - mín.)).



-1

Eu tenderia a usar baldes, que podem ser adaptativos. O tamanho do balde deve ter a precisão que você precisa. Então, conforme cada ponto de dados chega, você adiciona um à contagem do intervalo relevante. Isso deve fornecer aproximações simples para mediana e curtose, contando cada segmento como seu valor ponderado por sua contagem.

O único problema pode ser a perda de resolução em ponto flutuante após bilhões de operações, ou seja, adicionar um não altera mais o valor! Para contornar isso, se o tamanho máximo do balde exceder algum limite, você pode retirar um grande número de todas as contagens.


-1
for j in range (1,M):
    y=np.zeros(M) # build the vector y
    y[0]=y0

    #generate the white noise
    eps=npr.randn(M-1)*np.sqrt(var)

    #increment the y vector
    for k in range(1,T):
        y[k]=corr*y[k-1]+eps[k-1]

    yy[j]=y

list.append(y)

Poderia usar alguma explicação para vincular melhor isso à pergunta original.
Erica
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.