scipy minimizeについて
解決したいこと
scipyのminimizeを使って,閾値の最適化問題をときたいと思っていますが,制約条件がうまく機能していません.
PrecisionとRecallに基づいた最適化です.
具体的には,
Recallが0.9以上の制約条件のもとでPrecisionが最大となる閾値を得たいです.
条件設定にて最適な閾値が0.3となる仮想の問題を設定してみたのですが,
以下に示すように,初期値の閾値(0.5)を出力してしまいます.
なお,こちらのサイトのコードを参考にさせていただきました.
https://www.sairablog.com/article/scipy-minimize-threshold-optimization.html
ご協力いただけないでしょうか.
該当するソースコード
from scipy.optimize import minimize
import numpy as np
from sklearn.metrics import accuracy_score, precision_score,recall_score
y_test=np.array([1,1,1,1,0,0,0,0])
y_prob=np.array([0.3,0.4,0.6,0.7,0.2,0.1,0.25,0.28])
# 目的関数
def func(threshhold):
global y_test,y_prob
return -precision_score(y_test,y_prob>=threshhold)
# 制約条件式
def cons1(threshhold):
global y_test,y_prob
recall=recall_score(y_test,y_prob>=threshhold)
return (recall-0.9)
# 制約条件式が非負となるようにする
cons = (
{'type': 'ineq', 'fun': cons1},
# {'type': 'ineq', 'fun': cons2}
)
x=np.array([0.5])
result = minimize(func, constraints=cons,x0=x,method='Nelder-Mead')
print(result)
# 結果の閾値は0.5
print(precision_score(y_test,y_prob>=0.5))
print(recall_score(y_test,y_prob>=0.5))
# 理想の閾値は0.3
print(precision_score(y_test,y_prob>=0.3))
print(recall_score(y_test,y_prob>=0.3))
結果)
fun: -1.0
jac: array([0.])
message: 'Positive directional derivative for linesearch'
nfev: 3
nit: 5
njev: 1
status: 8
success: False
x: array([0.5])
0.5
1.0
1.0
1.0
0 likes