Como reduzo o número de pontos de dados em uma série?

11

Não estudo estatísticas há mais de 10 anos (e depois apenas um curso básico), então talvez minha pergunta seja um pouco difícil de entender.

Enfim, o que eu quero fazer é reduzir o número de pontos de dados em uma série. O eixo x é o número de milissegundos desde o início da medição e o eixo y é a leitura desse ponto.

Muitas vezes, existem milhares de pontos de dados, mas talvez eu precise apenas de algumas centenas. Portanto, minha pergunta é: como reduzo com precisão o número de pontos de dados?

Como é chamado o processo? (Para que eu possa pesquisá-lo no Google) Existem algoritmos preferidos (eu o implementarei em C #)

Espero que você tenha algumas pistas. Desculpe pela minha falta de terminologia adequada.


Edit: Mais detalhes vêm aqui:

Os dados brutos que obtive são dados da frequência cardíaca e na forma de número de milissegundos desde a última batida. Antes de plotar os dados, calculo o número de milissegundos da primeira amostra e o bpm (batimentos por minuto) em cada ponto de dados (60000 / vezes na batida anterior).

Eu quero visualizar os dados, ou seja, plotá-los em um gráfico de linhas. Eu quero reduzir o número de pontos no gráfico de milhares para algumas centenas.

Uma opção seria calcular a média de bpm para cada segundo da série, ou talvez a cada 5 segundos. Isso teria sido bem fácil se eu soubesse que teria pelo menos uma amostra para cada um desses períodos (segundos de intervalos de 5 segundos).

Rob Hyndman
fonte
Esqueci o seguinte: os pontos ao longo do eixo x vêm com espaçamento variável.
Não sei se entendi. Você não tem um eixo y?
Ah desculpa. Eu distorci. Agora eu mudei acima.
Eu também acho que você precisa fornecer um pouco mais de informação. Por exemplo, ainda não consigo visualizar o gráfico. Qual é o teu objetivo?
Ok desculpe. Eu adicionei mais alguns detalhes acima.

Respostas:

10

Você tem dois problemas: muitos pontos e como suavizar os pontos restantes.

Diluindo sua amostra

Se você tiver muitas observações chegando em tempo real, sempre poderá usar amostragem aleatória simples para afinar sua amostra. Observe que, para que isso também seja verdade, o número de pontos teria que ser muito grande.

Suponha que você tenha N pontos e deseje apenas n deles. Em seguida, gere n números aleatórios a partir de uma distribuição uniforme discreta U (0, N-1) . Esses seriam os pontos que você usa.

Se você quiser fazer isso sequencialmente, ou seja, em cada ponto que você decidir usá-lo ou não, aceite apenas um ponto com probabilidade p . Portanto, se você definir p = 0,01 , aceitaria (em média) 1 ponto em cem.

Se seus dados estiverem dispersos de maneira desigual e você desejar apenas reduzir regiões densas de pontos, apenas torne sua função de desbaste um pouco mais sofisticada. Por exemplo, em vez de p , que tal:

1pexp(λt)

onde é um número positivo é o tempo desde a última observação. Se o tempo entre dois pontos for grande, ou seja , grande , a probabilidade de aceitar um ponto será uma. Por outro lado, se dois pontos estiverem próximos, a probabilidade de aceitar um ponto será .λtt1p

Você terá que experimentar com os valores de e .λp

Suavização

Possivelmente algo como um esquema de tipo de média móvel simples. Ou você pode optar por algo mais avançado, como um kernel mais suave (como outros sugeriram). Você precisará tomar cuidado para não suavizar demais, pois presumo que uma queda repentina deve ser percebida muito rapidamente em seu cenário.

Deve haver bibliotecas C # disponíveis para esse tipo de coisa.

Conclusão

Dilua, se necessário, e depois alise.

csgillespie
fonte
Ah, interessante, mas preciso que seja previsível, ou seja, ter o mesmo resultado cada vez que visualizo os dados.
Nesse caso, gere os n índices dos pontos que você escolher e armazene esses índices.
csgillespie
Ou armazene a semente no RNG antes da amostragem.
Dirk Eddelbuettel
A solução de Dirk sobre a semente é provavelmente a melhor opção.
csgillespie
O cálculo das médias por cada segundo é bom, mas o que faço quando não há dados para um segundo específico. Eu acho que eu poderia fazer alguma interpolação dos segundos antes e depois, mas seria ótimo com algum método específico (nomeado) para isso, para não tentar inventar algo já inventado.
9

Bem, acho que a palavra que você procura é "amostragem", mas não sei por que você deseja fazer isso. Milhares de pontos de dados não são muitos. Ou você está olhando apenas para plotar um número menor de pontos igualmente espaçados? Isso geralmente é chamado de "binning".

Seu objetivo é gerar uma visualização? Nesse caso, convém manter os dados brutos, plotá-los como um gráfico de dispersão e sobrepor algum tipo de tendência central (linha de regressão, spline, qualquer que seja) para comunicar qualquer que seja a mensagem do takehome.

Ou seu objetivo é resumir numericamente os resultados de alguma forma? Nesse caso, convém explicar seu problema com mais detalhes!

Harlan
fonte
Sim, visualização é o que eu quero. Eu adicionei mais algumas informações na pergunta.
secundando plotando dados brutos com uma linha de suavização.
JoFrhwld
sedento plotando dados brutos com uma linha de suavização --- Você também pode plotar a alteração no BPM ao longo do tempo como uma visualização separada.
John
5

Calcular médias leva a um conjunto de dados diferente do que simplesmente reduzir o número de pontos de dados. Se um batimento cardíaco por minuto for muito mais rápido que o outro, você perderá o sinal durante o processo de suavização.

Se você resumir 125-125-0-125-125 como 100, a história contada pelos dados será diferente através da suavização.

Às vezes, o coração pula até as batidas e acredito que esse é um evento interessante, mas que deseja analisar os dados de freqüência cardíaca plotados.

Portanto, proponho que você calcule a distância entre dois pontos com uma fórmula como d=sqrt((time1-time2)^2 + (bpm1-bpm2)).

Você define uma distância mínima no seu programa. Em seguida, você repete os dados e, após cada ponto, exclui todos os seguintes pontos para os quais d é menor que a sua distância mínima.

Como a unidade de tempo e bpm não é a mesma, convém pensar em como encontrar uma maneira de dimensionar as unidades de maneira significativa. Para fazer essa tarefa corretamente, você deve conversar com os médicos que, no final, precisam interpretar seus gráficos e perguntar quais informações eles consideram essenciais.

cristão
fonte
Postagem interessante. Também vou investigar isso. Você provavelmente está certo.
2

Se o BPM permanecer o mesmo em muitas amostras (ou mudar infinitamente de uma maneira que você não está preocupado), você poderá truncar seus dados para um dígito significativo com o qual realmente se importa e executar a Codificação de Comprimento de Execução.

Por exemplo, em R estes dados:

0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

tem essa saída

rle(data)
Run Length Encoding
  lengths: int [1:3] 10 15 15
  values : num [1:3] 0 1 2
russellpierce
fonte
1

Você não está fornecendo informações suficientes. Por que você deseja reduzir os pontos de dados. Alguns milhares não são nada hoje em dia.

Como você deseja o mesmo resultado sempre que visualiza os mesmos dados, talvez deseje simplesmente classificar médias. Você tem espaçamento variável no seu eixo x. Talvez você esteja tentando tornar isso consistente? Nesse caso, você definiria uma largura de compartimento de talvez 50 ms ou 100 e, em seguida, calcularia a média de todos os pontos. Aumente a largura da bandeja, conforme necessário, para reduzir os pontos de dados ao tamanho do conjunto desejado.

É realmente uma pergunta difícil de responder sem uma razão para você estar se livrando dos dados.

John
fonte
Ok desculpe. Eu adicionei mais alguns detalhes acima.
1

Para reduzir seus pontos de dados, você pode usar o algoritmo de Ramer-Douglas-Peucker, que é muito fácil de entender e implementar. O sinal amostrado será muito semelhante ao sinal original.

Kamran Bigdely
fonte