Évaluation des classifieurs
Introduction¶
Ce document présente les résultats des différents classifieurs binaire de façon aggrégé par rapport à leurs performance respectives sur les 28 jeux de données fournis.
La phase d’optimisation des hyperparamètres a été réalisée pour chaque classifieur en utilisant un RandomHalvingRandomSearchCV pour réduire le temps d’exécution au lieu d’un classique GridSearchCV. Toutefois, en contrepartie, cela a généré des erreurs de fit pour certains classifieurs.
Nous pensons que ces erreurs de fit sont liés au paramètre de ressources minimale du RandomHalvingRandomSearchCV qui réduit le nombre de sample pour l’entrainement et peut malencontreusement fit le modèle sur des données ne contenant qu’une unique classe.
Présentation des jeux de données¶
import sys
sys.path.append("./../src/")
from get_dataset import dataset_loaders
import pandas as pd
datasets = dataset_loaders.keys()
data = []
for dataset_name in datasets:
X, y = dataset_loaders[dataset_name]()
n_samples, n_features = X.shape
size = n_samples * n_features
majority_class_proportion = max(sum(y == cls) for cls in set(y)) / n_samples
majority_class_proportion = "{:.0%}".format(majority_class_proportion)
# Percentage of non null elements in NDArray X
sparsity = "{:.0%}".format((X == 0).sum() / size)
data.append([dataset_name, n_samples, n_features, size, sparsity, majority_class_proportion])
df = pd.DataFrame(data, columns=["dataset", "n_samples", "n_features", "size", "sparsity", "majority_class"])
df = df.set_index("dataset")
df = df.sort_values("size", ascending=False)
display(df)Évaluation des classifieurs binaires¶
from pathlib import Path
import joblib
import pandas as pd
from sklearn.metrics import accuracy_score, f1_score
from scipy.stats import hmean
results_files = list(Path("./../results").rglob("*.joblib"))
combined_results = {}
for file in results_files:
results = joblib.load(file)
for model_name, result in results.items():
if model_name not in combined_results:
combined_results[model_name] = {
'best_params': result['best_params'],
'accuracies': [],
'f1_scores': []
}
y_true = result['y_true']
y_pred = result['y_pred']
accuracy = accuracy_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred, average='weighted')
combined_results[model_name]['accuracies'].append(accuracy)
combined_results[model_name]['f1_scores'].append(f1)
model_names = []
params = []
harmonic_means = []
for model_name, result in combined_results.items():
accuracies = result['accuracies']
f1_scores = result['f1_scores']
# Moyenne harmonique des métriques par rapport à chaque jeu de donnée
harmonic_mean_accuracy = hmean(accuracies)
harmonic_mean_f1 = hmean(f1_scores)
model_names.append(model_name)
params.append(result['best_params'])
harmonic_means.append((harmonic_mean_accuracy, harmonic_mean_f1))
df = pd.DataFrame({
'Model Name': model_names,
'Parameters': params,
'Harmonic Mean Accuracy': [hm[0] for hm in harmonic_means],
'Harmonic Mean F1 Score': [hm[1] for hm in harmonic_means]
})
df = df.sort_values(by='Harmonic Mean F1 Score', ascending=False)
average_harmonic_mean_accuracy = hmean(df['Harmonic Mean Accuracy'])
average_harmonic_mean_f1_score = hmean(df['Harmonic Mean F1 Score'])
df.loc['Average'] = ['Average', '-', average_harmonic_mean_accuracy, average_harmonic_mean_f1_score]
df = df.set_index('Model Name')
display(df)En examinant les résultats, on remarque que le Random Forest est l’un des modèles les plus performants. Sa version avec un apprentissage coût-sensible est étonnament moins efficace sur la base du score F1.
Les méthodes de boosting, comme AdaBoost et Gradient Boosting, affichent également de bons résultats, bien qu’elles restent légèrement en retrait par rapport au Random Forest. Ces modèles, bien que puissants, peuvent être plus sensibles aux hyperparamètres et aux bruits dans les données.
Les modèles linéaires, tels que la régression logistique et le SVM linéaire, obtiennent des performances légèrement inférieures aux méthodes à base d’arbres. La régression logistique reste compétitive et peut être une bonne alternative lorsqu’une meilleure interprétabilité est recherchée. Le SVM linéaire, quant à lui, est légèrement en retrait, bien qu’il conserve une certaine robustesse.
Concernant les modèles non linéaires, comme le SVM avec des noyaux non linéaires et les différentes variantes du KNN, leurs performances ne surpassent pas celles des forêts d’arbres. Le SVM utilisant SMOTE semble particulièrement affecté par une perte de performance. Le KNN, qu’il soit pondéré ou adaptatif, ne se démarque pas de manière significative et reste globalement moins efficace que les méthodes d’ensemble et les modèles linéaires.
De manière générale, les modèles basés sur des arbres, comme Random Forest et Gradient Boosting, semblent offrir le meilleur compromis entre performance et robustesse. Les modèles linéaires, bien que légèrement moins efficaces, restent des alternatives intéressantes, notamment pour leur interprétabilité. Les méthodes basées sur la proximité, comme KNN, et les SVM non linéaires ne semblent pas apporter d’amélioration significative et pourraient être moins adaptées dans ce contexte.