web-dev-qa-db-ja.com

sklearnのSGDClassifierを使用してトップ3またはトップNの予測を取得する方法

_from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
from sklearn import linear_model
arr=['dogs cats lions','Apple pineapple orange','water fire earth air', 'sodium potassium calcium']
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(arr)
feature_names = vectorizer.get_feature_names()
Y = ['animals', 'fruits', 'elements','chemicals']
T=["eating Apple roasted in fire and enjoying fresh air"]
test = vectorizer.transform(T)
clf = linear_model.SGDClassifier(loss='log')
clf.fit(X,Y)
x=clf.predict(test)
#prints: elements
_

上記のコードでは、clf.predict()list Xからのサンプルに対して1つの最良の予測のみを出力します。 リストXの特定のサンプルについて上位3つの予測に興味があります。関数_predict_proba_/_predict_log_proba_がすべてのリストを返すことを知っていますリストYの各機能の確率ですが、上位3つの結果を取得する前に、リストYの機能を並べ替えて関連付ける必要があります。直接的で効率的な方法はありますか?

14
Pranay Mathur

組み込み関数はありませんが、何が問題になっていますか

probs = clf.predict_proba(test)
best_n = np.argsort(probs, axis=1)[-n:]

コメントの1つで示唆されているように、[-n:][:,-n:]に変更する必要があります

probs = clf.predict_proba(test)
best_n = np.argsort(probs, axis=1)[:,-n:]
15
Andreas Mueller

私はこれが答えられたことを知っています...しかし私はもう少し追加することができます...

#both preds and truths are same shape m by n (m is number of predictions and n is number of classes)
def top_n_accuracy(preds, truths, n):
    best_n = np.argsort(preds, axis=1)[:,-n:]
    ts = np.argmax(truths, axis=1)
    successes = 0
    for i in range(ts.shape[0]):
      if ts[i] in best_n[i,:]:
        successes += 1
    return float(successes)/ts.shape[0]

速くて汚いですが、便利だと思います。独自のエラーチェックなどを追加できます。

8
user1269942

うまくいけば、 Andreas がこれに役立つでしょう。 loss = 'hinge'の場合、predict_probsは使用できません。 loss = 'hinge'のときにトップnクラスを取得するには、次のようにします。

calibrated_clf = CalibratedClassifierCV(clfSDG, cv=3, method='sigmoid')
model = calibrated_clf.fit(train.data, train.label)

probs = model.predict_proba(test_data)
sorted( Zip( calibrated_clf.classes_, probs[0] ), key=lambda x:x[1] )[-n:]

ClfSDG.predictとcalibrated_clf.predictが常に同じクラスを予測するかどうかはわかりません。

5
valearner