Я пытаюсь минимизировать функцию, определенную следующим образом:
utility(decision) = decision * (risk - cost)
, где переменные принимают следующую форму:
решение = двоичный массив
риск = массив чисел с плавающей запятой
стоимость = константа
Я знаю, что решение будет иметь вид:
решение = 1 если (риск > = порог)
решение = 0 в противном случае
Поэтому, чтобы свести к минимуму эту функцию, я могу предположить, что я преобразую утилиту функции в зависит только от этого порога. Мой прямой перевод на scipy следующий:
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} )
Это дает мне следующий результат:
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])
Однако я знаю, что результат неверный, потому что в этом случае он должен быть равен до стоимость . Кроме того, независимо от того, какой x0 я использую, он всегда возвращает его как результат. Глядя на результаты, я замечаю, что jacobian = 0 и неправильно вычисляет 1 итерацию.
Более подробное изучение функции. Я строю это и наблюдаю, что оно не выпукло в пределах границ, но мы можем ясно видеть минимум в 0.1. Однако независимо от того, насколько я настроил границы, чтобы они были только в выпуклой части, результат остается тем же.
Что я мог сделать минимизировать эту функцию?