修改: 提供更好解决方案的两件事: 1)使目标函数返回绝对值。 2)将方法从“绑定”更改为“金色”。
我在使用Scipy的最小化方法“ minimize_scalar”时遇到麻烦。 该方法未找到最小值,同时报告说已找到解决方案。该解决方案不满足收敛极限。
下面遵循完整的示例代码来说明问题。
# Import modules
import pandas as pd
import numpy as np
from scipy.optimize import minimize_scalar # Optmimizer
# Construct data
np.random.seed(1)
observations = 200
columns = ['colA', 'colB', 'colC']
df= pd.DataFrame(columns=columns)
for i in range(observations):
df.loc[i] = 'colA%d'%i, np.abs(np.asscalar(.6*np.random.randn(1))), \
np.abs(np.asscalar(2.5*np.random.randn(1)))
df.head()
给出
colA colB colC
0 colA0 0.974607 1.529391
1 colA1 0.316903 2.682422
2 colA2 0.519245 5.753847
3 colA3 1.046887 1.903017
4 colA4 0.191423 0.623426
目标函数:
def objectFunction(colBRightLimit, colBLeftLimit,
data,
wantedShare):
"""
Calculates column share for given lower and upper limits for the values
in the column.
"""
wantedIndices = (data["colB"] >= colBLeftLimit) & \
(data["colB"] < colBRightLimit)
wantedRows = data[wantedIndices]
numberOfObservationsInColumn = len(wantedRows)
columnShare = numberOfObservationsInColumn/len(data)
differenceFromWantedShares = columnShare - wantedShare
return differenceFromWantedShares
优化
wantedColumnShare = 0.1
colBLeftLimit = 0
tolerance = 1e-6
res = minimize_scalar(objectFunction,
method='bounded',
bounds=(np.min(df["colB"]), np.max(df["colB"])),
args=(colBLeftLimit, df, wantedColumnShare),
options={'xatol': tolerance})
#tol=tolerance)
optimalRightColBLimit = res.x
optimalRightColBLimit
哪个给
0.99999947848782
报告
res
给出
fun: -0.1
message: 'Solution found.'
nfev: 30
status: 0
success: True
x: 0.99999947848782
问题在于目标函数的值变为“ -0.1”,考虑到我们的容忍度,这应该是一个很小的数字。
有人知道为什么这行不通吗?