Estou explorando como modelar um conjunto de dados usando distribuições normais com média e variância definidas como funções lineares de variáveis independentes.
Algo como N ~ (f (x), g (x)).
Eu gero uma amostra aleatória como esta:
def draw(x):
return norm(5 * x + 2, 3 *x + 4).rvs(1)[0]
Então, eu quero recuperar 5, 2 e 4 como os parâmetros para minha distribuição.
Eu gero minha amostra:
smp = np.zeros ((100,2))
for i in range(0, len(smp)):
smp[i][0] = i
smp[i][1] = draw(i)
A função de probabilidade é:
def lh(p):
p_loc_b0 = p[0]
p_loc_b1 = p[1]
p_scl_b0 = p[2]
p_scl_b1 = p[3]
l = 1
for i in range(0, len(smp)):
x = smp[i][0]
y = smp[i][1]
l = l * norm(p_loc_b0 + p_loc_b1 * x, p_scl_b0 + p_scl_b1 * x).pdf(y)
return -l
Portanto, os parâmetros para as funções lineares usadas no modelo são dados no vetor variável de p 4.
Usando scipy.optimize, posso resolver os parâmetros do MLE usando um xtol extremamente baixo e já fornecendo a solução como ponto de partida:
fmin(lh, x0=[2,5,3,4], xtol=1e-35)
O que não funciona muito bem:
Warning: Maximum number of function evaluations has been exceeded.
array([ 3.27491346, 4.69237042, 5.70317719, 3.30395462])
Elevar o xtol a valores mais altos não é bom.
Então, eu tento usar uma solução inicial longe da solução real:
>>> fmin(lh, x0=[1,1,1,1], xtol=1e-8)
Optimization terminated successfully.
Current function value: -0.000000
Iterations: 24
Function evaluations: 143
array([ 1., 1., 1., 1.])
O que me faz pensar:
O PDF está amplamente agrupado em torno da média e possui gradientes muito baixos, apenas a alguns desvios padrão da média, o que não deve ser bom demais para métodos numéricos.
Então, como se faz esse tipo de estimativa numérica em funções em que o gradiente está muito próximo de zero da solução?