Qual é uma maneira robusta de ajustar dados lineares, porém barulhentos, por partes?
Estou medindo um sinal, que consiste em vários segmentos quase lineares. Eu gostaria de ajustar automaticamente várias linhas aos dados para detectar as transições.
O conjunto de dados consiste em alguns milhares de pontos, com 1 a 10 segmentos e eu sei o número de segmentos.
Este é um exemplo do que eu gostaria de fazer automaticamente.
algorithms
P3trus
fonte
fonte
Respostas:
Eu tentei duas abordagens, ingenuamente (usando apenas 3 segmentos). Certamente haveria métodos mais sofisticados por aí.
RANSAC, deveria ser um mecanismo de encaixe robusto. É fácil interromper o algoritmo após vários segmentos. No entanto, pode ser difícil impor a continuidade entre segmentos - como parece necessário no seu aplicativo - pelo menos com uma implementação simples. Como prova de conceito, criei uma imagem a partir dos pontos de dados para poder usar o mecanismo RANSAC disponível no , a função de detecção de linha do Mathematica.Eum a ge L i n e s
Ajuste um modelo linear por partes usando um minimizador de uso geral. É fácil impor a continuidade dos segmentos. Curiosamente, o teste de resíduos e outras propriedades pode fornecer informações suficientes para determinar automaticamente o número de segmentos - eu ainda não tentei. É assim que parece no Mathematica:
fonte
Não afirmo que o método a seguir seja robusto, mas pode funcionar para você. Com milhares de pontos e talvez dez ou mais segmentos retos, faça o seguinte.x [ n ]
Processe os pontos para criar uma matriz de bits seguinte maneira. Aqui é um pequeno número escolhido para se adequar à sua noção de quão perto de uma linha reta você deseja pontos para cortar para. O critério será reconhecido pelos cognoscentos como exigindo que a linha reta através de e possua quase a mesma inclinação que a linha reta através de e .x [ n ] y[ n ]
Se é uma matriz de dez ou corre tão alongados de s separados por corridas de s com vadios ocasional s aqui e ali para estragar a beleza, relaxe, você está no caminho certo. Caso contrário, se houver poucas execuções ou muitas execuções de s, repita a etapa anterior com um diferente .1 0 1 1 ϵy[n] 1 0 1 1 ϵ
fonte
(Anos mais tarde) as funções lineares por partes são splines de grau 1, que podem ser solicitadas à maioria dos instaladores de spline. scipy.interpolate.UnivariateSpline, por exemplo, pode ser executado com
k=1
um parâmetro de suavizaçãos
, com o qual você terá que brincar - consulte scipy-interpolation-with-univariate-splines .No Matlab, veja como escolher nós .
Adicionado: encontrar nós ótimos não é fácil, porque pode haver muitos ótimos locais. Em vez disso, você atribui ao UnivariateSpline um destino
s
, soma do erro ^ 2, e permite que ele determine o número de nós. Após o ajuste,get_residual()
obterá a soma real do erro ^ 2 eget_knots()
os nós. Uma pequena mudanças
pode mudar bastante os nós, especialmente em ruídos altos - sim.O gráfico mostra ajustes para uma função linear aleatória por partes + ruído para vários
s
.Para ajustar constantes por partes, consulte Detecção de etapas . Isso pode ser usado para pw linear? Não sei; começar por diferenciar dados ruidosos aumentará o ruído errado.
Outras funções de teste e / ou links para documentos ou códigos seriam bem-vindos. Alguns links:
Splines lineares são muito sensíveis a onde os nós são colocados
Este é um problema complicado e a maioria das pessoas apenas seleciona os nós por tentativa e erro.
Uma abordagem que está crescendo em popularidade é usar splines de regressão penalizados.
regressão linear por partes com nós como parâmetros
seleção de nó para splines de regressão cúbica
Adicionado em março de 2014: a programação dinâmica é um método geral para problemas com subproblemas aninhados como este:
A programação dinâmica é muito inteligente, mas pode vencer a força bruta + heurística para esta tarefa?
Veja as excelentes notas de curso de Erik Demaine no MIT 6.006. Introdução aos algoritmos e
também à regressão linear segmentada pelo Google e à
síndrome de John Henry.
fonte
Pegue a derivada e procure por áreas de valor quase constante. Você precisaria criar o algoritmo para procurar por áreas com idealmente algum nível de +/- inclinação e isso daria a inclinação da linha para essa seção. Você pode querer realizar alguma suavização, como uma média deslizante, antes de fazer a classificação secional. O próximo passo seria obter a interseção y, que deve ser trivial nesse ponto.
fonte
Usar um filtro de tendência l1 é outra ideia:
Papel
Exemplo Online
fonte