我有一个代码,可最大化61周每周数据的对数似然总和,此处忽略输入数据。
数学错误在这一行上:
x=x+(math.log(incre[i]))*(numb[i])
。但是,增量是伽玛威布尔分布的CDF差异的列表。基本上递增[i] = F [i] -F [i-1],因此肯定是正数。初始p0会产生很好的结果,但是当我尝试优化器时,它总是返回数学域或数学范围错误。
另外,有时我会遇到exp(bs*adjsale[i]+bx*adjchristmas[i]+ba*aba[i]))
的数学范围错误。删除* exp并加上“ +”号可以解决此问题,并且由于这里的exp仅是为了使后半部分为正数,因此这不是必须的,但是仍然存在日志问题。
我只是对scipy有点熟悉,所以我不确定问题出在哪里。我尝试了无济于事的其他方法。变量实际上没有上限,但我想使其更简单。
import scipy
from scipy import stats
from scipy.optimize import minimize
import math
from math import exp
import numpy as np
import pdb
import random
num=[3344,501,235,574,241,160 ,426 ,458 ,374 ,167, 106 , 75 ,62 , 67 , 75 , 72 , 102, 207 , 57 ,43 , 60, 59, 46, 40 , 135 , 47 , 43, 42, 43, 40 , 29 , 397 , 208 , 64 , 46 , 37 , 39 , 47 , 120 , 55, 50 , 40 , 32 , 44 , 48, 56 , 60 , 52 , 42 , 50 , 58 , 422 , 171 , 253 , 97 , 187, 115 , 72 , 63 , 416 , 324,88405]
sale=[0,0,0,5,0,0,5,7,4,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,4,1,0,0,7,6]
time=[]
for i in range(1,62):
time.append(i)
christmas=[0,0,0,0,0,0,5/7,1,4/7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,6/7]
ab=[]
for i in range(51):
ab.append(0)
def adjsale (sale,rs,ass):
adjs=[]
for i in range(61):
adjs.append((stats.gamma.cdf((i+1),a=rs,scale=ass))*sale[i])
return adjs
def adjchristmas(christmas,rs,ass):
adjsc=[]
for i in range(61):
adjsc.append((stats.gamma.cdf((i+1),a=rs,scale=ass))*christmas[i])
return adjsc
def aba(r2,a2):
global ab
ab.append((1-stats.gamma.cdf(4/7,a=r2,scale=a2))*4/7)
for i in range(10):
ab.append(1-stats.gamma.cdf(4/7+i+1, a=r2, scale=a2))
return ab
def bt(time,c, bs,bx,ba,adjsale,adjchristmas,aba):
newt=[1**c*math.exp(0)]
for i in range(1,61):
newt.append(newt[i-1]+((i+1)**c-i**c)*exp(bs*adjsale[i]+bx*adjchristmas[i]+ba*aba[i]))
return newt
def ft(newt,r,a):
cdft=[]
for i in range (61):
cdft.append(1-(a/(a+newt[i]))**r)
return cdft
def increment (cdft):
incre=[cdft[0]]
for i in range (60):
incre.append(cdft[i+1]-cdft[i])
incre.append(1-cdft[60])
return incre
def ll(numb, incre):
x=0
for i in range (62):
x=x+(math.log(incre[i]))*(numb[i])
return x
#parameters sequence: r, a, c, rs, as, rab, aab, bs, ba, bx
def objective(ps):
global ll,adjsale,adjchristmas,aba,bt,ft,increment,ll, sale,time,christmas,num
return -1*(ll(num,increment(ft(bt(time,ps[2],ps[7], ps[9], ps[8],adjsale(sale,ps[3],ps[4]),
adjchristmas(christmas,ps[3],ps[4]),aba(ps[5],ps[6])),ps[0],ps[1]))))
ps0=[1,1,0.3,1,1,1,1,1,1,1]
b=(0.000001,111111)
c=(0.000001, 0.56)
bnds=(b,b,c,b,b,b,b,b,b,b)
solution=minimize(objective, ps0, method="Powell", bounds=bnds)