如何使用sklearn的SGDClassifier获得前3或前N个预测

时间:2015-09-08 15:05:56

标签: python scikit-learn multilabel-classification

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()仅为列表X 中的样本打印了1个最佳预测。 我对列表X 中的特定样本的前3个预测感兴趣,我知道函数predict_proba / predict_log_proba返回所有列表列表Y 中每个要素的概率,但在获得前3个结果之前,必须对其进行排序,然后与列表Y中的要素相关联。 有没有直接有效的方法?

5 个答案:

答案 0 :(得分:3)

希望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是否总能预测同一类。

答案 1 :(得分:3)

我知道这已经得到了解答......但我可以多补充一点......

#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]

这很快又脏,但我发现它很有用。可以添加自己的错误检查等。

答案 2 :(得分:0)

wantedData = pd.DataFrame({'recipient > Full Name': {0: 'Norway', 1: 'Sweden'}, 'transporter > Full Name': {0: "UPS", 1: "Sweden Mail Services"}, 'Description': {0:'Priority mail', 1: 'Fragile object - be careful'}, 'recipient > Asset Type': {0: "Country", 1: "Country"}, 'recipient > Domain': {0: "Transport", 1: "Transport"}, 'transporter > Asset Type': {0: "Legal Enitity", 1: "Legal Entity"}, 'transporter > Domain': {0: "Transport", 1: "Transport"}}) 以升序给出结果,如果您想避免出现异常循环或混乱,可以使用一个简单的技巧。

argsort

否定概率将从最小变成最大,因此您可以按降序获得前n个结果。

答案 3 :(得分:0)

How do I get indices of N maximum values in a NumPy array?中所述的@FredFoo,更快的方法是使用argpartition

较新的NumPy版本(1.8及更高版本)具有称为argpartition的功能 为了这。要获取四个最大元素的索引,

>>> a = np.array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
>>> a array([9, 4, 4, 3, 3, 9, 0, 4, 6, 0])
>>> ind = np.argpartition(a, -4)[-4:]
>>> ind array([1, 5, 8, 0])
>>> a[ind] array([4, 9, 6, 9])

argsort不同,此函数在最坏的情况下以线性时间运行,但返回的索引不是 从评估a[ind]的结果可以看出,排序。如果你 也需要它,然后对它们进行排序:

>>> ind[np.argsort(a[ind])] array([1, 8, 5, 0]) 

以这种方式获得top-k元素的排序顺序需要O(n + k log k)时间。

答案 4 :(得分:0)

我编写了一个函数,该函数输出一个包含前 n 个预测及其概率的数据帧,并将其与类名联系起来。希望这对您有帮助!

def return_top_n_pred_prob_df(n, model, X_test, column_name):
  predictions = model.predict_proba(X_test)
  preds_idx = np.argsort(-predictions) 
  classes = pd.DataFrame(model.classes_, columns=['class_name'])
  classes.reset_index(inplace=True)
  top_n_preds = pd.DataFrame()
  for i in range(n):
        top_n_preds[column_name + '_prediction_{}_num'.format(i)] =     [preds_idx[doc][i] for doc in range(len(X_test))]
    top_n_preds[column_name + '_prediction_{}_probability'.format(i)] = [predictions[doc][preds_idx[doc][i]] for doc in range(len(X_test))]
    top_n_preds = top_n_preds.merge(classes, how='left', left_on= column_name + '_prediction_{}_num'.format(i), right_on='index')
    top_n_preds = top_n_preds.rename(columns={'class_name': column_name + '_prediction_{}'.format(i)})
    try: top_n_preds.drop(columns=['index', column_name + '_prediction_{}_num'.format(i)], inplace=True) 
    except: pass
  return top_n_preds