Archives de la catégorie Intelligence artificielle

La logique floue (fuzzy logic) – Exemple en C# avec Aforge.Fuzzy

Introduction

La logique floue est un domaine de l’intelligence artificielle, elle se rapproche du raisonnement humain. Contrairement à des calculs rigides, qui se base sur des ensembles bien définis, elle utilise des ensembles flous ou imprécis. Elle s’appuie sur la théorie mathématique des ensembles flous qui est une extension de la théorie des ensembles.

Pour vous montrer l’utilisation de la bibliothèque .Net Aforge.Net, nous allons nous baser sur l’exemple décris dans l’excellent article de Franck Dernoncourt que je vous invite à lire : http://franck-dernoncourt.developpez.com/tutoriels/algo/introduction-logique-floue/

L’objectif sera de décider du pourboire à donner à la fin d’un repas au restaurant en fonction de la qualité du service ainsi que de la qualité de la nourriture.

Étapes pour définir un système flou

Représentation d’un système d’inférence avec Aforge.net

Fig4

  • Input et Output

Il est nécessaire dans un premier temps de définir les différentes entrées et sorties du système :

    • Input    : Nourriture          =   noté sur une échelle de  0 à 10
    • Input    : QualiteService    =   noté sur une échelle de  0 à 10
    • Output : Pourboire           =    montant donné de 0 à 30 euros

Code avec la librairie Aforge.Net :

var lvNourriture = new LinguisticVariable("Nourriture", 0, 10);
    var lvQualiteService = new LinguisticVariable("QualiteService", 0, 10);
    var lvPourboire = new LinguisticVariable("Pourboire", 0, 30);

  • La Fuzzification

Nous devons définir des variables dites “variables linguistiques” qui seront utilisées pour définir les règles du système. Il y a ici 3 variables linguistiques  : Nourriture, QualiteService, Pourboire.

Pour chacune de ces variables, il est nécessaire de qualifier les éléments de ces ensembles flous

    • Input    : Nourriture          =   {Execrable, Delicieux}
    • Input    : QualiteService  =   {Mauvais, Bon, Excellent}
    • Output : Pourboire           =   {Faible, Moyen, Eleve)}

Pour chacun de ces éléments il est nécessaire de lui adjoindre une fonction d’appartenance, le plus souvent définie par des segments de droites.

is-var-nourriture

Code avec Aforge.Net :  les fonctions trapézoïdales ont plusieurs constructeurs, ici le trapèze est ouvert sur la droite, puis sur la gauche en formant une ligne infinie.

//Trapèze avec ligne infinie sur la droite
    var fsExecrable = new FuzzySet("Execrable", new TrapezoidalFunction(1, 3, TrapezoidalFunction.EdgeType.Right));
    //Trapèze avec ligne infinie sur la gauche
    var fsDelicieux = new FuzzySet("Delicieux", new TrapezoidalFunction(7, 9, TrapezoidalFunction.EdgeType.Left));

Exemple: une note pour la qualité de la nourriture de 1 est considérée comme exécrable; une note de 2 est considéré comme 50% exécrable; et 3 sort du périmètre de ce qualificatif.

is-var-service

Code avec Aforge.Net :

var fsMauvais = new FuzzySet("Mauvais", new TrapezoidalFunction(0, 5, TrapezoidalFunction.EdgeType.Right));
    var fsBon = new FuzzySet("Bon", new TrapezoidalFunction(0, 5, 10));
    var fsExcellent = new FuzzySet("Excellent", new TrapezoidalFunction(5, 10, TrapezoidalFunction.EdgeType.Left));

Exemple: Pour la qualité de service, une note de 5 est considérée comme 100% bon, une note de 8,5 est considérée comme 50% excellent.

is-var-pourboire

Code avec Aforge.Net :

var fsFaible = new FuzzySet("Faible", new TrapezoidalFunction(0, 5, 10));
    var fsMoyen = new FuzzySet("Moyen", new TrapezoidalFunction(10, 15, 20));
    var fsEleve = new FuzzySet("Eleve", new TrapezoidalFunction(20, 25, 30));

Exemple: Pour le pourboire, un montant de 5 € est 100% faible, 22.5€ est considéré comme 50% élevé.

Il faut maintenant associer les qualificatifs aux différents ensembles flous :

    lvNourriture.AddLabel(fsExecrable);  //Ajout du qualificatif exécrable à l’ensemble flou Nourriture
    lvNourriture.AddLabel(fsDelicieux);  //Ajout du qualificatif délicieux à l’ensemble flou Nourriture 
    lvQualiteService.AddLabel(fsMauvais); //Ajout du qualificatif mauvais à l’ensemble flou Qualité de service
    lvQualiteService.AddLabel(fsBon);     //Ajout du qualificatif bon à l’ensemble flou Qualité de service
    lvQualiteService.AddLabel(fsExcellent); //Ajout du qualificatif excellent à l’ensemble flou Qualité de service 
    lvPourboire.AddLabel(fsFaible); //Ajout du qualificatif faible à l’ensemble flou Pourboire 
    lvPourboire.AddLabel(fsMoyen);  //Ajout du qualificatif moyen à l’ensemble flou Pourboire 
    lvPourboire.AddLabel(fsEleve);  //Ajout du qualificatif élevé à l’ensemble flou Pourboire 
  • Base de connaissance

Nous allons créer une base regroupant les variables linguistiques créées juste avant.

var fuzzyDb = new Database();      //Création de la base 
    fuzzyDb.AddVariable(lvNourriture); //Ajout des variables linguistiques
    fuzzyDb.AddVariable(lvQualiteService);
    fuzzyDb.AddVariable(lvPourboire);
  • Initialisation du système d’inférence

// Création system inference
    // Initialise la méthode de défuzzification : centre de gravité
    var inferenceSys = new InferenceSystem(fuzzyDb, new CentroidDefuzzifier(1000));

Le constructeur a besoin de la base regroupant l’ensemble des variables linguistiques et d’une méthode de défuzzification.

  • Définition des règles floues

les règles du système sont les suivantes :

    • Si le service est mauvais ou la nourriture est exécrable alors le pourboire est faible.
    • Si le service est bon alors le pourboire est moyen.
    • Si le service est excellent ou la nourriture est délicieuse alors le pourboire est élevé.

Ce qui se traduit en code par :

    inferenceSys.NewRule("Rule 1", "IF QualiteService IS Mauvais OR Nourriture IS Execrable THEN Pourboire IS Faible");
    inferenceSys.NewRule("Rule 2", "IF QualiteService IS Bon THEN Pourboire IS Moyen");
    inferenceSys.NewRule("Rule 3", "IF QualiteService IS Excellent OR Nourriture IS Delicieux THEN Pourboire IS Eleve");
  • Défuzzification & Output

// Initialise les données d'entrées
    inferenceSys.SetInput("QualiteService", noteQualiteService);
    inferenceSys.SetInput("Nourriture", noteNourriture);
    // Evalue la donnée de sortie : Pourboire = Output
    resPourboire = inferenceSys.Evaluate("Pourboire");


Source complète de l’exemple :

static void Main(string[] args)
{
WritePourboire(7, 9);
    WritePourboire(2, 9);
    WritePourboire(5, 6);
    WritePourboire(2, 3);
    Console.ReadLine();
}

public static void WritePourboire(float noteQualiteService, float noteNourriture)
{
    #region Input (Qualité de service)
    var lvQualiteService = new LinguisticVariable("QualiteService", 0, 10);

    var fsMauvais = new FuzzySet("Mauvais", new TrapezoidalFunction(0, 5, TrapezoidalFunction.EdgeType.Right));
    var fsBon = new FuzzySet("Bon", new TrapezoidalFunction(0, 5, 10));
    var fsExcellent = new FuzzySet("Excellent", new TrapezoidalFunction(5, 10, TrapezoidalFunction.EdgeType.Left));

    lvQualiteService.AddLabel(fsMauvais);
    lvQualiteService.AddLabel(fsBon);
    lvQualiteService.AddLabel(fsExcellent);
    #endregion

    #region Input (Nourriture)
    var lvNourriture = new LinguisticVariable("Nourriture", 0, 10);

    var fsExecrable = new FuzzySet("Execrable", new TrapezoidalFunction(1, 3, TrapezoidalFunction.EdgeType.Right));
    var fsDelicieux = new FuzzySet("Delicieux", new TrapezoidalFunction(7, 9, TrapezoidalFunction.EdgeType.Left));

    lvNourriture.AddLabel(fsExecrable);
    lvNourriture.AddLabel(fsDelicieux);
    #endregion

    #region Output (Pourboire)
    var lvPourboire = new LinguisticVariable("Pourboire", 0, 30);

    var fsFaible = new FuzzySet("Faible", new TrapezoidalFunction(0, 5, 10));
    var fsMoyen = new FuzzySet("Moyen", new TrapezoidalFunction(10, 15, 20));
    var fsEleve = new FuzzySet("Eleve", new TrapezoidalFunction(20, 25, 30));

    lvPourboire.AddLabel(fsFaible);
    lvPourboire.AddLabel(fsMoyen);
    lvPourboire.AddLabel(fsEleve);
    #endregion

    #region Système Inference
    // Base de données pour les variables linguistiques
    // Nourriture(Execrable, Delicieux) 0 - 10
    // QualiteService(Mauvais, Bon, Excellent) 0 - 10
    // Pourboire(Faible, Moyen, Eleve) 0 - 30
    var fuzzyDb = new Database();
    fuzzyDb.AddVariable(lvNourriture);
    fuzzyDb.AddVariable(lvQualiteService);
    fuzzyDb.AddVariable(lvPourboire);

    // Creation system inference
    // Initialise la methode de défuzzification : centre de gravité
    var inferenceSys = new InferenceSystem(fuzzyDb, new CentroidDefuzzifier(1000));
    // Ajoute des regles
    inferenceSys.NewRule("Rule 1", "IF QualiteService IS Mauvais OR Nourriture IS Execrable THEN Pourboire IS Faible");
    inferenceSys.NewRule("Rule 2", "IF QualiteService IS Bon THEN Pourboire IS Moyen");
    inferenceSys.NewRule("Rule 3", "IF QualiteService IS Excellent OR Nourriture IS Delicieux THEN Pourboire IS Eleve");
    #endregion

    #region Exemple
    // Initialise les données d'entrées
    inferenceSys.SetInput("QualiteService", noteQualiteService);
    inferenceSys.SetInput("Nourriture", noteNourriture);

    // Evalue la donnée de sortie : Pourboire
    var resPourboire = -1f;
    try
    {
        resPourboire = inferenceSys.Evaluate("Pourboire");
    }
    catch (Exception ex)
    {
        throw new Exception(string.Format("Erreur : {0}", ex.Message));
    }
    Console.WriteLine("Nourriture: {0}  + QualiteService : {1} = Pourboire : {2}", 
        noteNourriture, noteQualiteService, resPourboire);
    #endregion
}

Sortie du programme :

Nourriture: 9  + QualiteService : 7 = Pourboire : 20,43472
Nourriture: 9  + QualiteService : 2 = Pourboire : 15,64511
Nourriture: 6  + QualiteService : 5 = Pourboire : 14,99998
Nourriture: 3  + QualiteService : 2 = Pourboire : 9,324404

Publicités

Poster un commentaire

%d blogueurs aiment cette page :