Monday, 3 July 2017

Algoritmo De Filtro De Média Móvel Exponencial


Eu essencialmente tenho uma série de valores como este: a matriz acima é simplificada, 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, IncIm codificando algo no momento em que eu estou levando um monte de valores ao longo do tempo a partir de uma bússola de hardware. Esta bússola é muito precisa e atualiza-se com muita frequência, com o resultado de que, se ela for ligeiramente leve, acabo com o valor estranho que é extremamente incompatível com seus vizinhos. Eu quero suavizar esses valores. Tendo feito alguma leitura ao redor, parece que o que eu quero é um filtro passa-alto, um filtro passa-baixa ou uma média móvel. Mudar a média com que consigo descer, mantenho um histórico dos últimos 5 valores ou o que quer que seja e use a média desses valores a jusante no meu código, onde acabei de usar o valor mais recente. Isso deve, penso eu, suavizar esses jiggles bem, mas isso me parece que é provavelmente bastante ineficiente, e este é provavelmente um desses Problemas Conhecidos para Programadores Aprovados para o qual existe uma solução de Matemática inteligente inteligente. Eu sou, no entanto, um daqueles horríveis programadores autodidatas sem um pingo de educação formal em qualquer coisa, mesmo vagamente relacionada com CompSci ou Matemática. Ler em torno de um pouco sugere que este pode ser um filtro de passagem alta ou baixa, mas não consigo encontrar nada que explique em termos compreensíveis para um hack como eu, qual seria o efeito desses algoritmos em uma série de valores, e muito menos como as matemáticas trabalho. A resposta dada aqui. Por exemplo, tecnicamente responde a minha pergunta, mas apenas em termos compreensíveis para aqueles que provavelmente já saberiam como resolver o problema. Seria uma pessoa muito adorável e inteligente, de fato, quem poderia explicar o tipo de problema que isso é, e como funcionam as soluções, em termos compreensíveis para um graduado em artes. Perguntou 21 de setembro às 13:01 Se sua média móvel deve ser longa para conseguir o alisamento necessário e você realmente não precisa de nenhuma forma específica de kernel, então você estará melhor se usar uma média móvel exponencialmente decadente: onde você Escolha minúsculo para ser uma constante apropriada (por exemplo, se você escolher um pequeno 1- 1N, ele terá a mesma quantidade de média como uma janela de tamanho N, mas distribuído de maneira diferente em pontos mais antigos). De qualquer forma, uma vez que o próximo valor da média móvel depende apenas do anterior e de seus dados, você não precisa manter uma fila ou qualquer coisa. E você pode pensar nisso como fazendo algo como, Bem, eu tenho um novo ponto, mas eu realmente não confio nisso, então eu vou manter 80 da minha antiga estimativa da medição, e só confio neste novo ponto de dados 20. Isso é Praticamente o mesmo que dizer: Bem, eu só confio neste novo ponto 20, e eu uso 4 outros pontos que eu confio na mesma quantidade, exceto que em vez de tomar explicitamente os outros 4 pontos, você assumirá que a média que você fez na última vez Foi sensato para que você possa usar seu trabalho anterior. Respondeu 21 de setembro 10 às 14:27 Ei, eu sei que isso é 5 anos de atraso, mas obrigado por uma ótima resposta. Estou trabalhando em um jogo onde o som muda com base em sua velocidade, mas, devido ao funcionamento do jogo em um computador de câmera lenta, a velocidade flutuaria selvagemente, o que era bom para a direção, mas super irritante em termos de som. Esta foi uma solução muito simples e barata para algo que pensei que seria um problema realmente complexo. Ndash Adam Mar 16 15 at 20:20 Se você está tentando remover o valor ímpar ocasional, um filtro passa-baixa é a melhor das três opções que você identificou. Os filtros de passagem baixa permitem mudanças de baixa velocidade, como as causadas pela rotação de uma bússola à mão, ao mesmo tempo que rejeitam mudanças de alta velocidade, como as causadas por solavancos na estrada, por exemplo. Uma média móvel provavelmente não será suficiente, uma vez que os efeitos de uma única descarga em seus dados afetarão vários valores subsequentes, dependendo do tamanho da sua janela média móvel. Se os valores estranhos forem facilmente detectados, você pode até estar melhor com um algoritmo de remoção de falhas que os ignora completamente: Aqui está um gráfico de guick para ilustrar: O primeiro gráfico é o sinal de entrada, com uma falha desagradável. O segundo gráfico mostra o efeito de uma média móvel de 10 amostras. O gráfico final é uma combinação da média de 10 amostras e do algoritmo de detecção de falha simples mostrado acima. Quando a falha é detectada, a média de 10 amostras é usada em vez do valor real. Mover média com a qual posso descer. Mas parece-me que é provavelmente bastante ineficiente. Realmente, nenhum motivo para uma média móvel deve ser ineficiente. Você mantém o número de pontos de dados desejados em algum buffer (como uma fila circular). Em cada novo ponto de dados, você exibe o valor mais antigo e subtrai-lo de uma soma, e empurre o mais novo e adicione-o à soma. Portanto, cada novo ponto de dados realmente só envolve um poppush, uma adição e uma subtração. Sua média móvel é sempre essa soma de mudança dividida pelo número de valores em seu buffer. Isso fica um pouco mais complicado se você estiver recebendo dados simultaneamente de vários tópicos, mas como seus dados são provenientes de um dispositivo de hardware que parece muito duvidoso para mim. Ah, e também: os horríveis programadores autodidatas se unem) A média móvel pareceu ineficiente para mim porque você precisa armazenar um buffer de valores - melhor para fazer algumas Matemáticas Inteligentes com seu valor de entrada e valor de trabalho atual Eu acho que isso é como a média móvel exponencial trabalho. Uma otimização que eu vi para este tipo de média móvel envolve o uso de um amplificador de espera de comprimento fixo, um ponteiro para onde você está na fila, e apenas empacotando o ponteiro ao redor (com ou um if). Voila Não há pushpop caro. Poder para os amadores, irmão ndash Henry Cooke 22 de setembro 10 às 0:54 Henry: Para uma média móvel direta, você precisa do buffer simplesmente para que você saiba o valor que aparece quando o próximo valor é empurrado. Dito isto, o amplo amplificador de espera de comprimento fixo que você está descrevendo é exatamente o que eu quis dizer com uma fila quotcircular. Por isso, eu estava dizendo que isso não é ineficiente. O que você achou que eu quis dizer E se sua resposta é uma matriz quotan que muda seus valores de volta em cada remoção indexada (como std :: vector em C). Bem, então, eu já estou doente, nem quero falar com você mais) ndash Dan Tao 22 de setembro 10 às 1:58 Henry: Eu não sei sobre AS3, mas um programador de Java tem coleções como CircularQueue em sua disposição (I39m não é um Desenvolvedor de Java, então eu tenho certeza de que há exemplos melhores lá fora, esse é o que eu encontrei a partir de uma busca rápida do Google), que implementa precisamente a funcionalidade em que estamos falando. Estou bastante confiante de que a maioria das linguagens de nível médio e baixo com bibliotecas padrão tem algo semelhante (por exemplo, no. NET there39s QueueltTgt). Enfim, eu também era filosofia. tudo é perdoado. Ndash Dan Tao 22 de setembro 10 às 12:44 Uma média móvel exponencialmente decadente pode ser calculada manualmente com apenas a tendência se você usar os valores apropriados. Veja quatromilab. chhackdiete4 para uma idéia sobre como fazer isso rapidamente com uma caneta e papel, se você estiver procurando uma média móvel suavemente exponencial com 10 suavização. Mas, como você tem um computador, você provavelmente deseja fazer mudanças binárias em oposição à mudança decimal). Desta forma, tudo que você precisa é uma variável para seu valor atual e outra para a média. A próxima média pode então ser calculada a partir disso. Respondeu 21 de setembro 10 às 14:39 há uma técnica chamada de portão de alcance que funciona bem com amostras espúrias de baixa ocorrência. Assumindo o uso de uma das técnicas de filtro mencionadas acima (média móvel, exponencial), uma vez que você tenha um histórico suficiente (uma Constante de Tempo), você pode testar a nova amostra de dados recebidos por razoabilidade, antes de ser adicionada à computação. É necessário algum conhecimento da taxa de mudança máxima razoável do sinal. A amostra bruta é comparada ao valor mais liso e se o valor absoluto dessa diferença é maior que o intervalo permitido, essa amostra é descartada (ou substituída por alguma heurística, por exemplo, uma previsão baseada no diferencial de inclinação ou na tendência Valor de previsão a partir de suavização exponencial dupla) 30 de abril de 16 em algoritmo 6: 56C para média móvel exponencial de latência zero Última modificação: 2012-08-13 Estou tentando 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