scipy.optimize python中的数学域错误

时间:2019-04-11 17:25:07

标签: python scipy

我有一个代码,可最大化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)


0 个答案:

没有答案