Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. L'Intelligence Artificielle pour les développeurs
  3. Logique floue
Extrait - L'Intelligence Artificielle pour les développeurs Concepts et implémentations en C# (2e édition)
Extraits du livre
L'Intelligence Artificielle pour les développeurs Concepts et implémentations en C# (2e édition) Revenir à la page d'achat du livre

Logique floue

Présentation du chapitre

La logique floue est une technique d’intelligence artificielle déterministe permettant de prendre des décisions. Elle permet ainsi d’avoir un comportement cohérent et reproductible en fonction de règles qui sont fournies. L’intelligence de cette technique se trouve dans sa capacité à gérer l’imprécision et à avoir un comportement plus souple qu’un système informatique traditionnel.

Ce chapitre commence par définir la notion d’imprécision, à ne pas confondre avec l’incertitude. Ensuite, les différents concepts sont abordés : les ensembles flous, les fonctions d’appartenance et les différents opérateurs en logique floue.

La partie suivante traite des règles floues et des étapes pour appliquer ces règles à un cas concret et en sortir un résultat utilisable (elles s’appellent respectivement fuzzification et défuzzification).

Le chapitre continue ensuite avec la présentation de différents domaines d’application de la logique floue, que l’on retrouve aujourd’hui de nos lave-linge à nos voitures en passant par les usines.

Enfin, la dernière partie consiste à montrer comment on peut implémenter un moteur de logique floue générique et évolutif...

Incertitude et imprécision

Il est important de différencier deux concepts : l’incertitude et l’imprécision. En effet, chacun va être associé à une technique d’intelligence artificielle différente. 

1. Incertitude et probabilités

L’incertitude, c’est évidemment, le contraire de la certitude. Par exemple, la règle "S’il va pleuvoir, alors je prendrai mon parapluie" est sûre (à 100 %) : se mouiller n’est pas agréable. Au contraire, l’énoncé "Demain, il devrait pleuvoir" est incertain : la météo a peut-être annoncé de la pluie, mais rien ne dit qu’il pleuvra vraiment. On peut dire que la probabilité qu’il pleuve est de 80 % par exemple. Tout énoncé dont la probabilité est différente de 100 % est incertain.

2. Imprécision et subjectivité

Au contraire, l’imprécision se manifeste lorsque l’on manque... de précision ! Dans les faits, cela se traduit par des énoncés qu’il est difficile d’évaluer : ils semblent subjectifs. Par exemple, dans la phrase "S’il fait très chaud, alors je ne mettrai pas de pull", l’imprécision se situe sur la notion de "très chaud".

On est certain...

Ensembles flous et degrés d’appartenance

Si on reprend l’exemple de notre store électrique et de la température, on aimerait définir le terme "chaud". On va donc définir pour quelles températures il fait chaud ou non.

1. Logique booléenne et logique floue

En logique booléenne (la logique classique), une valeur peut seulement être vraie ou fausse. On doit définir une valeur précise qui sert de transition. Pour définir "chaud" pour notre store, cette valeur est 25°. Au-dessus de cette température, "chaud" est vrai, au-dessous, "chaud" est faux. Il n’y a pas de valeurs intermédiaires.

images/02DP01.png

En logique floue, on va utiliser un ensemble flou. Il se différencie de l’ensemble booléen par la présence d’une "phase de transition", durant laquelle la variable se situe entre vrai et faux. Pour la température, entre 20° et 25°, il fait alors plus ou moins chaud.

Au-dessous de 20°C, il ne fait pas chaud, et au-dessus de 25°, il fait chaud à 100 %. Mais à 23°, il ne fait chaud qu’à 60 % (soit 0.6).

images/02DP02.png

2. Fonctions d’appartenance

On voit ainsi qu’en logique booléenne, on ne travaille que sur les termes "vrai" ou "faux". On passe de faux (0 %) à vrai (100 %) à 25°. En logique floue, on rajoute des états intermédiaires : de 20° à 25° on va passer progressivement de faux à vrai. Ainsi, on peut lire sur le graphique que le degré d’appartenance (ou valeur de vérité) à "chaud" pour une température de 23° est de 0.6 soit 60 %. De même, à 24°, il fait "chaud" à 80 %.

La courbe indiquant les degrés d’appartenance est appelée fonction d’appartenance. Elle permet de définir un ensemble flou, possédant des limites qui ne sont pas nettes, mais progressives, comme un fondu. Ces ensembles flous peuvent utiliser différentes fonctions d’appartenance qui associent toutes un degré d’appartenance aux différentes valeurs possibles. Il existe cependant cinq fonctions plus classiques.

1.

La fonction triangulaire : il n’y a qu’une seule valeur possédant...

Opérateurs sur les ensembles flous

En logique classique, on a trois opérateurs de composition élémentaires : l’union (OU), l’intersection (ET) et la négation (NON). Ces opérateurs sont aussi nécessaires en logique floue, en particulier pour pouvoir composer des valeurs linguistiques (par exemple "frais OU bon") et écrire des règles.

1. Opérateurs booléens

En logique booléenne, ces trois opérateurs peuvent se représenter grâce à des diagrammes de Venn. Dans ceux-ci, les ensembles sont représentés par des cercles.

Ici, on a deux ensembles, A et B, qui se chevauchent en partie :

images/02DP11.png
La négation de l’ensemble A est dite NON A et s’écrit images/eq4.png. Elle représente l’ensemble des valeurs qui n’appartiennent pas à A. Elle est ici représentée par la zone finement hachurée :
images/02DP12.png
L’union de A et B est dite A OU B et se note A images/U.png B. Elle représente l’ensemble des valeurs appartenant à l’un ou l’autre des ensembles. Elle est ici représentée par la zone finement hachurée :
images/02DP13.png
Enfin, l’intersection lue A ET B et notée A images/Uinverse.png B, représente l’ensemble des valeurs appartenant aux deux ensembles en même temps. Elle est ici représentée par la zone finement hachurée commune aux ensembles :
images/02DP14.png

2. Opérateurs...

Création de règles

1. Règles en logique booléenne

Dans un système classique, comme le contrôle du store du début de ce chapitre, une règle s’exprime sous la forme :


SI (condition précise) ALORS action
 

On a par exemple :


SI (température ⩾ 25°) ALORS baisser le store
 

On peut aussi concevoir des règles plus complexes. Par exemple, on pourrait prendre en compte l’éclairage extérieur, qui se mesure en lux (car s’il y a du soleil, il faut s’en protéger). Il va de 0 (nuit noire sans étoile ni lune) à plus de 100 000 (éclairage direct du soleil). Un ciel nuageux de jour correspond à un éclairage entre 200 et 25 000 lux environ (selon l’épaisseur de nuages).

Dans notre application de contrôle de store, on pourrait donc créer la règle :


SI (température ⩾ 25° ET éclairage ⩾ 30 000 lux) ALORS baisser le store
 

Cela pose cependant des problèmes lorsque les températures mesurées ou l’éclairage sont proches des valeurs limites.

2. Règles floues

Dans un système flou, les règles utilisent des valeurs floues au lieu des valeurs numériques. On note les expressions utilisées dans les règles sous la forme :


"Variable linguistique" EST "valeur linguistique"...

Fuzzification et défuzzification

1. Valeur de vérité

Les différentes règles possèdent toutes une implication (la clause ALORS). Il va donc falloir exprimer à quel point la règle doit être appliquée en fonction des valeurs numériques mesurées : c’est l’étape de fuzzification.

Nous allons nous intéresser à la règle R8 :


SI température EST bon ET éclairage EST moyen ALORS store EST 
à mi-hauteur
 

Nous souhaitons savoir à quel point cette règle s’applique pour une température de 21°C et un éclairage de 80 000 lux.

On va donc commencer par chercher à quel point il fait BON. La figure suivante nous indique qu’à 21°C, il fait bon à 80 %.

images/02DP23.png

Nous cherchons ensuite à quel point l’éclairage est MOYEN pour 80000 lux. On peut lire qu’il l’est à 25 % :

images/02DP24.png

La règle contient donc une partie vraie à 80 % et une partie vraie à 25 %. On dira que la règle entière est vraie à 25 %, la valeur minimale (opérateur ET). C’est donc le terme le moins vrai qui donne la valeur de vérité d’une règle entière. 

2. Fuzzification et application des règles

On cherche maintenant à savoir quel sera le résultat de cette règle. Elle nous dit que le store doit être à mi-hauteur. On sait que la règle s’applique à 25 %.

On a alors de nombreux choix pour l’opérateur d’implication afin de déterminer l’ensemble flou résultant. Nous allons nous intéresser à deux d’entre eux : l’implication d’après Mamdani et celle d’après Larsen. Ce qui change entre les deux, c’est la forme de l’ensemble flou d’arrivée.

Pour l’opérateur d’implication de Mamdani, l’ensemble flou est troqué à la valeur de vérité de la règle. Pour notre règle R8 qui s’applique à 25 %, on obtiendrait donc la sortie suivante.

images/02DP25.png

Pour l’opérateur d’implication...

Domaines d’applications

Zadeh a posé les bases théoriques de la logique floue en 1965. Les pays occidentaux ne se sont pas vraiment intéressés à cette technique à ses débuts. Au contraire, le Japon a très vite compris son intérêt, suivi plusieurs années plus tard par le reste du monde.

1. Première utilisation

Dès 1987, le premier train contrôlé par un système à base de règles floues a vu le jour à Sendai, une ville à moins de 400 km au nord de Tokyo. Les ingénieurs voulaient alors maximiser le confort des voyageurs et minimiser la consommation d’énergie alors que le véhicule devait faire de nombreux changements de vitesse. La vitesse du train est donc le résultat de la logique floue.

Il s’est avéré que la consommation d’énergie a baissé de 10 % par rapport à un conducteur humain, et que les passagers vantent tous la souplesse de la conduite, principalement lors des arrêts et départs.

Il est toujours en circulation et a été le premier grand succès commercial de la logique floue.

2. Dans les produits électroniques

De nombreux autres constructeurs ont compris qu’un contrôleur flou pouvait améliorer le fonctionnement des machines qui nous entourent.

C’est ainsi que l’on est aujourd’hui...

Implémentation d’un moteur de logique floue

Cette partie indique comment coder un moteur de logique floue, en utilisant les choix préconisés précédemment. Ce code est en C#, mais il peut facilement être adapté à n’importe quel autre langage objet. Il est compatible avec le framework .NET 4.5 (et les versions suivantes), et Windows 8 et supérieur.

Lorsque des connaissances en mathématiques sont nécessaires, les formules utilisées sont expliquées.

1. Le cœur du code : les ensembles flous

a. Point2D : un point d’une fonction d’appartenance

Nous allons commencer par créer les classes de base. Pour cela, il nous faut d’abord une classe Point2D qui nous permet de donner les coordonnées d’un point représentatif des fonctions d’appartenance. L’axe des abscisses (x) représente la valeur numérique et l’axe des ordonnées (y) la valeur d’appartenance correspondante, entre 0 et 1.

La base de cette classe est donc la suivante :


using System; 
  
public class Point2D  
{ 
  public double X { get; set; } 
  public double Y { get; set; } 
 
  public Point2D(double x, double y) 
  { 
    this.X = x; 
    this.Y = y; 
  } 
}
 

Ultérieurement, il faudra comparer des points pour connaître leur ordre. Plutôt que de devoir comparer nous-mêmes les coordonnées x des points, nous allons faire implémenter l’interface IComparable à cette classe. Il faut donc modifier l’en-tête pour le suivant :


public class Point2D : IComparable
 

Il faut ensuite ajouter la méthode CompareTo, qui permet de savoir si le point passé en paramètre est plus petit, égal ou plus grand que l’objet en cours (la méthode doit renvoyer respectivement un nombre positif, nul ou négatif). On se contente donc de faire la différence des abscisses :


  public int CompareTo(object obj) 
  { 
    return (int)(this.X - ((Point2D) obj).X); 
  }
 

Enfin, la méthode ToString() permet de faciliter l’affichage :


  public override String ToString() 
  { 
    return "(" + this.X + ";" + this.Y + ")"; 
  }
 

b. FuzzySet : un ensemble flou

La principale classe de notre programme, autant en termes de lignes de code que d’importance, est l’ensemble flou (ou FuzzySet en anglais). Elle est constituée d’une liste de points qui seront triés selon l’axe x, et de deux valeurs particulières : le minimum et le maximum que pourront prendre les valeurs numériques.

Cette...

Implémentation d’un cas pratique

Nous allons utiliser la logique floue pour contrôler un GPS de voiture, plus précisément le niveau de zoom. En effet, en fonction de la distance au prochain changement de direction et de la vitesse à laquelle on roule, le niveau de zoom utilisé n’est pas le même : lorsqu’on se rapproche d’un changement de direction ou que l’on ralentit, le zoom augmente pour nous montrer de plus en plus de détails.

Pour avoir un rendu fluide et non saccadé, un contrôleur flou est donc utilisé. Pour cela, on commence par créer une nouvelle classe contenant juste une méthode Main pour le moment (qui boucle, pour permettre de conserver les affichages ensuite) :


using System; 
  
public class ZoomGPS 
{ 
  static void Main(string[] args) 
  { 
    // Le code sera placé ici 
    while (true) ; 
  } 
}
 

On commence par créer un nouveau contrôleur flou dans le main :


    // Création du système 
    FuzzySystem system = new FuzzySystem("Gestion du zoom GPS");
 

L’étape suivante consiste à définir les différentes variables linguistiques. Nous en aurons trois : Distance et Vitesse en entrée, et Zoom en sortie. Pour la distance  (en mètres jusqu’au prochain changement de direction), on va créer trois variables linguistiques : "faible", "moyenne" et "grande". On fera aller la distance jusqu’à 500 000 m, soit 500 km, ce qui représenterait le fait de suivre une autoroute sur une grande distance.

Voici le schéma reprenant ces ensembles flous :

images/02DP37.png

Au niveau du code, on va donc créer la variable linguistique, puis lui ajouter les trois valeurs linguistiques, et enfin ajouter cette variable comme entrée au système :


    Console.WriteLine("1) Ajout des variables"); 
    // Ajout de la variable linguistique "Distance" (de 0 à 500 000 m) 
    LinguisticVariable distance = new LinguisticVariable("Distance", 
0, 500000); 
    distance.AddValue(new LinguisticValue("Faible", new 
LeftFuzzySet(0, 500000, 30, 50))); 
    distance.AddValue(new LinguisticValue("Moyenne", new 
TrapezoidalFuzzySet(0, 500000, 40, 50, 100, 150))); 
    distance.AddValue(new LinguisticValue("Grande", new 
RightFuzzySet(0, 500000, 100, 150))); 
    system.addInputVariable(distance);
 

On procède de même avec la vitesse. Voici les différentes valeurs et les ensembles flous correspondants (on s’arrêtera à 200 km/h)...

Synthèse

La logique floue permet de prendre des décisions en fonction de règles imprécises, c’est-à-dire dont l’évaluation est soumise à interprétation.

Pour cela, on définit des variables linguistiques (comme la température) et on leur associe des valeurs linguistiques ("chaud", "froid"...). À chaque valeur, on fait correspondre un ensemble flou, déterminé par sa fonction d’appartenance : pour toutes les valeurs numériques possibles, elle associe un degré d’appartenance entre 0 (la valeur linguistique est totalement fausse) et 1 (elle est totalement vraie), en passant par des stades intermédiaires.

Une fois les variables et valeurs linguistiques déterminées, les règles à appliquer sont indiquées au système flou. On lui donne ensuite les valeurs numériques mesurées.

La première étape pour fournir une décision est la fuzzification qui consiste à associer à chaque valeur numérique son degré d’appartenance aux différentes valeurs linguistiques. Les règles peuvent alors être appliquées, et la somme des règles (constituée par l’union des ensembles flous résultants) fournit un nouvel ensemble flou.

La défuzzification est l’étape permettant...