Przy budowie modelów klasyfikacji 0-1 występuje problem zbilansowanych zbiorów
import numpy as np
import pandas as pd
#import xgboost as xgb
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
import matplotlib.pylab as plt
from pylab import plot, show, subplot, specgram, imshow, savefig
from sklearn import preprocessing
#from sklearn import cross_validation, metrics
from sklearn.preprocessing import Normalizer
#from sklearn.cross_validation import cross_val_score
from sklearn.preprocessing import Imputer
import matplotlib.pyplot as plote
plt.style.use('ggplot')
df = pd.read_csv('c:/1/bank.csv')
df.head()
MODEL BEZ ZBILANSOWANIA ZBIORÓW ———————————–
Skalowanie standardowe tylko dla wartości dyskretnych
Wybieram kolumny tekstowe, dyskretne, do głębszej analizy. Lepsze było to wybieranie dyskretne i ciągłe.
encoding_list = ['job', 'marital', 'education', 'default', 'housing', 'loan',
'contact', 'month', 'day_of_week','poutcome']
df[encoding_list] = df[encoding_list].apply(LabelEncoder().fit_transform)
df[encoding_list].head()
Tworzymy zestaw treningowy i zestaw testowy, budujemy model
y = df['y']
X = df.drop('y', axis=1)
Złoty podział zioru na testowy i treningowy
from sklearn.model_selection import train_test_split
Xtrain, Xtest, ytrain, ytest = train_test_split(X,y, test_size=0.33, stratify = y, random_state = 148)
wielkości zbiorów
print ('Zbiór X treningowy: ',Xtrain.shape)
print ('Zbiór X testowy: ', Xtest.shape)
print ('Zbiór y treningowy: ', ytrain.shape)
print ('Zbiór y testowy: ', ytest.shape)
Dane dyskretne są zdygitalizowane
Xtrain.head(4)
Random Forest Classifier
from sklearn import model_selection
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
forestVC = RandomForestClassifier (random_state = 1,
n_estimators = 750,
max_depth = 15,
min_samples_split = 5, min_samples_leaf = 1)
modelF = forestVC.fit(Xtrain, ytrain)
y_predF = modelF.predict(Xtest)
Blok oceny jakości modelu Random Forest Classifier
ypred = modelF.predict(Xtest)
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
co_matrix = metrics.confusion_matrix(ytest, ypred)
co_matrix
print(classification_report(ytest, ypred))
print("Accuracy: ",np.round(metrics.accuracy_score(ytest, ypred), decimals=2))
print("Precision: ",np.round(metrics.precision_score(ytest, ypred), decimals=2))
print("Recall: ",np.round(metrics.recall_score(ytest, ypred), decimals=2))
print("F1 score: ",np.round(metrics.f1_score(ytest, ypred), decimals=2))
Analiza poziomu zbilansowania zmiennej wynikowej
df.y.value_counts(dropna = False, normalize=True)
print("ytrain = 0: ", sum(ytrain == 0))
print("ytrain = 1: ", sum(ytrain == 1))
Proporcja = sum(ytrain == 0) / sum(ytrain == 1)
Proporcja = np.round(Proporcja, decimals=0)
Proporcja = Proporcja.astype(int)
Proporcja
Na jedną daną sybskrypcje przypada 8 nieprzedłużonych subskrypcji. Powiększamy liczbę próbek niezależnych.
ytrain_pos_OVS = pd.concat([ytrain[ytrain==1]] * Proporcja, axis = 0)
ytrain_pos_OVS.count()
Ilość zmiennych wynikowych: (1) zwiększyła się do liczby 24872
Mamy już wektor zmiennych wynikowych y, teraz trzeba zwiększyć liczbę zmiennych niezależnych.
Xtrain_pos_OVS = pd.concat([Xtrain.loc[ytrain==1, :]] * Proporcja, axis = 0)
Xtrain_pos_OVS.age.count()
Teraz mamy tą samą liczbę wierszy zmiennych wynikowych i zmiennych niezależnych.
Teraz wprowadzamy nowe, dodatkowe zmienne 1 do zbioru treningowego.
ytrain_OVS = pd.concat([ytrain, ytrain_pos_OVS], axis = 0).reset_index(drop = True)
Xtrain_OVS = pd.concat([Xtrain, Xtrain_pos_OVS], axis = 0).reset_index(drop = True)
Sprawdzamy ilość wierszy w zbiorach przed i po oversampling
print("ilość elementów w zbiorze Xtrain: ", Xtrain.age.count())
print("ilość elementów w zbiorze Xtrain_OVS: ", Xtrain_OVS.age.count())
print("ilość elementów w zbiorze ytrain: ", ytrain.count())
print("ilość elementów w zbiorze ytrain_OVS: ", ytrain_OVS.count())
forestVC = RandomForestClassifier (random_state = 1,
n_estimators = 750,
max_depth = 15,
min_samples_split = 5, min_samples_leaf = 1)
modelF = forestVC.fit(Xtrain_OVS, ytrain_OVS)
ypred = modelF.predict(Xtest)
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import metrics
co_matrix = metrics.confusion_matrix(ytest, ypred)
co_matrix
print(classification_report(ytest, ypred))
print("Accuracy: ",np.round(metrics.accuracy_score(ytest, ypred), decimals=2))
print("Precision: ",np.round(metrics.precision_score(ytest, ypred), decimals=2))
print("Recall: ",np.round(metrics.recall_score(ytest, ypred), decimals=2))
print("F1 score: ",np.round(metrics.f1_score(ytest, ypred), decimals=2))
- Accuracy: 0.91
- Precision: 0.66
- Recall: 0.48
- F1 score: 0.56
Wynik kodelu po Oversampling
- Accuracy: 0.89
- Precision: 0.52
- Recall: 0.82
- F1 score: 0.63