8

sklearn precision_recall_curve関数とmatplotlibパッケージを使用して精度と再現率の曲線を描きました。適合率-再現率曲線に精通している方は、この例のように、一部の科学コミュニティが補間された場合にのみそれを受け入れることを知っています。私の質問は、Pythonで補間を行う方法を知っている人がいるかどうかです。私はしばらくの間解決策を探していましたが、成功しませんでした! どんな助けでも大歓迎です。

解決策: @francis と @ali_m による両方の解決策は正しく、一緒に問題を解決しました。precision_recall_curveしたがって、 の関数から出力が得られると仮定するとsklearn、グラフをプロットするために私が行ったことは次のとおりです。

precision["micro"], recall["micro"], _ = precision_recall_curve(y_test.ravel(),scores.ravel())
pr = copy.deepcopy(precision[0])
rec = copy.deepcopy(recall[0])
prInv = np.fliplr([pr])[0]
recInv = np.fliplr([rec])[0]
j = rec.shape[0]-2
while j>=0:
    if prInv[j+1]>prInv[j]:
        prInv[j]=prInv[j+1]
    j=j-1
decreasing_max_precision = np.maximum.accumulate(prInv[::-1])[::-1]
plt.plot(recInv, decreasing_max_precision, marker= markers[mcounter], label=methodNames[countOfMethods]+': AUC={0:0.2f}'.format(average_precision[0]))

そして、これらの線を for ループに入れて各反復で各メソッドのデータを渡すと、補間された曲線がプロットされます。これは、補間されていない適合率-再現率曲線をプロットしないことに注意してください。

4

2 に答える 2

11

@francis のソリューションは、 を使用してベクトル化できますnp.maximum.accumulate

import numpy as np
import matplotlib.pyplot as plt

recall = np.linspace(0.0, 1.0, num=42)
precision = np.random.rand(42)*(1.-recall)

# take a running maximum over the reversed vector of precision values, reverse the
# result to match the order of the recall vector
decreasing_max_precision = np.maximum.accumulate(precision[::-1])[::-1]

プロットに使用されるループplt.stepを取り除くために使用することもできます。for

fig, ax = plt.subplots(1, 1)
ax.hold(True)
ax.plot(recall, precision, '--b')
ax.step(recall, decreasing_max_precision, '-r')

ここに画像の説明を入力

于 2016-10-04T21:44:27.007 に答える
4

後方反復を実行して、 の増加部分を削除できますprecision。次に、ベネット・ブラウンの回答で指定されているように、垂直線と水平線を matplotlibの垂直線と水平線にプロットできます。

サンプルコードは次のとおりです。

import numpy as np
import matplotlib.pyplot as plt

#just a dummy sample
recall=np.linspace(0.0,1.0,num=42)
precision=np.random.rand(42)*(1.-recall)
precision2=precision.copy()
i=recall.shape[0]-2

# interpolation...
while i>=0:
    if precision[i+1]>precision[i]:
        precision[i]=precision[i+1]
    i=i-1

# plotting...
fig, ax = plt.subplots()
for i in range(recall.shape[0]-1):
    ax.plot((recall[i],recall[i]),(precision[i],precision[i+1]),'k-',label='',color='red') #vertical
    ax.plot((recall[i],recall[i+1]),(precision[i+1],precision[i+1]),'k-',label='',color='red') #horizontal

ax.plot(recall,precision2,'k--',color='blue')
#ax.legend()
ax.set_xlabel("recall")
ax.set_ylabel("precision")
plt.savefig('fig.jpg')
fig.show()

そして、ここに結果があります:

ここに画像の説明を入力

于 2016-10-03T19:00:34.783 に答える