scipy的问题最小化

时间:2017-11-26 22:51:14

标签: python numpy

我从scipy最小化收到以下错误。

RuntimeWarning: overflow encountered in double_scalars
  inner = x[k]*((x[0]**int(cAnde[ses][sub][strats][0]))*(1.0-x[0])**int(cAnde[ses][sub][strats][1]))
Traceback (most recent call last):
  File "MLEestimation.py", line 39, in ,module.
     constraints=MLEfunction.MLEconstrain(x), method = 'SLSQP', options = {'disp': True})
  File "C:\ProgramData\Anaconda2\lib\site-packages\scipy\optimize\_minimize.py", line 458, in minimize
     constraints, callback=callback, **options)
  File "C:\ProgramData\Anaconda2\lib\site-packages\scipy\optimize\slsqp.py", line 370 in _minimize_slsqp
      raise ValueError("Objective function must return a scalar")
   ValueError: Objective function must return a scalar

但是,当我使用np.isscalar检查目标函数的输出是否是标量时,我知道它是,所以我不确定我做错了什么。以下是所有参考代码。

import math
import pickle
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy.optimize import minimize
import MLEfunction

x = [0.9,0.2,0.1,0.2,0.1,0.2,0.2]

def MLE(x, cAnde):
    est = 0.0
    for ses in cAnde:
        for sub in cAnde[ses]:
            k = 0
            for strats in cAnde[ses][sub]:
                k += 1
                inner = x[k] * x[0] ** int(cAnde[ses][sub][strats][0]) \
                    * (1.0 - x[0]) ** int(cAnde[ses][sub][strats][1])
                est += math.log(inner)
    est = -1.0 * est
    return est


def MLE_deriv(x, cAnde):
    der = np.zeros_like(x)
    d0 = 0
    for ses in cAnde:
        for sub in cAnde[ses]:
            for strat in cAnde[ses][sub]:
                inner = float(cAnde[ses][sub][strat][0]) / x[0]
                inner += float(cAnde[ses][sub][strat][1]) / (1 - x[0])
                d0 += inner
    der[0] = -1.0 * d0
    for k in range(len(x) - 1):
        d = 0
        for ses in cAnde:
            for sub in cAnde[ses]:
                d += 1.0 / x[k + 1]
        der[k + 1] = -1.0 * d
    return der


def MLEconstraint(x):
    cons = []
    jacs = []
    for j in range(len(x)):
        if j == 0:
            jacs.append(0.0)
        else:
            jacs.append(1.0)
    sum1 = {'type': 'eq', 'fun': lambda x: np.array([sum(x[1:]) - 1]),
            'jac': lambda x: np.array(jacs)}
    cons.append(sum1)
    for k in range(len(x)):
        jacu = []
        jacd = []
        for l in range(len(x)):
            if l == k:
                jacu.append(-1.0)
                jacd.append(1.0)
            else:
                jacu.append(0.0)
                jacd.append(0.0)
        up = {'type': 'ineq', 'fun': lambda x: np.array([1 - x[k]]),
              'jac': lambda x: np.array(jacu)}
        low = {'type': 'ineq', 'fun': lambda x: np.array([x[k]]),
               'jac': lambda x: np.array(jacd)}
        cons.append(up)
        cons.append(low)
    return tuple(cons)


res = minimize(
    MLEfunction.MLE,
    x,
    args=CEs['48,0.75'],
    jac=MLEfunction.MLE_deriv,
    constraints=MLEfunction.MLEconstraint(x),
    method='SLSQP',
    options={'disp': True},
    )

print res.x

注意:最小化是在与定义函数不同的.py文件中完成的,我正在导入定义函数的原始文件

0 个答案:

没有答案