使用scipy Minimize函数时遇到了麻烦,它给出了奇怪的结果。

4

创建了一个目标函数

添加约束条件

问题在于,无论我使用什么初始猜测,最小化函数都只会继续使用那个数字。例如:如果我使用15作为初始猜测,求解器将不会尝试任何其他数字,而是会说答案是15。我确定代码存在问题,但我不确定问题出在哪里。

以下是代码:

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

可能的值列表:
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。

首先调查您的 Lambda 函数:对于接近 15 的不同值,它返回什么?另外,请记住,除非优化函数具有某些有用的属性(如凸性),否则 minimize() 将无法找到全局最小值,而只能找到局部最小值。 - Bitwise
添加了可能值列表。 - DataByDavid
好的,你已经可以看到你的函数不是凸函数,因为它有多个局部最小值。 - Bitwise
从您添加的值来看,似乎fun(15)=0.666,那么minimize()如何返回15? - Bitwise
优化一个没有额外信息的一般函数是NP难问题。 - Bitwise
显示剩余2条评论
1个回答

7
你的函数在整数输入值之间是分段常数的,如下图所示(在x轴上以0.1为步长绘制): function plot 因此,在几乎所有点处导数都为零,这就是梯度下降最小化方法会将任何给定的初始点返回为局部最小值的原因。
为了解决这个问题,你可以考虑在目标函数中使用插值来获取非整数输入值的中间函数值。如果将其与基于梯度的最小化结合使用,当从15开始时,它可能会找到某个8附近的局部最小值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接