Model regresji Logistyczne. Część 4: Zastosowanie class_weight

Zastosowanie class_weight jest sposobem na poprawę wskaźnika recall w zbiorach wyników wysoko niezbilansowanych. Podniesienie wskaźnika recall wiąże się ze spadkiem poziomu wskaźnika precision.

W poprzednich częściach omówiliśmy jak przygotowywać dane i jak tworzyć model regresji logistycznej. Mówiliśmy również o tym, w jaki sposób zmienić ilość danych, tak aby zmniejszyć wpływ niezbilansowania w zbiorze treningowym podczas tworzenia modelu regresji logistycznej.

Wcześniejsze części można znaleźć pod tymi adresami:

Przykład Modelu Regresji Logistycznej. Część 1: model podstawowy

Model Regresji Logistycznej. Część 2: Oversampling

Model Regresji Logistycznej. Część 3: zmiana progu w modelu regresji logistycznej

Zastosowanie class_weight

Wspominaliśmy we wcześniejszych wpisach, że zbiór zmiennych zależnych jest wysoko niezbilansowany. Na jedną zmienną wynikową klasy 1 w zbiorze treningowym przypada 216 zmiennych klasy 0. Aby ograniczyć znaczenie tej dysproporcji należy podnieść wagę zmiennej zależnej o około 216 razy.

Pw = sum(ytrain == 0) / sum(ytrain == 1)  # size to repeat y == 1
Pw = np.round(Pw, decimals=0)
Pw = Pw.astype(int)
Pw

Parametr eagowy positive weight, Pw = 216.

Występowanie klasy 0 w zbiorze testowym zmiennych zależnych jest 216 razy częstsza niż 1. Należy zatem zwiększyć parametr class_weight  dla klasy 1, w stosunku do klasy 0 według przedziału {0:1,1:216}.

Parameters = {'C': np.power(10.0, np.arange(-3, 3))}
LogReg = LogisticRegression(class_weight = {0 : 1, 1 : Pw}, warm_start = True, solver='lbfgs')

Dostrojenie modelu za pomocą siatki Grid.

LRV_Reg_grid = GridSearchCV(LogReg, param_grid = Parameters, scoring = 'roc_auc', n_jobs = 5, cv = 6)

LRV_Reg_grid.fit(Xtrain, ytrain)

Z ciekawości zbadamy jakie zostały wybrane hiperparametry.

print("The Best parameter:",LRV_Reg_grid.best_params_)
print("The Best estimator:",LRV_Reg_grid.best_estimator_)

Wstawiam moduł diagnostyczny.

print()
print("Recall Training data:     ", np.round(recall_score(ytrain, LRV_Reg_grid.predict(Xtrain)), decimals=4))
print("Precision Training data:  ", np.round(precision_score(ytrain, LRV_Reg_grid.predict(Xtrain)), decimals=4))

print("----------------------------------------------------------------------")
print("Recall Test data:         ", np.round(recall_score(ytest, LRV_Reg_grid.predict(Xtest)), decimals=4)) 
print("Precision Test data:      ", np.round(precision_score(ytest, LRV_Reg_grid.predict(Xtest)), decimals=4))
print("----------------------------------------------------------------------")
print("Confusion Matrix Test data")
print(confusion_matrix(ytest, OVS_grid.predict(Xtest)))


print("----------------------------------------------------------------------")
print(classification_report(ytest, LRV_Reg_grid.predict(Xtest)))

y_pred_proba = LRV_Reg_grid.predict_proba(Xtest)[::,1]
fpr, tpr, _ = metrics.roc_curve(ytest,  y_pred_proba)
auc = metrics.roc_auc_score(ytest, y_pred_proba)
plt.plot(fpr, tpr, label='Logistic Regression (auc = %0.2f)' % auc)
plt.xlabel('False Positive Rate',color='grey', fontsize = 13)
plt.ylabel('True Positive Rate',color='grey', fontsize = 13)
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.legend(loc=4)
plt.plot([0, 1], [0, 1],'r--')
plt.show()

Zastosowanie class_weight spowodowało podniesienie wagi zmiennych zależnych w klasie 1. Dzięki temu model regresji logistycznej zwiększył wskaźnik recall dla klasy 1 do poziomu 0.92 kosztem precision wynoszącym 0.35 dla tej klasy.

Parameters = {'C': np.power(10.0, np.arange(-3, 3))}
LogReg = LogisticRegression(class_weight = {0 : 1, 1 : Pw}, warm_start = True, solver='lbfgs')
LRV_Reg_grid = GridSearchCV(LogReg, param_grid = Parameters, scoring = 'roc_auc', n_jobs = 5, cv = 6)
LRV_Reg_grid.fit(Xtrain, ytrain)

print()
print("Recall Training data:     ", np.round(recall_score(ytrain, LRV_Reg_grid.predict(Xtrain)), decimals=4))
print("Precision Training data:  ", np.round(precision_score(ytrain, LRV_Reg_grid.predict(Xtrain)), decimals=4))

print("----------------------------------------------------------------------")
print("Recall Test data:         ", np.round(recall_score(ytest, LRV_Reg_grid.predict(Xtest)), decimals=4)) 
print("Precision Test data:      ", np.round(precision_score(ytest, LRV_Reg_grid.predict(Xtest)), decimals=4))
print("----------------------------------------------------------------------")
print("Confusion Matrix Test data")
print(confusion_matrix(ytest, OVS_grid.predict(Xtest)))


print("----------------------------------------------------------------------")
print(classification_report(ytest, LRV_Reg_grid.predict(Xtest)))

y_pred_proba = LRV_Reg_grid.predict_proba(Xtest)[::,1]
fpr, tpr, _ = metrics.roc_curve(ytest,  y_pred_proba)
auc = metrics.roc_auc_score(ytest, y_pred_proba)
plt.plot(fpr, tpr, label='Logistic Regression (auc = %0.2f)' % auc)
plt.xlabel('False Positive Rate',color='grey', fontsize = 13)
plt.ylabel('True Positive Rate',color='grey', fontsize = 13)
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.legend(loc=4)
plt.plot([0, 1], [0, 1],'r--')
plt.show()