optimization - scipy-optimize-minimize does not perform the optimization - CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL
问题描述
I am trying to minimize a function defined as follows:
utility(decision) = decision * (risk - cost)
where variables take the following form:
decision = binary array
risk = array of floats
cost = constant
I know the solution will take the form of:
decision = 1 if (risk >= threshold)
decision = 0 otherwise
Therefore, in order to minimize this function I can assume that I transform the function utility to depend only on this threshold. My direct translation to scipy is the following:
def utility(threshold,risk,cost):
selection_list = [float(risk[i]) >= threshold for i in range(len(risk))]
v = np.array(risk.astype(float)) - cost
total_utility = np.dot(v, selection_list)
return -1.0*total_utility
result = minimize(fun=utility, x0=0.2, args=(r,c),bounds=[(0,1)], options={"disp":True} )
This gives me the following result:
fun: array([-17750.44298655]) hess_inv: <1x1 LbfgsInvHessProduct with
dtype=float64>
jac: array([0.])
message: b'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
nfev: 2
nit: 0 status: 0 success: True
x: array([0.2])
However, I know the result is wrong because in this case it must be equal to cost. On top of that, no matter what x0 I use, it always returns it as the result. Looking at the results I observe that jacobian=0 and does not compute 1 iteration correctly.
Looking more thoroughly into the function. I plot it and observe that it is not convex on the limits of the bounds but we can clearly see the minimum at 0.1. However, no matter how much I adjust the bounds to be in the convex part only, the result is still the same.
What could I do to minimize this function?
解决方案
错误消息告诉您梯度在某个点太小,因此在数值上等于零。这可能是由于您在计算selection_list
. 你说float(risk[i]) >= threshold
,它几乎到处都有导数 0 。因此,几乎每个起始值都会为您提供收到的警告。
一种解决方案可能是对阈值操作进行一些平滑处理。float(risk[i]) >= threshold
因此,您可以使用连续函数来代替:
def g(x):
return 1./(1+np.exp(-x))
使用此函数,您可以将阈值操作表示为
g((risk[i] - threshold)/a)
,其中一个参数a
。越大a
,这个修改后的误差函数就越接近你目前所做的。在类似的a=20
情况下,您可能会拥有与目前几乎相同的东西。因此,您将导出一系列解决方案,从 开始,a=1
然后将该解决方案作为与 相同的问题的起始值a=2
,将该解决方案作为与 的问题的起始值a=4
,依此类推。在某些时候,您会注意到更改a
不再更改解决方案,您就完成了。
推荐阅读
- python - 从列表中删除多个具有相同小时和分钟的词典?
- java - 伴随对象 Kotlin JNI 中的 UnsatisfiedLinkError
- java - HTML 5 datetime-local 到 spring mvc 并转换为毫秒
- c++ - 将低效的递归硬币找零函数转换为迭代
- ios - 在没有 CallKit UI 的情况下在最近通话中显示拨出电话
- javascript - 为什么 g 元素在 svg 之外渲染
- python - Python到Php使用http请求发布数据
- firefox - Selenium webdriver 打开默认的 Firefox 配置文件而不是预定义的配置文件
- unity3d - Unity Parent 的 SetActive() 会影响孩子吗?
- python - 如何从 Firebase 存储中下载 json 格式的数据?