Scikit: вычислить точность и вспомнить, используя функцию cross val score

Я использую scikit для выполнения логистической регрессии на данные спама/ветчины. X_train - это мои данные обучения, а y_train-метки ("спам" или "ветчина"), и я обучил свою LogisticRegression следующим образом:

classifier = LogisticRegression()
classifier.fit(X_train, y_train)

если я хочу получить точность для 10-кратной перекрестной проверки, я просто пишу:

 accuracy = cross_val_score(classifier, X_train, y_train, cv=10)

Я думал, что можно вычислить также точность и отзыв, просто добавив один параметр таким образом:

precision = cross_val_score(classifier, X_train, y_train, cv=10, scoring='precision')
recall = cross_val_score(classifier, X_train, y_train, cv=10, scoring='recall')

но это приводит к ValueError:

ValueError: pos_label=1 is not a valid label: array(['ham', 'spam'], dtype='|S4') 

связано ли это с данными (должен ли я бинаризовать метки ?) или они меняют

4 ответов


для вычисления полнота и точность данных должна быть действительно бинаризован, таким образом:

from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
lb.fit(y_train)

чтобы пойти дальше, я был удивлен, что мне не пришлось бинаризовать данные, когда я хотел рассчитать точность:

accuracy = cross_val_score(classifier, X_train, y_train, cv=10)

это просто потому, что формула точности действительно не нуждается в информации о том, какой класс считается положительным или отрицательным: (TP + TN) / (TP + TN + FN + FP). Мы действительно видим, что TP и TN взаимозаменяемы, это не относится к напомним, точность и f1.


я столкнулся с той же проблемой здесь, и я решил ее с

# precision, recall and F1
from sklearn.preprocessing import LabelBinarizer

lb = LabelBinarizer()
y_train = np.array([number[0] for number in lb.fit_transform(y_train)])

recall = cross_val_score(classifier, X_train, y_train, cv=5, scoring='recall')
print('Recall', np.mean(recall), recall)
precision = cross_val_score(classifier, X_train, y_train, cv=5, scoring='precision')
print('Precision', np.mean(precision), precision)
f1 = cross_val_score(classifier, X_train, y_train, cv=5, scoring='f1')
print('F1', np.mean(f1), f1)

синтаксис, который вы показали выше, является правильным. Похоже, проблема с используемыми данными. Метки не нуждаются в бинаризации, если они не являются непрерывными числами.

вы можете доказать тот же синтаксис с другим набором данных:

iris = sklearn.dataset.load_iris()
X_train = iris['data']
y_train = iris['target']

classifier = LogisticRegression()
classifier.fit(X_train, y_train)

print cross_val_score(classifier, X_train, y_train, cv=10, scoring='precision')
print cross_val_score(classifier, X_train, y_train, cv=10, scoring='recall')

вы можете использовать перекрестную проверку, как это, чтобы получить оценку f1 и вспомнить:

print('10-fold cross validation:\n')
start_time = time()
scores = cross_validation.cross_val_score(clf, X,y, cv=10, scoring ='f1')
recall_score=cross_validation.cross_val_score(clf, X,y, cv=10, scoring ='recall')
print(label+" f1: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), 'DecisionTreeClassifier'))
print("---Classifier %s use %s seconds ---" %('DecisionTreeClassifier', (time() - start_time)))

для получения дополнительной оценки-параметр просто см. страница