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 = 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 = 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()