Я хочу понять, почему я получил разные оценки AU C со сбалансированными весами классов и нормализованными весами классов для 6-мультиклассовой классификации. Нормализованные веса - это просто мои рассчитанные веса классов, разделенные на сумму весов. Вес по каждому классу должен быть одинаковым с нормализацией или без нее. Вот мои расчеты:
from sklearn.utils import class_weight
k_train = class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
#original class weights
wt = dict(zip(np.unique(y_train), k_train))
wt
#normalized class weights
wt_norm = dict(zip(np.unique(y_train), k_train/k_train.sum()))
wt_norm
#weight relative to classes should be the same
list(wt.values())/wt[6]
list(wt_norm.values())/wt_norm[6]
Output:
{1: 0.5468164794007491,
2: 0.9931972789115646,
3: 0.8538011695906432,
4: 1.2478632478632479,
5: 1.1587301587301588,
6: 3.0416666666666665}
{1: 0.0697285449730655,
2: 0.12664980617556795,
3: 0.10887439478250578,
4: 0.1591241154513546,
5: 0.1477581072048293,
6: 0.38786503141267686}
array([0.17977528, 0.32653061, 0.28070175, 0.41025641, 0.38095238,
1. ])
array([0.17977528, 0.32653061, 0.28070175, 0.41025641, 0.38095238,
1. ])
Я также проверил, что мои вычисленные веса сбалансированного класса приводят к тому же баллу AU C, что и установка class_weight = 'сбалансированный' в классификаторе:
scoring = {'accuracy': make_scorer(accuracy_score),
'auc' : make_scorer(roc_auc_score, multi_class = 'ovr', average = 'macro', needs_proba=True),
'auc_wt' : make_scorer(roc_auc_score, multi_class = 'ovr', average = 'weighted', needs_proba=True),
'precision': make_scorer(precision_score, average = 'macro'),
'recall': make_scorer(recall_score, average = 'macro'),
'f1_macro': make_scorer(f1_score, average = 'macro')
}
for w, w_type in zip(['balanced', wt, wt_norm], ['balanced', 'calculated balanced', 'normalized']):
logistic = LogisticRegression(random_state=0, max_iter=1000, solver='saga', penalty='l2', multi_class='multinomial',
class_weight = w)
def pipeline(classifier_name, classifier):
imp = SimpleImputer(strategy = 'median')
scaler = MinMaxScaler()
return Pipeline(steps=[('impute', imp), ('scale', scaler), (classifier_name, classifier)], verbose=0)
pipe = pipeline('logistic', logistic)
grid_values = {'logistic__C': np.arange(1,11)} #np.logspace(-4, 3, 8)}
grid_lr = GridSearchCV(estimator = pipe, param_grid = grid_values,
scoring = scoring,
cv = 5, return_train_score=True,
n_jobs = -1, refit='auc')
grid_lr.fit(X_train, y_train)
print('Best AUC for {} class weights: {}'.format(w_type, grid_lr.best_score_))
print('Best Parameter for {} class weights: {}'.format(w_type, grid_lr.best_params_))
cv_results_ разные:
Best AU C для веса сбалансированного класса: 0,9993888888888888 Лучший параметр для сбалансированных весов классов: {'logistic __ C': 5}
Лучший AU C для расчетных весов сбалансированных классов: 0,9993888888888888 Лучший параметр для исходных весов классов: {'logistic __ C': 5}
Лучший AU C для нормализованных весов классов: 0,9994041950113377 Лучший параметр для нормализованных весов классов: {'logistic __ C': 1}
Мало того, что оценка AU C выше с нормализованными весами при перекрестной проверке, оценка также выше при прогнозировании на тесте установить (0,99609 против 0,99628). Есть мысли, почему разница?