scipy 'Minimizar a soma dos quadrados de um conjunto de equações'
Pergunta
Eu enfrento um problema no scipy 'leastsq' otimização de rotina, se eu executar o seguinte programa que diz
raise errors[info][1], errors[info][0]
TypeError: Improper input parameters.
e às vezes index out of range for an array
...
from scipy import *
import numpy
from scipy import optimize
from numpy import asarray
from math import *
def func(apar):
apar = numpy.asarray(apar)
x = apar[0]
y = apar[1]
eqn = abs(x-y)
return eqn
Init = numpy.asarray([20.0, 10.0])
x = optimize.leastsq(func, Init, full_output=0, col_deriv=0, factor=100, diag=None, warning=True)
print 'optimized parameters: ',x
print '******* The End ******'
Eu não sei qual é o problema com o meu func optimize.leastsq () chamada, por favor, ajuda-me
Solução
leastsq
trabalha com vetores para que a função residual, func
, precisa retornar um vetor de comprimento pelo menos dois. Então, se você substituir return eqn
com return [eqn, 0.]
, o seu exemplo vai funcionar. Executá-lo dá:
optimized parameters: (array([10., 10.]), 2)
que é uma das muitas respostas corretas para o mínimo da diferença absoluta.
Se você quiser minimizar uma função escalar, fmin
é o caminho a percorrer, optimize.fmin(func, Init)
.
A questão aqui é que estas duas funções, embora a mesma aparência por escalares são destinados a objetivos diferentes. leastsq
encontra o erro menos quadrado, geralmente a partir de um conjunto de curvas idealizadas, e é apenas uma maneira de fazer um "melhor ajuste". Por outro fmin
mão achar o valor mínimo de uma função escalar.
Obviamente seu é um exemplo de brinquedo, para o qual nenhuma delas realmente faz sentido, de modo que caminho você vai vai depender do que o seu objetivo final é.
Outras dicas
Desde que pretende minimizar uma função escalar simples (func()
retorna um único valor, não uma lista de valores), scipy.optimize.leastsq()
deve ser substituída por uma chamada para uma das funções fmin
(com os argumentos apropriados):
x = optimize.fmin(func, Init)
corretamente funciona!
Na verdade, leastsq()
minimiza a soma dos quadrados de uma lista de valores. Ela não aparece para trabalhar em um (lista contendo a) valor único, como no seu exemplo (mesmo que pudesse, em teoria).
Apenas olhando para o quadrados docs menos , pode ser que o seu func
função é definida incorretamente. Você está assumindo que você sempre recebe um conjunto de, pelo menos, comprimento 2, mas a função de otimizar é insanamente vago sobre o comprimento da matriz que você receberá. Você pode tentar escrever para a tela o que quer apar
é, para ver o que você está realmente recebendo.
Se você estiver usando algo como ipython
ou o shell python, você deve estar recebendo rastreamentos de pilha que mostram exatamente qual linha o erro está ocorrendo em, assim que começar lá. Se você não pode descobrir a partir daí, postando o rastreamento de pilha, provavelmente nos ajudar.