6 - Optimiser les performances

Techniques

Certaines techniques d’optimisations sont spécifiques aux différents algorithmes:

D’autres vont pouvoir être applicable dans la majorité des algorithmes, si ce n’est tous:


Cross-validation

Notebook: Cross-validation


Réequilibrer les classes

Up-sampling de la classe minoritaire

python
from sklearn.utils import resample

# Separate majority and minority classes
df_majority = df[df.balance==0]
df_minority = df[df.balance==1]

# Upsampling minority class
df_minority_up = resample(
  df_minority,
  replace=True,
  n_samples=len(df_majority),
  random_state=0
)

# Combine majority class with upsampled minority class
df_up = pd.concat([df_majority, df_minority_up])

# Display new class counts
df_up.balance.value_counts()

SMOTE

python
!pip install imbalanced-learn

from imblearn.over_sampling import SMOTE

smote = SMOTE()
X, y  = smote.fit_resample(X, y)

Down-sampling de la classe majoritaire

python
from sklearn.utils import resample

# Separate majority and minority classes
df_majority = df[df.balance==0]
df_minority = df[df.balance==1]

# Downsampling majority class
df_majority_down = resample(
  df_majority,
  replace=False,
  n_samples=len(df_minority),
  random_state=0
)

# Combine minority class with downsampled majority class
df_down = pd.concat([df_majority_down, df_minority])

# Display new class counts
df_down.balance.value_counts()

NearMiss

Under-over sampling.ipynb

Pour aller plus loin:
imbalanced-learn API
Techniques to handle Class Imbalance in data
Pandas resample() tricks for time-series data


Ajuster les hyperparamètres

Différents algorithmes vont avoir différents hyperparamètres, des paramètres qui ne sont pas appris par l’algorithme mais définis par le développeur — par exemple: la fonction d’hypothèse, la fonction coût, la fonction d’optimisation, le nombre K à utiliser dans K-means, etc.
Quand on utilise un framework tel que Keras ou scikit-learn, les hyperparamètres ont une valeur par défaut. On commence généralement avec les valeurs par défaut et, après évaluation, on vient modifier les hyperparamètres. Le but étant de trouver la combinaison d’hyperparamètes avec laquelle le modèle est le plus performant. Pour ce faire, on peut utiliser:

Pour aller plus loin:
Hyperparameter Optimization Techniques
Bayesian Optimization


Techniques d’ensemble

Un modèle aura toujours ses forces et ses faiblesses — il reconnaîtra certaines tendances, mais passera à côté des autres. Pour rendre les prédictions plus fiables, on peut construire différents modèles et les laisser “voter” la prédiction finale. Ça permet d’exploiter les points forts de différents modèles et les résultats seront généralement meilleurs que les résultats d’un seul modèle. Plusieurs approches existent pour parvenir à ce but.

Bagging

(aka boostrap aggregating, parallel ensemble learning)

On divise l’ensemble de données en différents sous-ensembles, et on s’en sert pour entraîner parallélement différents modèles du même type. On utilise une méthode statistique (typiquement la moyenne) pour combiner les différentes prédictions en une seule.

Ex: Bagged Decision Trees, Extra Trees

python
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import BaggingClassifier

model_log = LogisticRegression(solver='liblinear')

bagging_log = BaggingClassifier(
    base_estimator=model_log,
    n_estimators=12
)
bagging_log.fit(X_train, y_train)

print('Accuracy Score on train:', bagging_log.score(X_train, y_train))
print('Accuracy Score on test:', bagging_log.score(X_test, y_test))
from sklearn.ensemble import ExtraTreesClassifier

model_et = ExtraTreesClassifier(n_estimators=8)
model_et.fit(X_train, y_train)

y_pred = model_et.predict(X_test)
print('Accuracy Score:', accuracy_score(y_test, y_pred))

Random Forest

Random Forest est une technique d’ensemble spécifiques aux Decision Tree. Là où une technique de bagging sélectionne des observations de manière aléatoire pour construire des modèles, Random Forest sélectionne des caractéristiques au hasard. Différents arbres vont donc choisir différentes caractéristiques pour partitionner les données. La prédiction finale est calculée en calculant la réponse moyenne des arbres.

Random Forest peut être utilisé comme une finalité (effectuer une prédiction à partir de différents modèles) mais aussi comme outil pour identifier les caractéristiques les plus pertinentes.

python
# Random Forest
model = RandomForestClassifier(
  n_estimators=1000,
  max_features=2,
  oob_score=True
)
model.fit(X=X, y=y)

# Feature importance
df_rank = pd.DataFrame(
  data=[],
  columns=['Feature', 'Importance'])

for feature, imp in zip(X.columns, model.feature_importances_):
    df_rank.loc[len(df_rank)] = [feature, imp]

df_rank.sort_values(by=['Importance'], ascending=False)

Boosting

(aka sequential ensemble learning)

On entraîne un modèle, détermine quelles observations ont été mal prédites, puis on entraîne un nouveau modèle sur ces observations, en espérant qu’il leur accorde plus d’attention et que ses prédictions soient correctes. Chaque modèle apprend à partir des erreurs des précedents.

Ex: AdaBoost, Gradient Boosting Machine (GBM), Extreme Gradient Boosting (XGBoost)

python
from sklearn.ensemble import AdaBoostClassifier

boosting_log = AdaBoostClassifier(
    base_estimator=model_log,
    n_estimators=10
)
boosting_log.fit(X_train, y_train)

print('Accuracy Score on train:', boosting_log.score(X_train, y_train))
print('Accuracy Score on test:', boosting_log.score(X_test, y_test))
from sklearn.ensemble import GradientBoostingClassifier

gboosting_log = GradientBoostingClassifier()
gboosting_log.fit(X_train, y_train)

y_pred = gboosting_log.predict(X_test)
print('Accuracy Score:', accuracy_score(y_test, y_pred))

AdaBoost, Gradient Boost, XGBoost

Bucket of models

Ce n’est pas une technique d’ensemble — mais on en entend généralement parler dans ce contexte. On entraîne différents types de modèles en parallèle et on choisit celui qui a les meilleures performances.

Stacking

(aka voting)

On entraîne différents types de modèles en parallèle et on combine leur résultat via une méthode statistique (comme la moyenne ou le mode).

python
from sklearn.ensemble import VotingClassifier

model1 = LogisticRegression(random_state=1)
model2 = DecisionTreeClassifier(random_state=1)

stacking = VotingClassifier(estimators=[
  ('lr', model1),
  ('dt', model2)
], voting='hard')

stacking.fit(X_train,y_train)
stacking.score(X_test,y_test)