scipy最小化功能有问题,它给我奇怪的结果

Dat*_*vid 4 python minimize scipy

创建了一个目标函数
添加了约束

问题是无论我使用什么初始猜测,最小化函数只是继续使用该数字.例如:如果我使用15作为初始猜测,求解器将不会尝试任何其他数字并且说答案是15.我确定ere是代码的问题,但我不确定在哪里.

代码如下:

from scipy.optimize import minimize
import numpy as np
from pandas import *

#----------------------------------------------------
#-------- Create Function ------------
#----------------------------------------------------
def MovingAverage(Input,N,test=0):

    # Create data frame
    df = DataFrame(Input, columns=['Revenue'])

    # Add columns
    df['CummSum'] = df['Revenue'].cumsum()
    df['Mavg'] = rolling_mean(df['Revenue'], N)
    df['Error'] = df['Revenue'] - df['Mavg']
    df['MFE'] = (df['Error']).mean()
    df['MAD'] = np.fabs(df['Error']).mean()
    df['MSE'] = np.sqrt(np.square(df['Error']).mean())
    df['TS'] = np.sum(df['Error'])/df['MAD']

    print N, df.MAD[0]

    if test == 0:
        return df.MAD[0]
    else: return df

#----------------------------------------------------
#-------- Input ------------
#----------------------------------------------------
data = [1,2,3,4,5,5,5,5,5,5,5,5,5,5,5]


#----------------------------------------------------
#-------- SOLVER ------------
#----------------------------------------------------

## Objective Function
fun = lambda x: MovingAverage(data, x[0])

## Contraints
cons = ({'type': 'ineq', 'fun': lambda x:  x[0] - 2}, # N>=2
        {'type': 'ineq', 'fun': lambda x:  len(data) - x[0]}) # N<=len(data)


## Bounds (note sure what this is yet)
bnds = (None,None)

## Solver
res = minimize(fun, 15, method='SLSQP', bounds=bnds, constraints=cons)

##print res
##print res.status
##print res.success
##print res.njev
##print res.nfev
##print res.fun
##for i in res.x:
##    print i
##print res.message
##for i in res.jac:
##    print i
##print res.nit

# print final results
result = MovingAverage(data,res.x,1)
print result
Run Code Online (Sandbox Code Playgroud)

可能值的列表:
2 = 0.142857142857,
3 = 0.25641025641,
4 = 0.333333333333,
5 = 0.363636363636,
6 = 0.333333333333,
7 = 0.31746031746,
8 = 0.3125,
9 = 0.31746031746,
10 = 0.333333333333,
11 = 0.363636363636,
12 = 0.416666666667,
13 = 0.487179487179,14
= 0.571428571429,15
= 0.666666666667

sil*_*ado 7

您的函数在整数输入值之间是分段常数,如下图所示(在x轴上以0.1为单位绘制):

功能图

因此,导数在几乎所有点都为零,这就是基于梯度的最小化方法将任何给定的初始点作为局部最小值返回的原因.

为了解决这种情况,您可以考虑在目标函数中使用插值来获取非整数输入值的中间函数值.如果将它与基于梯度的最小化相结合,它可能会在从15开始时找到8左右的局部最小值.