Wednesday 9 August 2017

Algoritmo Da Média Móvel Exponencial


Eu preciso acompanhar os últimos 7 dias de trabalho em um loop de leitura de arquivos planos. Está sendo usado para medir a fatigabilidade das listas de trabalho. Agora eu tenho algo que funciona, mas parece bastante detalhado e não tenho certeza se há um padrão que é mais sucinto. Atualmente, eu tenho uma classe Java com uma matriz estática para armazenar os últimos dados de x dias, então, ao ler o arquivo, retiro o primeiro elemento e mova os outros 6 (por um total de uma semana) de volta por um. O processamento desta matriz estática é feito em seu próprio método, ou seja. A minha pergunta: esta é uma abordagem de design razoável, ou há algo cegamente óbvio e simples para fazer esta tarefa. Obrigado, eles pediram 30 de agosto 11 às 14:33. Obrigado, pessoal: eu recebi a mensagem: use um objeto de nível superior e explore o Métodos relevantes ou um buffer circular. Excelentes respostas, todas elas. Quando você pensa sobre isso, você sempre precisa ter acesso a toda a matriz para que você possa se livrar daquela primeira entrada - da qual eu não tinha certeza por minha conta. Eu aliviei que eu não tivesse perdido algum liner e estava basicamente em uma faixa razoável, se não eficiente e fácil. Isto é o que eu adoro neste site: respostas de alta qualidade e relevantes de pessoas que conhecem o seu sht. Ndash Pete855217 30 de agosto 11 às 15:05 Por que você inicializa o runningTotal para null O que é seu tipo Onde é declarado Isso faria bem se você colocar alguns exemplos de código que se assemelham ao código Java real. Continuando, minha crítica seria a seguinte: sua função faz demais. Uma função ou método deve ser coeso. Mais apropriadamente, eles devem fazer uma coisa e uma coisa apenas. Pior ainda, o que acontece no seu loop for quando x 5 Você copia runningTotal6 em runningTotal5. Mas então você tem duas cópias do mesmo valor na posição 5 e 6. No seu projeto, sua função movesshuffles os itens em sua matriz calcula o material total de impressões para o erro padrão retorna o total. Faz demais. Minha primeira sugestão não é mover coisas na matriz. Em vez disso, implemente um buffer circular e use-o em vez da matriz. Isso simplificará seu design. A minha segunda sugestão é dividir as coisas em funções que são coesas: tenha uma estrutura de dados (um buffer circular) que lhe permita adicionar a ela (e isso diminui a entrada mais antiga sempre que ela atinja sua capacidade). Interator tem uma função que calcula o total no iterador (você não se importa se você estiver calculando o total de uma matriz, lista ou bufer circular). Não o chame total. Chame isso de soma, que é o que você está informando. Isso é o que eu faço :) Essa é a ótima informação de luis, no entanto, lembre-se de que esta função é uma pequena parte da funcionalidade da classe, e seria um excesso para adicionar muito código para torná-la perfeita. Você é tecnicamente correto, e eu entendo que meu código faz 39 muito muito39, mas, ao mesmo tempo, às vezes é melhor errar ao lado de um código menor e mais claro do que ir para a perfeição. Dadas as minhas habilidades em Java, mesmo fazer o pseudocódigo que você descreve a compilação me faria soprar meu orçamento neste (), mas obrigado pela descrição clara. Ndash Pete855217 31 de agosto 11 às 2:23 Hmmm, não é sobre a perfeição, mas sobre práticas industriais estabelecidas que conhecemos há 3 décadas. O código limpo é sempre um que é particionado. Temos décadas de evidências que indicam que este é o caminho a seguir no caso geral (em termos de custo-eficiência, redução de defeitos, compreensão, etc.). A menos que seja um código descartável por um tipo de coisa única. Nunca é dispendioso fazer isso quando se inicia qualquer análise de problema dessa maneira. Codificação 101, quebra o problema e o código segue, nem excesso nem dificuldade) ndash luis. espinal 31 de agosto 11 às 15:55 Sua tarefa é muito simples e o enfoque que você adotou é certamente bom para o trabalho. No entanto, se você quiser usar um design melhor, você deve se livrar de todo esse movimento numérico, você usa uma fila FIFO e faz bom uso de métodos push e pop, de modo que o código não reflete qualquer movimento de dados, apenas as duas ações de lógica De novos dados e remova dados com mais de 7 dias. Respondeu 30 de agosto 11 às 14: 49I essencialmente tenho uma série de valores como este: a matriz acima é simplificada demais, estou coletando 1 valor por milissegundo no meu código real e preciso processar a saída em um algoritmo que escrevi para encontrar o pico mais próximo Antes de um ponto no tempo. Minha lógica falha porque no meu exemplo acima, 0.36 é o pico real, mas meu algoritmo olhava para trás e veria o último número 0.25 como o pico, pois há uma diminuição para 0.24 antes dele. O objetivo é levar esses valores e aplicar um algoritmo para eles, que os suavizará um pouco para que eu tenha mais valores lineares. (Ie: Id como os meus resultados para serem curvy, não jaggedy) Eu fui dito para aplicar um filtro exponencial de média móvel aos meus valores. Como posso fazer isso. É muito difícil para mim ler equações matemáticas, eu lido muito melhor com o código. Como faço para processar valores na minha matriz, aplicando um cálculo exponencial da média móvel para os fazer sair, solicitado 8 de fevereiro às 20:27 Para calcular uma média móvel exponencial. Você precisa manter algum estado ao redor e você precisa de um parâmetro de ajuste. Isso exige uma pequena classe (supondo que você esteja usando o Java 5 ou posterior): instanciar com o parâmetro de decaimento desejado (pode ser necessário que a sintonização esteja entre 0 e 1) e depois use a média () para filtrar. Ao ler uma página sobre uma recorrência matemática, tudo o que você realmente precisa saber ao transformá-lo em código é que os matemáticos gostam de escrever índices em arrays e seqüências com subscritos. (Eles também têm algumas outras notações, o que não ajuda.) No entanto, o EMA é bastante simples, pois você só precisa se lembrar de um valor antigo, não é necessário nenhum arrays de estados complicados. Respondeu 8 de fevereiro às 20:42 TKKocheran: praticamente. Não é bom quando as coisas podem ser simples (Se começar com uma nova seqüência, obtenha uma nova média). Observe que os primeiros termos da seqüência média saltarão em torno de um bit devido a efeitos de limites, mas você obtém aqueles com outras médias móveis também. No entanto, uma boa vantagem é que você pode envolver a lógica média móvel na média e experimentar sem incomodar demais o seu programa. Ndash Donal Fellows 9 de fevereiro às 0:06 Estou tendo dificuldade em entender suas perguntas, mas vou tentar responder de qualquer maneira. 1) Se o seu algoritmo encontrou 0,25 em vez de 0,36, então é errado. É errado porque assume um aumento ou diminuição monotônico (que sempre está subindo ou sempre está indo para baixo). A menos que você tenha média de todos os seus dados, seus pontos de dados --- como você os apresenta --- são não-lineares. Se você realmente quer encontrar o valor máximo entre dois pontos no tempo, então corte sua matriz de tmin para tmax e encontre o máximo desse subarray. 2) Agora, o conceito de médias móveis é muito simples: imagine que eu tenho a seguinte lista: 1.4, 1.5, 1.4, 1.5, 1.5. Eu posso suavizar, levando a média de dois números: 1.45, 1.45, 1.45, 1.5. Observe que o primeiro número é a média de 1,5 e 1,4 (segundo e primeiro número), a segunda (nova lista) é a média de 1,4 e 1,5 (terceira e segunda lista antiga) a terceira (nova lista) a média de 1,5 e 1,4 (Quarto e terceiro), e assim por diante. Eu poderia ter feito período três ou quatro, ou n. Observe como os dados são muito mais suaves. Uma boa maneira de ver as médias móveis no trabalho é ir para o Google Finance, selecionar um estoque (tente Tesla Motors bastante volátil (TSLA)) e clique em técnicas na parte inferior do gráfico. Selecione a média móvel com um período determinado e a média móvel exponencial para comparar suas diferenças. A média móvel exponencial é apenas uma outra elaboração deste, mas considera os dados mais antigos inferiores aos novos dados, esta é uma maneira de polarizar o alisamento para trás. Leia a entrada da Wikipedia. Então, isso é mais um comentário do que uma resposta, mas a pequena caixa de comentários foi apenas pequena. Boa sorte. Se você estiver tendo problemas com a matemática, você poderia ir com uma média móvel simples em vez de exponencial. Então, a saída que você obtém seria os últimos x termos divididos por x. Pseudocódigo não testado: note que você precisará lidar com as partes de início e término dos dados, pois claramente você não pode significar os últimos 5 termos quando estiver no seu segundo ponto de dados. Além disso, existem maneiras mais eficientes de calcular essa média móvel (soma sumária - a mais nova), mas é para obter o conceito de o que está acontecendo. Respondeu 8 de fevereiro às 20:41 Sua resposta 2017 Stack Exchange, algoritmo IncC para média móvel exponencial de latência zero Última modificação: 2012-08-13 Tenho tentado implementar um corte de baixa freqüência em c que essencialmente leva um fluxo de números e Suaviza a saída (filtragem de movimento de alta freqüência), porém é importante que os números ponderados da frente sejam considerados imediatamente, pois os dados são críticos no tempo (é controlar uma base de simulação de movimento usando o resultado de um pouco de software de jogo). Eu tenho um algoritmo de média móvel ponderada trabalhando, mas poderia fazer com algo um pouco mais responsivo no front-end, e eu achei isso: - O pseudo-código é o seguinte: Entradas: Preço (NumericSeries), Periodo (NumericSimple) Variáveis: Fator (0), lag (0) se CurrentBar lt 1 começar ZLEMA Fator de preço 2 (Período1) atraso (Período-1) 2 final, então, começar fator ZLEMA (2Preço-Pricelag) (1 fator) ZLEMA1 fim Ive traduziu-o em Para C e meu código é o seguinte: No entanto, ele não parece se comportar bem como espero. Parece estar quase lá, mas às vezes eu recebo um valor ligeiramente inferior ao de todos os itens na fila (quando eles são todos mais altos). Minha fila e o número de itens nele são passados ​​como parâmetros, sendo que o último é na frente em todos os momentos, também passo um contador incremental a partir de 0, conforme exigido pela função. Eu não tenho certeza de que interpretei o significado do ZLEMA1 corretamente, pois não está claro em seu pseudocódigo, então eu considerei que isso é o último zlema de chamadas e também suponho que o preço realmente significa Price0. Talvez eu tenha feito isso errado. Eu deveria estar copiando os valores calculados zlema reais de volta para minha fila original antes da próxima chamada, eu não mudo a fila original do que simplesmente deslocando todos os valores um para o final e inserindo o mais recente no início . O código que eu uso para fazer isso é: ficaria extremamente agradecido se alguém com uma melhor compreensão da matemática pudesse sanar a sanidade verifique isso para mim, para ver se eu tenho algo um pouco errado. Agradeço muito com antecedência, se você puder ajudar. Em primeiro lugar, agradeço tudo por Sua contribuição, muito apreciada. Isso faz sentido, acho que, então, suponho que o melhor que eu possa esperar é simplesmente uma média móvel exponencial, aceitando que haverá um pouco de atraso, mas isso será minimizado pela ponderação frontal mais pesada do que a dada em tipical ponderada Média móvel também tenho esse algoritmo, mas um problema semelhante na medida em que os valores não parecem bastante corretos (a menos que esta seja a natureza da fórmula). Por exemplo, diga que minha matriz contém 16 valores, tudo 0.4775 - a saída é 0.4983, mas espero que seja 0.4775 Isso parece diretamente para você. Média móvel exponencial. Float ema (float vals, int numVals, int currentSample) static float factor 0 static float lastema 0 float ema if (currentSample lt 1) ema vals0 factor 2.0 ((float) numVals) 1.0) else ema (factor vals0) ((1.0 - factor) lastema) lastema ema return ema Inversamente, as vezes a saída é menor que todas e cada uma das entradas, mesmo que todas sejam mais altas. É chamado da mesma maneira que zlema (.) Acima, com um contador de incremento. A fórmula e o pseudocódigo para este estão aqui: - autotradingstrategy. wordpress20091130exposential-moving-average Obrigado novamente, desculpas pelo meu mal-entendido de alguns dos princípios básicos :( Atenciosamente, Chris J Quanto ao código que postei, você está certo sobre o tamanho da matriz Situação. Isso deve ser facilmente corrigido. Quanto às suas perguntas: 1) A constante do filtro representa um corte de freqüência. Eu usei um Processamento de Sinal Digital (DSP) para esta técnica. En. wikipedia. orgwi kiLow-pas sfilter é uma explicação simples. Você quer a seção de Realização de Tempo Discreto. No meu caso, o A é o RC-Constant de que falam. Portanto, a freqüência que ele corta é acima de 1 (2piA). Se você não tem uma compreensão da teoria do domínio da frequência, isso pode se tornar complicado. No seu caso, quanto maior você fizer A, menor será a frequência que este filtro permitirá, o que significa que irá suavizar cada vez mais a curva. Quanto mais baixo você conseguir, mais ruído é permitido no sistema. Lembre-se de que A deve ser maior ou igual a 1 para ser eficaz. Voltei a colocar o XLS novamente, desta vez sem os números mut rand (). Ajuste a constante A e assista como quotsmoothsquot (ou filtra) as variações de alta freqüência. 2) O último ponto da matriz de entrada tem o valor mais recente. 3) O mesmo é verdadeiro para a matriz de saída. O último é o valor mais recente. 5) O NUMVALS é arbitrário. Você pode adicionar continuamente à matriz de entrada e saída, quantas vezes você quiser e não afetará o filtro. Em particular, usei 49 pontos. Mas eu posso excluir facilmente os últimos 20 e as primeiras 29 saídas permaneceriam as mesmas. A função não é baseada em quantos pontos estão sendo usados. Gostaria de mencionar que desenvolvi essa função para uma conversão única. Se você quisesse fazer uma conversão para o próximo valor, você poderia tentar algo mais simples (como anexado). Novamente estou enferrujado em c. Espero que isso esteja certo. A única coisa que você precisaria fornecer é a entrada e filtro constante. Avise-me se isso ajudar.

No comments:

Post a Comment