sklearn использовать RandomizedSearchCV с пользовательскими метриками и ловить исключения - PullRequest
0 голосов
/ 10 декабря 2018

Я использую функцию RandomizedSearchCV в sklearn с классификатором Random Forest.Чтобы увидеть различные метрики, я использую пользовательскую оценку

from sklearn.metrics import make_scorer, roc_auc_score, recall_score, matthews_corrcoef, balanced_accuracy_score, accuracy_score

acc = make_scorer(accuracy_score)

auc_score = make_scorer(roc_auc_score)
recall = make_scorer(recall_score)
mcc = make_scorer(matthews_corrcoef)
bal_acc = make_scorer(balanced_accuracy_score)

scoring = {"roc_auc_score": auc_score, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }

. Эти пользовательские счетчики используются для рандомизированного поиска

rf_random = RandomizedSearchCV(estimator=rf, param_distributions=random_grid, n_iter=100, cv=split, verbose=2,
                               random_state=42, n_jobs=-1, error_score=np.nan, scoring = scoring, iid = True, refit="roc_auc_score")

Теперь проблема в том, что я использую пользовательские разбиения,AUC выдает исключение, потому что для этого точного разбиения существует только одна метка класса.

Я не хочу менять разбиения, следовательно, есть ли возможность перехватить эти исключения в функциях RandomizedSearchCV или make_scorer?Например, если одна из метрик не рассчитана (из-за исключения), просто добавьте NaN и переходите к следующей модели.

Редактировать: очевидно, error_score исключает обучение модели, но не вычисление метрики.Если я использую, например, Точность, все работает, и я просто получаю предупреждения в сгибах, где у меня есть только одна метка класса.Если я использую, например, AUC в качестве метрики, я по-прежнему получаю исключения.

Было бы здорово получить некоторые идеи здесь!

Решение: Определить пользовательский секретарь с исключением:

def custom_scorer(y_true, y_pred, actual_scorer):
score = np.nan

try:
  score = actual_scorer(y_true, y_pred)
except ValueError: 
  pass

return score

Это приводит к новой метрике:

acc = make_scorer(accuracy_score)
recall = make_scorer(custom_scorer, actual_scorer=recall_score)
new_auc = make_scorer(custom_scorer, actual_scorer=roc_auc_score)
mcc = make_scorer(custom_scorer, actual_scorer=matthews_corrcoef)
bal_acc = make_scorer(custom_scorer,actual_scorer=balanced_accuracy_score)

scoring = {"roc_auc_score": new_auc, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }

, которая, в свою очередь, может быть передана параметру скоринга RandomizedSearchCV

Второе найденное мной решение:

def custom_auc(clf, X, y_true):
score = np.nan
y_pred = clf.predict_proba(X)
try:
    score = roc_auc_score(y_true, y_pred[:, 1])
except Exception:
    pass

return score

, который также может быть передан в аргумент оценки:

scoring = {"roc_auc_score": custom_auc, "recall": recall, "MCC" : mcc, 'Bal_acc' : bal_acc, "Accuracy": acc }

(Адаптировано с этот ответ )

1 Ответ

0 голосов
/ 10 декабря 2018

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

def custom_scorer(y_true, y_pred, actual_scorer):
    score = np.nan

    try:
      score = actual_scorer(y_true, y_pred)
    except Exception: 
      pass

    return score

Затем вы можете вызвать это, используя:

acc = make_scorer(custom_scorer, actual_scorer = accuracy_score)
auc_score = make_scorer(custom_scorer, actual_scorer = roc_auc_score, 
                        needs_threshold=True) # <== Added this to get correct roc
recall = make_scorer(custom_scorer, actual_scorer = recall_score)
mcc = make_scorer(custom_scorer, actual_scorer = matthews_corrcoef)
bal_acc = make_scorer(custom_scorer, actual_scorer = balanced_accuracy_score)

Пример для воспроизведения:

import numpy as np
def custom_scorer(y_true, y_pred, actual_scorer):
    score = np.nan

    try:
      score = actual_scorer(y_true, y_pred)
    except Exception: 
      pass

    return score


from sklearn.metrics import make_scorer, roc_auc_score, accuracy_score
acc = make_scorer(custom_scorer, actual_scorer = accuracy_score)
auc_score = make_scorer(custom_scorer, actual_scorer = roc_auc_score, 
                        needs_threshold=True) # <== Added this to get correct roc

from sklearn.datasets import load_iris
X, y = load_iris().data, load_iris().target

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV, KFold
cvv = KFold(3)
params={'criterion':['gini', 'entropy']}
gc = GridSearchCV(DecisionTreeClassifier(), param_grid=params, cv =cvv, 
                  scoring={"roc_auc": auc_score, "accuracy": acc}, 
                  refit="roc_auc", n_jobs=-1, 
                  return_train_score = True, iid=False)
gc.fit(X, y)
print(gc.cv_results_)
...