Méthodes par consistance

Les méthodes par consistance sont des techniques d’apprentissage semi-supervisé qui exploitent la notion de cohérence ou consistance des étiquettes des données. L’idée sous-jacente est que les modèles doivent prédire de manière cohérente les étiquettes des données sous diverses transformations (comme des perturbations de données ou des ajouts de bruit). Ces méthodes cherchent à faire en sorte que les prédictions du modèle restent stables (ou consistantes) lorsque les données sont modifiées d’une manière qui n’affecte pas leur classe réelle.

Les méthodes par consistance peuvent être appliquées sur des données étiquetées et non étiquetées, en forçant le modèle à se comporter de manière cohérente vis-à-vis de ces deux types de données.

Exemples de techniques :

  1. Consistency Regularization (régularisation par consistance) : Utilisée dans des modèles comme MixMatch, FixMatch, où un modèle prédit la même étiquette pour les données bruyantes ou légèrement modifiées.

  2. Pseudo-labelling : Cette approche consiste à générer des pseudo-étiquettes pour les exemples non étiquetés à partir des prédictions du modèle.

Fonctions :

  • Méthodes par consistance(exemple)

    Voici un exemple de pseudo-labelling utilisant une technique de consistance, où les données non étiquetées sont utilisées pour générer des pseudo-étiquettes à partir des prédictions du modèle.

    Exemple de code :

    import numpy as np
    from sklearn.datasets import make_classification
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import accuracy_score
    
    # Création d'un jeu de données fictif
    X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
    
    # Simulation de données non étiquetées (par exemple, 40% des données sont non étiquetées)
    y[400:] = -1  # -1 indique des étiquettes non étiquetées
    
    # Séparation en données d'entraînement et de test
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
    
    # Création du classificateur
    classifier = RandomForestClassifier(n_estimators=100, random_state=42)
    
    # Phase d'apprentissage initiale sur les données étiquetées
    classifier.fit(X_train[y_train != -1], y_train[y_train != -1])
    
    # Méthode de Pseudo-labelling : générer des pseudo-étiquettes pour les données non étiquetées
    pseudo_labels = classifier.predict(X_train[y_train == -1])
    confidence_threshold = 0.9
    
    # Application d'un seuil de confiance pour considérer les pseudo-étiquettes
    probas = classifier.predict_proba(X_train[y_train == -1])
    confident_indices = np.max(probas, axis=1) > confidence_threshold
    y_train_copy = y_train.copy()
    
    # Attribuer les pseudo-étiquettes uniquement pour les prédictions confiant
    y_train_copy[y_train == -1] = np.where(confident_indices, pseudo_labels, -1)
    
    # Réentraîner le modèle avec les pseudo-étiquettes
    classifier.fit(X_train[y_train_copy != -1], y_train_copy[y_train_copy != -1])
    
    # Évaluation du modèle
    y_pred = classifier.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print(f"Accuracy with Consistency Method (Pseudo-labelling): {accuracy:.4f}")

    Explication du code :

    import numpy as np importe la bibliothèque NumPy, utilisée ici pour la manipulation efficace de tableaux et le traitement vectoriel.
    
    from sklearn.datasets import make_classification importe la fonction make_classification qui génère un jeu de données synthétique de classification avec des caractéristiques informatives et redondantes.
    
    from sklearn.model_selection import train_test_split importe la fonction train_test_split qui permet de diviser un jeu de données en un ensemble d’entraînement et un ensemble de test.
    
    from sklearn.ensemble import RandomForestClassifier importe la classe RandomForestClassifier, un classificateur puissant basé sur des forêts d’arbres décisionnels (ensemble learning).
    
    from sklearn.metrics import accuracy_score importe la fonction accuracy_score qui calcule la précision du modèle en comparant les prédictions avec les vraies étiquettes.
    
    
    Création du jeu de données
    X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42) génère un jeu de 1000 échantillons, chacun ayant 20 caractéristiques numériques, répartis entre 2 classes (classification binaire). Le paramètre random_state garantit la reproductibilité.
    Simulation de données non étiquetées
    y[400:] = -1 remplace les étiquettes de 60% des données par -1, indiquant qu’elles sont considérées comme non étiquetées. Cette étape simule un contexte semi-supervisé.
    Séparation en données d'entraînement et de test
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) divise les données en 70% pour l’entraînement (dont une partie non étiquetée) et 30% pour le test.
    Entraînement initial du modèle sur les données étiquetées
    classifier = RandomForestClassifier(n_estimators=100, random_state=42) crée un modèle d’ensemble composé de 100 arbres de décision. classifier.fit(X_train[y_train != -1], y_train[y_train != -1]) entraîne le modèle uniquement sur les exemples d’entraînement ayant une étiquette (c’est-à-dire, y ≠ -1).
    Génération des pseudo-étiquettes
    pseudo_labels = classifier.predict(X_train[y_train == -1]) prédit les classes des données non étiquetées à l’aide du modèle entraîné. probas = classifier.predict_proba(X_train[y_train == -1]) calcule la probabilité associée à chaque prédiction.
    Filtrage des prédictions selon un seuil de confiance
    confidence_threshold = 0.9 définit un seuil au-dessus duquel les pseudo-étiquettes sont considérées comme fiables. confident_indices = np.max(probas, axis=1) > confidence_threshold identifie les indices des exemples dont la prédiction est effectuée avec une probabilité supérieure à 90%. y_train_copy = y_train.copy() crée une copie des étiquettes d'entraînement pour ne pas modifier directement y_train. y_train_copy[y_train == -1] = np.where(confident_indices, pseudo_labels, -1) attribue les pseudo-étiquettes uniquement aux exemples jugés fiables ; les autres restent non étiquetés.
    Réentraîner le modèle avec les pseudo-étiquettes fiables
    classifier.fit(X_train[y_train_copy != -1], y_train_copy[y_train_copy != -1]) réentraîne le modèle en incluant les données initialement non étiquetées mais maintenant enrichies de pseudo-étiquettes fiables.
    Évaluation du modèle
    y_pred = classifier.predict(X_test) prédit les classes du jeu de test. accuracy = accuracy_score(y_test, y_pred) calcule la précision du modèle final sur les données de test. print(f"Accuracy with Consistency Method (Pseudo-labelling): {accuracy:.4f}") affiche cette précision avec 4 décimales. Ce code met en œuvre la stratégie de Pseudo-labelling, une méthode d’apprentissage semi-supervisé où un modèle est d’abord entraîné sur les données étiquetées, puis utilisé pour attribuer des étiquettes provisoires (pseudo-labels) aux données non étiquetées. Seules les prédictions les plus confiantes sont intégrées à un second entraînement, ce qui permet d’améliorer les performances tout en limitant les erreurs dues aux données mal étiquetées.