Pergunta

Eu estou olhando para um não-linear ajuste da curva de rotina (e, provavelmente, mais provável de ser encontrado em R ou Python, mas estou aberto a outras línguas), o que levaria x,y de dados e ajuste de uma curva a ele.

Eu deveria ser capaz de especificar uma cadeia de caracteres com o tipo de expressão que deseja ajustar.

Exemplos:

"A+B*x+C*x*x"
"(A+B*x+C*x*x)/(D*x+E*x*x)"
"sin(A+B*x)*exp(C+D*x)+E+F*x"

O que eu iria sair esta é, pelo menos, os valores para as constantes (A, B, C, etc.) E espero que as estatísticas sobre a adequação do jogo.

Existem programas comerciais para fazer isso, mas eu esperava ser capaz de encontrar algo tão comum como o encaixe desejado expressão em uma biblioteca de idioma nos dias de hoje.Eu suspeito que SciPy otimização do material pode ser capaz de fazer isso, mas eu não posso ver o que me permite definir uma equação.Da mesma forma, eu não consigo encontrar exatamente o que eu quero em R.

É o que eu estou olhando para fora de lá, ou eu preciso rolar para o meu próprio?Eu odeio fazer isso, se ele está lá e eu só estou tendo problemas para encontrá-lo.


Editar:Eu quero fazer isso por um pouco mais de controle sobre o processo que eu recebo do LAB Fit.O LAB de Ajuste de INTERFACE do usuário é terrível.Eu também gostaria de ser capaz de quebrar o intervalo em vários pedaços e têm diferentes curvas representam as diferentes partes de intervalo.No final, o resultado tem de ser capaz de (velocidade-wise) bater uma LUT com interpolação linear ou eu não estou interessado.

Na minha atual conjunto de problemas, eu tenho funções trigonométricas ou exp() e eu preciso executá-los 352,800 vezes por segundo em tempo real (e usar apenas uma fracção da CPU).Então eu plotar a curva e usar os dados para a unidade a curva mais apto a obter menos caro aproximações.Nos velhos tempos, LUTs foram, quase sempre, a solução, mas hoje em dia inutilizar a memória de pesquisas e fazendo uma aproximação, às vezes, é mais rápido.

Foi útil?

Solução

Para responder a sua pergunta em um sentido geral (sobre estimativa de parâmetros em R) sem considerar as especificidades das equações que você apontou, eu acho que você está procurando nls() ou optim()...'nls' é minha primeira opção, pois fornece as estimativas de erro para cada parâmetro estimado e quando ele falha, eu uso 'ot'.Se você tem o seu x,y variáveis:

out <- tryCatch(nls( y ~ A+B*x+C*x*x, data = data.frame(x,y), 
                start = c(A=0,B=1,C=1) ) ,
                error=function(e) 
                optim( c(A=0,B=1,C=1), function(p,x,y)  
                      sum((y-with(as.list(p),A + B*x + C*x^2))^2), x=x, y=y) )

para obter os coeficientes, algo como

getcoef <- function(x) if(class(x)=="nls") coef(x) else x$par
getcoef(out)

Se você deseja o padrão de erros no caso de 'nls',

summary(out)$parameters

Os arquivos de ajuda e r-help lista de discussão posts contêm muitas discussões em relação específica de minimização de algoritmos implementados por cada um (o padrão utilizado em cada caso de exemplo acima) e sua adequação para a forma específica da equação na mão.Certos algoritmos pode lidar com restrições de caixa, e outra função chamada constrOptim() irá lidar com um conjunto de restrições lineares.Este site também pode ajudar:

http://cran.r-project.org/web/views/Optimization.html

Outras dicas

Seu primeiro modelo é realmente linear nos três parâmetros e pode ser adequado em r usando

 fit <- lm(y ~ x + I(x^2), data=X)

o que lhe dará seus três parâmetros.

O segundo modelo também pode ser adequado usando nls() em r com as advertências usuais de ter que fornecer valores iniciais etc. o Estatística Questões na otimização não são necessariamente as mesmas que o numérico Problemas - Você não pode apenas otimizar qualquer formulário funcional, independentemente do idioma que você escolher.

Verificação de saída GNU oitava - Entre o solucionador poliFit () e o solucionador de restrições não lineares, deve ser possível construir algo adequado para o seu problema.

Em R, isso é bastante fácil.

O método embutido é chamado de otim (). É preciso como argumentos um vetor inicial de parâmetros em potencial, depois uma função. Você precisa criar sua própria função de erro, mas isso é realmente simples.

Então você chama isso como out = otim (1, err_fn)

onde err_fn está

err_fn = function(A) {
    diff = 0;
    for(i in 1:data_length){
      x = eckses[i];
      y = data[i];
      model_y = A*x;
      diff = diff + ( y - model_y )^2
    }
    return(diff);
}

Isso apenas pressupõe que você tenha um vetor de valores x e y em Ecks e dados. Altere a linha Model_Y, como você achar adequado, até adicione mais parâmetros.

Funciona bem no não -linear, eu o uso para curvas E^x quatro dimensionais e é muito rápido. Os dados de saída incluem o valor de erro no final do acessório, que é uma medida de quão bem ele se encaixa, dada como uma soma das diferenças quadradas (no meu err_fn).

Editar: se você precisar absorver o modelo como uma string, poderá fazer com que sua interface do usuário construa todo esse processo de ajuste de modelo como um script R e carregá -lo para executar. R pode receber texto do stdin ou de um arquivo, portanto, não deve ser muito difícil criar a string dessa função equivalente e fazer com que seja executado automaticamente.

Você provavelmente não encontrará uma única rotina com a flexibilidade implícita em seus exemplos (polinômios e funções racionais usando a mesma rotina), muito menos uma que analisará uma string para descobrir que tipo de equação caber.

Um ajustador polinomial de mínimos quadrados seria apropriado para o seu primeiro exemplo. (Cabe a você que grau polinômio de usar - quadrado, cúbico, quartico etc.). Para uma função racional como o seu segundo exemplo, talvez seja necessário "rolar o seu próprio" se não conseguir encontrar uma biblioteca adequada. Além disso, lembre-se de que um polinômio suficientemente alto pode ser usado para aproximar sua função "real", desde que você não precise extrapolar além dos limites do conjunto de dados que você está se encaixando.

Como outros observaram, existem outros algoritmos de estimativa de parâmetros mais generalizados que também podem ser úteis. Mas esses algoritmos não são "plug and play": eles geralmente exigem que você escreva algumas rotinas auxiliares e forneça uma lista de valores iniciais para os parâmetros do modelo. É possível que esses tipos de algoritmos divergem ou fiquem presos no mínimo ou no máximo local para uma escolha infeliz das estimativas iniciais dos parâmetros.

Se você tem restrições aos seus coeficientes e sabe que existe um tipo específico de função que deseja se encaixar nos seus dados e essa função é uma bagunça, onde métodos de regressão padrão ou outros métodos de ajuste de curva não funcionam, tenha Você considerou algoritmos genéticos?

Eles não são minha primeira escolha, mas se você estiver tentando encontrar os coeficientes da segunda função que você mencionou, talvez o gás funcione-especialmente se você estiver usando métricas não padrão para avaliar o melhor ajuste. Por exemplo, se você quiser encontrar os coeficientes de "(a+bx+cx^2)/(dx+ex^2)" de modo que a soma das diferenças quadradas entre sua função e dados seja mínima e Que haja alguma restrição no comprimento da função resultante, um algoritmo estocástico pode ser uma boa maneira de abordar isso.

Algumas advertências: 1) algoritmos estocásticos não garantem o melhor solução, mas eles geralmente serão muito próximos. 2) Você deve ter cuidado com a estabilidade do algoritmo.

Em uma nota mais longa, se você estiver no estágio em que deseja encontrar uma função de algum espaço de funções que melhor se encaixem nos seus dados (por exemplo, você não vai impor, digamos, o segundo modelo em seus dados), então genético Técnicas de programação também podem ajudar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top