View
0
Download
0
Category
Preview:
Citation preview
page 1
Manage Yourself
Rapport de pré-étude
Projet de 4ème année informatique
Equipe :
Etienne Alibert, Florian Barbedette, Pierre Chesneau, Mathias Deshayes, Sevan Hartunians, Mathieu Poignet. Encadrant :
Laurence Rozé
Le 20/10/09
page 2
Sommaire A. Présentation du projet ................................................................................................... 5
1. Présentation de Telelogos ........................................................................................ 5
2. Présentation de DREAM ........................................................................................... 5
3. But du projet ............................................................................................................. 6
4. Description technique .............................................................................................. 6
B. Windows mobile ............................................................................................................ 7
1. Présentation de l’operating system .......................................................................... 7
2. Types de développement sur Windows Mobile ....................................................... 8
a. Langages de programmations .................................................................................. 8
b. Environnement de développements ........................................................................ 8
3. Nos choix .................................................................................................................. 9
4. Programmes de tests ................................................................................................ 9
a. « Hello world » .......................................................................................................... 9
b. «Accès aux informations système» ........................................................................ 10
C. Les Systèmes Experts ................................................................................................... 10
1. Introduction ............................................................................................................ 10
2. Anatomie d'un système expert............................................................................... 11
a. Les composants d'un système expert ..................................................................... 11
b. Description des éléments ....................................................................................... 11
3. Le moteur d'inférence ............................................................................................ 12
a. Les connaissances du moteur d'inférence .............................................................. 12
b. Les raisonnements du moteur d'inférence............................................................. 13
c. Le chaînage avant ................................................................................................... 13
d. Le chaînage arrière ................................................................................................. 13
4. Conclusion .............................................................................................................. 14
D. Les systèmes experts existants .................................................................................... 14
1. Nos critères ............................................................................................................. 14
a. Le chaînage : ........................................................................................................... 14
b. Les contraintes des données .................................................................................. 14
c. Les contraintes de l’embarqué ............................................................................... 14
d. La licence ................................................................................................................ 14
e. Le langage de programmation ................................................................................ 14
page 3
2. Révision des critères ............................................................................................... 15
3. Les Framework retenus .......................................................................................... 16
a. Drools.net ............................................................................................................... 16
b. NXBRE ..................................................................................................................... 17
c. Simple Rule Engine ................................................................................................. 17
4. Bilan : Les choix possibles ....................................................................................... 18
E. Apprentissage .............................................................................................................. 18
1. Introduction ............................................................................................................ 18
2. La classification ....................................................................................................... 19
3. Algorithmes de classification .................................................................................. 21
a. Le Find-S algorithme. .............................................................................................. 21
b. Espace des versions ................................................................................................ 22
4. Arbres de décisions ................................................................................................. 22
5. Conclusion .............................................................................................................. 24
F. Conclusion.................................................................................................................... 25
G. Annexes ....................................................................................................................... 26
1. Code de l’application Hello world........................................................................... 26
2. Code de l’application d’obtention des données ..................................................... 27
a. Form1.cs ................................................................................................................. 27
b. Mem.cs ................................................................................................................... 28
3. Planification ............................................................................................................ 30
page 4
A notre époque, avec l'avènement des nouveaux moyens de communications, les
téléphones mobiles sont de plus en plus répandus. Parmi ces derniers, les assistants personnels ou
PDA connaissent un développement important. Ces derniers, comme toutes technologies, ne sont
pas exempts de problèmes techniques. Il devient donc important de pouvoir effectuer des
diagnostics sur les PDA.
Notre projet de 4ème année en informatique à l'INSA de Rennes consiste ainsi à développer
un outil permettant d'effectuer des diagnostics sur les assistants personnels. Pour se faire un petit
système expert peut être embraqué sur les PDA. Un exemple de règle peut être de vider
automatiquement certains répertoires lorsque la mémoire du PDA est saturée. Il est difficile de
prévoir toutes les règles du système expert à l’avance, c’est pourquoi il est possible d’envisager de
mettre en place un module d’apprentissage pour conclure de nouvelles règles. Ce module se situerait
sur un serveur et centraliserait toute les situations non reconnues sur l’ensemble des PDA abonnés
au service de diagnostic.
Le présent rapport contient la pré-étude de ce projet qui nous a permis de bien
comprendre le sujet (que nous présenterons en détail dans la première section), de nous renseigner
sur les technologies qui seront nécessaires au projet (ces technologies seront présentées dans la
deuxième section), d’étudier les systèmes experts et les outils de génération et d’implémentation de
ces derniers (que nous étudierons dans la partie 3), et enfin d’explorer quelques notions
d’apprentissage (notions que nous présenterons dans la partie 4).
page 5
A. Présentation du projet Manage Yourself est un projet de diagnostique et surveillance de plates-formes
embarquées, il s'inscrit dans le cadre d'une collaboration entre Telelogos et DREAM. Telelogos est
une entreprise éditant des logiciels professionnels qui automatisent, administrent et optimisent les
processus d’échanges entre système informatique central et ceux des utilisateurs distants. DREAM
est une équipe de recherche de l'IRISA spécialisée dans l'aide à la surveillance et au diagnostic de
systèmes évoluant dans le temps.
Le besoin de développer une telle application émane de Telelogos, qui, dans le cadre d’un
programme de formation aux technologies d’innovation cherche à développer deux logiciels
concepts. Ces logiciels concepts ont pour but de tester la faisabilité de la mise en œuvre de
technologies d’innovation et de créer un nouveau pôle d’activité autour de cette technologie si le
résultat s’avère concluant. Manage Yourself est l’un de ses logiciels, ayant pour but d’explorer les
possibilités dans le domaine du MBM (Mobile Device Management).
1. Présentation de Telelogos
Telelogos est une entreprise spécialisée dans la conception de middleware de
synchronisation de données, de gestion de parc informatique et d'administration de terminaux
distants. Ces logiciels s’adressent aux marchés de la grande distribution (point de vente, agence,
galerie marchande), de l’entreprise (siège, site de production), de la communication (agence de
communication, régie publicitaire). A ce jour, 250 000 logiciels Telelogos sont en exploitation dans le
monde. 2 000 grands comptes ou PME les utilisent quotidiennement pour gérer leurs échanges de
données stratégiques : Altadis, Dalkia, Danone, Dim, Guilbert, Hasbro, Kraft Food, Krys, L’Oréal,
Mattel, Midas, Nestlé, Picard, Pierre Fabre, Roche, Saupiquet, Skis Rossignol, Speedy, Unilever, Yves
Rocher...
Telelogos à été crée en 1982 a partir du service informatique de la société Les ardoisières
d’Angers. Jusqu’à 1995, la société exerce des activités de société de service et de revendeur. En 1996
elle s’oriente vers l’édition de logiciels et lance TEL96++, logiciel de transfert de fichiers automatisé et
sécurisé pour les plates-formes DOS et UNIX. En 1997 est lancé la commercialisation de la première
version de MediaTransfer, logiciel de synchronisation de fichiers automatisée pour Windows
s’intégrant dans les environnements TCP/IP. En 2001 MediaContact version 1, logiciel
d’administration et de synchronisation dédié à l’informatique distante mobile et fixe, est lancé. En
2005 Telelogos package les fonctionnalités les plus demandées de MediaContact, ainsi, le produit se
décline en trois logiciels clef-en-main dédiés respectivement à l’administration des terminaux
mobiles, à la synchronisation des applications et à la sauvegarde des données. En 2007, le lancement
de Media4Display, plate-forme de gestion et de diffusion de contenu multimédia destinée à
l’affichage dynamique et à la PLV numérique, constitue un ouverture des activités de Telelogos vers
des applicatifs métiers.
2. Présentation de DREAM
L’IRISA (Institut de Recherche en Informatique et Systèmes Aléatoires), créé en 1975, est
une unité mixte de recherche (UMR 6074) dont les établissements partenaires sont le CNRS,
l’Université de Rennes 1, l’Insa de Rennes et l’ENS Cachan (antenne de Bretagne). L’Irisa est associé à
l’INRIA à travers un nombre important d’équipes communes au sein du centre Inria Rennes –
Bretagne Atlantique.
page 6
DREAM est l'une de ces équipes dont le thème principal de recherche est l'aide à la
surveillance et au diagnostic de systèmes ou activités complexes évoluant dans le temps. Il s'agit
d'inférer l'état d'un système à partir d'observations issues de capteurs afin de détecter et de
caractériser un éventuel dysfonctionnement de ce système, l’idéal étant d’aller jusque la réparation
du système. Les principaux axes de recherche de l’équipe sont :
L’acquisition automatique de modèles en utilisant des techniques d'apprentissage symbolique à partir d'exemples telles que la PLI (Programmation Logique Inductive).
Le développement d'algorithmes efficaces utilisant la notion de diagnostiqueur (inversion et compilation du modèle). Ces algorithmes produisent un modèle compact liant directement observations et pannes.
L’interaction entre diagnostic et décision dans un univers incertain. Les domaines d'application de l’équipe DREAM sont :
le monitoring cardiaque : l’analyse en ligne d'électrocardiogrammes, l’étude de prothèses cardiaques "intelligentes" : stimulateurs et défibrillateurs.
La protection de l'environnement : amélioration de la classification de parcelles agricoles à partir d'images de télédétection, modélisation qualitative du transfert de polluants tels que pesticides et nitrates
Le diagnostic industriel : supervision de réseaux de télécommunications et de distribution d'électricité.
3. But du projet
Le but du projet est de développer une plate forme de surveillance sur des appareils de type
Smartphone ou PDA, fonctionnant sous Windows mobile. L'application de surveillance sera
embarquée sur l'appareil mobile. Elle sera constamment au courant de l'état du système et sera
capable de détecter les situations problématiques et d'y remédier d'une façon complètement
transparente pour l'utilisateur.
L'application saura reconnaitre et réagir à une situation problématique grâce a un
ensemble de règles. Un exemple de règle serait « Si il n'y a pas assez de mémoire alors supprimer les
fichiers temporaires ». Ces règles auront été au préalable téléchargées sur un serveur distant.
D'autre part si l'application de surveillance n'a pas réussi à empêcher la défaillance de l'appareil, elle
devra, dès qu'elle pourra se connecter au serveur, envoyer un bilan de la situation de l'appareil juste
avant le problème encouru. L'objectif étant, à terme, de pouvoir apprendre de ces données
remontées sur le serveur afin de générer de nouvelles règles permettant des traiter les problèmes
ayant provoqués des erreurs.
4. Description technique
Le projet contient donc deux parties, d'une part l'application embarquée, d'autre part
l'application côté serveur.
Le serveur contient toutes les règles disponibles au téléchargement par les appareils mobile
ainsi que l'application embarquée permettant la surveillance du système. Lorsqu'un client s'abonne
au service de surveillance il télécharge l'application embarquée contenant un système expert ainsi
que toutes les règles adaptées à l'appareil.
page 7
L'application embarquée opère une surveillance périodique du système en générant des
rapports d'état du système contenant des informations telles que la charge processeur, la mémoire
disponible, ou encore les processus lancés. Ces rapports sont ensuite passés au système expert qui
teste toutes les règles qu'il contient sur ce rapport, ils seront également sauvegardés sous forme de
fichiers. Grâce à ces règles le système expert va déterminer si l'appareil est dans une situation
problématique et effectuer les actions nécessaires afin d’éviter les défaillances de l’appareil.
Toutes les situations problématiques n'auront pas pu être prises en compte avec les règles
initialement présentes sur le serveur. Ainsi lorsque l'appareil rencontre un problème pour lequel
aucune règle n'a été reconnue, il envoie au serveur les derniers rapports d'état du système. Le but
étant, à terme, d'apprendre de ces rapports d'erreur afin de générer automatiquement de nouvelles
règles permettant de prévenir le problème rencontré.
L'application présente sur le serveur permet de recevoir les rapports des appareils ayant
rencontré une défaillance. Grâce au déploiement de l'application sur une flotte d'appareils mobile, le
programme sera capable de déduire les causes de défaillances à partir de ces rapports. Enfin, elle
fournit une interface administrateur permettant de définir de nouvelles règles pouvant être ajoutées
à la base de règles existante.
Une des contraintes du projet est le développement sous Windows Mobile, nous allons donc
nous pencher sur ce système d’exploitation.
B. Windows mobile
1. Présentation de l’operating system
Windows mobile est le nom du système d’exploitation pour Smartphones et PDA de
Microsoft. Ce logiciel permet une compatibilité transversale de la plateforme mobile vers le monde
PC. De nombreuses versions sont sorties, cependant nous nous intéresserons uniquement à la
version 6. En effet cette version est la plus rependue sur le marché actuel des plateformes mobiles.
Ce système d’exploitation existe sous 3 versions différentes :
Une version standard pour les Smartphones. Une version classique pour les PDA sans fonction téléphonique. Une version professionnelle intégrant une fonction téléphonique.
Windows Mobile 6 ajoute certaines améliorations au système d’exploitation :
Le support de Windows Vista. L’indexage des fichiers qui facilite la recherche. Le support de la téléphonie par VoIP (voix sur réseaux IP permettant de communiquer
avec les accès réseaux basés sur le protocole TCP/IP comme Internet). La compatibilité avec les nouveaux logiciels (Office 2007, Windows Live Messenger, la
Wifi, le Bluetooth, …).
Dans cette partie, nous nous intéresserons aux moyens de développement ainsi
qu’aux différentes possibilités qui nous sont proposés. En effet le développement sous Windows
page 8
mobile est un peu particulier car il requiert des outils spéciaux (Le SDK Windows mobile 6.0, le
compact Framework qui est inclus dans Visual Studio et un émulateur). L’émulateur permet de
simuler un déploiement de l’application sur un terminal mobile.
2. Types de développement sur Windows Mobile
Plusieurs possibilités sont offertes au développeur sur plateforme mobile. Le choix le plus
crucial est celui du langage car il va déterminer toute la suite d’outils à utiliser pour le codage ainsi
que le temps passé sur la réalisation du produit.
C’est dans ce cadre que nous nous sommes penchés sur les différents langages mis à notre
disposition.
a. Langages de programmations
Langages supportant le .NET Framework
Le développement pour Windows mobile peut-être simplifié en utilisant le compact
Framework de Microsoft qui permet le support de code managé (code dans lequel la gestion
mémoire est gérée par l’interpréteur). Ce compact Framework est un sous-ensemble du .NET
Framework, certaines classes sont communes avec le .Net Framework mais d’autres sont spécifiques
à la version compact.
. Les langages utilisant ce Framework permettent une meilleure productivité et rapidité
d’exécution car ils utilisent la plateforme .NET qui est native sur Windows Mobile. Nous pouvons
utiliser les Framework Windows avec les langages C# ou C++. Cependant, le C# offre la possibilité
d’utiliser du code managé (option débrayable). De plus, étant de plus haut niveau, le C#, permet un
gain de temps appréciable et un niveau d’abstraction important. A contrario, le C++ offre une grande
vitesse d’exécution car il est compilé, mais sa syntaxe le rend moins apte à manier des donnés
abstraites. Cette caractéristique est primordiale pour ce projet car nous allons manipuler un moteur
d’inférence et des ensembles de règles.
Java
Une machine virtuelle Java est présente sous Windows mobile, mais elle est très légère et
beaucoup de fonctionnalités ne sont pas implémentables. En outre elle ne supporte pas le
Framework « .NET » de Microsoft et ceci réduit donc énormément son intérêt.
b. Environnement de développements
Visual Studio 2008
Visual Studio est l’outil de développement de Microsoft qui permet de réaliser facilement
des applications avec une interface graphique tout en utilisant toutes les librairies .NET. Pour
développer sous Windows Mobile avec Visual Studio il est nécessaire d’installer le mobile SDK qui
fournit le compact Framework ainsi qu’un émulateur pour tester les applications avant de les charger
dans le mobile. De plus l’entreprise Telelogos travaille également avec Microsoft Visual Studio et il
est important que nous travaillions avec les mêmes outils pour pouvoir partager notre travail.
page 9
Eclipse
Pour développer les applications JAVA pour Windows Mobile on peut utiliser Eclipse, mais il
faut installer le plugin JAVA Mobile. On ne pourra ainsi utiliser que les quelques classes présentes
sous Windows Mobile.
3. Nos choix
Pour notre projet nous avons besoin d’accéder aux propriétés du mobile à assez bas niveau.
Le SDK JAVA Mobile ne permet pas cela. De plus l’entreprise avec laquelle nous travaillons à pour
habitude de développer avec la plateforme .NET et sous Microsoft Visual Studio 2005. Cela ne leur
pose pas de problème si nous développons sous MVS2008 à condition que nous leur envoyions les
projets en format 2005. Nous avons donc choisi de développer en C# sous Microsoft Visual Studio
2008.
4. Programmes de tests
a. « Hello world »
Notre premier programme avait pour but de nous familiariser avec Microsoft Visual Studio
et le SDK Windows Mobile. Il consiste juste à afficher un texte à l’écran et à quitter le programme de
manière convenable si l’utilisateur appuie sur le bouton central du téléphone.
Le déploiement sur le mobile est très simple, il suffit en effet de transférer le fichier .exe
créé par Visual Studio dans le mobile puis de l’exécuter. La figure ci-dessous montre le résultat de
l’exécution de notre programme.
Figure 1: Hello World sur émulateur
page 10
b. «Accès aux informations système»
Notre deuxième programme avait pour but de capturer des informations système. Nous
avons choisis d’afficher toutes les informations mémoires du portable. Pour cela nous avons eu
besoin d’utiliser la DLL coreDLL qui contient toutes les méthodes d’accès système du mobile.
Figure 2: Affichage des informations mémoire
Le code développé sous Windows Mobile nous permettra d’implémenter notre système
expert. Étudions alors l’anatomie d’un système expert.
C. Les Systèmes Experts
1. Introduction
La notion de système expert est une notion assez ancienne qui est apparue dans les années
70 avec l’apparition du système expert MYCIN dont le but est d’aider les médecins à effectuer le
diagnostic de maladies infectieuses du sang. Les systèmes experts ont comme finalité la modélisation
de la connaissance et du raisonnement d’experts dans un domaine donné fixé. Un système expert se
page 11
compose généralement de trois parties: une base de faits, une base de règles, et un moteur
d'inférence.
La plupart des systèmes experts existants reposent sur des mécanismes de logique formelle
et utilisent le raisonnement déductif. Pour l'essentiel, ils utilisent la règle d'inférence suivante: Si P
est vraie, et si on sait que P implique Q, alors Q est vraie.
Les plus simples des systèmes experts s'appuient sur la logique des propositions, ou sur la
logique des prédicats du premier ordre, que des algorithmes permettent de manipuler aisément.
Analysons alors plus précisément l'anatomie d'un système expert, ainsi que le fonctionnement d'un
moteur d'inférence.
2. Anatomie d'un système expert
a. Les composants d'un système expert
Un système expert est composé comme suit :
Il est important de noter la séparation entre les connaissances et l’inférence.
b. Description des éléments
La base de faits
La base de faits contient à tout moment les faits donnés par l’administrateur ou obtenus par
le système. C'est la mémoire de travail du système expert. Temporaire, elle est modifiée au fur et à
mesure de la progression du raisonnement, et vidée lorsqu'un traitement se termine.
La base de connaissances
La base de connaissances rassemble la connaissance et le savoir-faire du spécialiste dans
son domaine. On distingue donc deux sortes de connaissances: les connaissances indiscutables
constituant le savoir de l'expert; et les connaissances intuitives regroupant les convictions
Interface
Editeur
Moteur
d’Inférence
Explication
Base de
Connaissance
------------------------
Base de Règles
Utilisateur
page 12
personnelles de l'expert (également appelées connaissances « heuristiques »). Le formalisme le plus
communément répandu pour représenter la base de connaissances est celui des règles de
production. On parle alors de base de règles. Un règle étant une expression de la forme: « Si
<condition> alors <action> ; ce qui permet généralement d'ajouter de nouveaux faits. L’éditeur
permet quant à lui, d’éditer des connaissances dans la base.
Le moteur d'inférence
Le moteur d'inférence est un programme qui met en œuvre des mécanismes généraux
d'interprétation des connaissances d'un domaine particulier. Selon des heuristiques, et des stratégies
variées, souvent extérieures au domaine d'application, le moteur interprète les connaissances
jusqu'à satisfaire des conditions d'arrêt. En général, l'action du moteur provoque des modifications
de la base de faits et même parfois de la base de règles. Le moteur est surtout caractérisé par sa
stratégie de raisonnement, nommée chaînage, pour utiliser les connaissances. On distingue deux
types de stratégies: le chaînage avant et le chaînage arrière. En chaînage avant, le moteur essaye
d'obtenir tous les faits déductibles à partir des règles dont les conditions sont vérifiées par des
éléments de la base de faits. Chaque fois qu'une règle est déclenchée, le moteur utilise les nouveaux
faits obtenus pour activer d'autres règles. Il s'arrête lorsqu'un but est atteint ou qu'aucun fait ne peut
plus être déduit. Le chaînage avant est utilisé lorsque l'on n'a pas d'idée précise sur l'objectif à
atteindre. En chaînage arrière, le moteur cherche à atteindre un ou plusieurs buts considérés comme
des hypothèses ou des problèmes à résoudre. Pour cela, il essaye d'appliquer les règles qui
« concluent sur ces buts ». Le chaînage arrière s'avère alors judicieux lorsque l'on a un but précis à
atteindre.
La stratégie de raisonnement d'un moteur d'inférence comporte donc trois phases: la
détection des règles intéressantes, la sélection de la règle à appliquer, et le déclenchement de la
règle retenue.
3. Le moteur d'inférence
a. Les connaissances du moteur d'inférence
Les systèmes experts disposent, pour simuler le raisonnement humain, de formalismes de
représentation des connaissances. Les connaissances utilisées doivent rendre compte d'une
représentation des objets manipulés, de leurs relations, et si possible, de leur sémantique. La grande
majorité des systèmes experts actuels utilise les règles de production comme moyen de
représentation des connaissances. Un règle de production est une expression de la forme: si
ANTECEDENTS alors CONCLUSIONS.
Un antécédent étant la description d'une situation représentée dans un formalisme
approprié (en général, cette condition est mise sous la forme d'une conjonction de faits); et une
conclusion étant une action à envisager si la situation décrite par les antécédents est réalisée (cette
action est aussi, généralement, une conjonction de plusieurs faits).
La base de connaissances est formée d'un ensemble de règles établies de façon purement
énonciative. Chaque règle est constituée de son action et des conditions de son application. Le
déclenchement des règles s'obtient par comparaison de leurs conditions avec des éléments de la
base de faits.
page 13
b. Les raisonnements du moteur d'inférence
Les modes de raisonnement du moteur d'inférence (chaînages avant et arrière) se
réduisent à un enchainement de cycles de base. Chaque cycle de base comprend trois phases:
détection, choix ou résolution de conflit, application.
Durant la phase de détection, le moteur recense toutes les règles pouvant être mises en
œuvre pour donner la solution cherchée.
De plus, pour détecter les connaissances intéressantes à utiliser, le moteur dispose de
différentes stratégies de résolution de conflit. Ces stratégies ont pour objectif d'orienter la recherche
intelligemment pour obtenir la ou les solutions. A chaque cycle de base, il convient de décider quelle
règle appliquer en priorité. On peut de plus, par exemple, choisir les règles à l'aide de métarègles qui
désignent quelles règles utiliser en fonction de l'état courant de nos connaissances sur le sujet traité.
Grâce à ces métarègles, l'étape de résolution des conflits est directement liée aux spécificités du
problème rencontré. Chaque système possède ses propres heuristiques de choix de déclenchement
des règles.
Durant la dernière étape (l'application), le moteur déclenche la ou les règle(s) retenue(s)
lors de la résolution de conflit. Son action provoque soit l'insertion de nouveaux faits, soit la
vérification d'hypothèses. Si le but recherché est atteint, les déductions sont stoppées. Si aucune
règle n'est déclenchée, le moteur s'arrête ou reconsidère l'étape précédente. C'est au cours de la
phase de déduction que sont testées les conditions d'arrêt du moteur.
c. Le chaînage avant
Le mode de raisonnement sous-jacent des systèmes de production est le modus-ponens.
Ainsi, en chaînage avant, la règle « si A alors B » ne peut être déclenchée que si toutes les conditions
exprimées par A apparaissent dans la base des faits. Le fait B peut alors y être inséré. Le système
sélectionne des règles en s'appuyant sur ce qu'il connait du cas particulier, et en déclenche une, ou,
s’il manque de données, demande des informations supplémentaires. Les conclusions obtenues
viennent enrichir la base de faits jusqu'à saturation de la base de connaissances, ou jusqu'à ce que le
but fixé soit atteint. Le risque du chaînage avant est de déduire des faits inintéressants. La résolution
doit donc être particulièrement critique. En revanche, avec ce raisonnement, l'interprétation permet
une formalisation naturelle des connaissances. En chaînage avant, le raisonnement est donc guidé
par les données.
d. Le chaînage arrière
Le raisonnement en chaînage arrière est guidé par le but à atteindre. On assigne au
système un but hypothétique et recherche la façon de le prouver. Il choisit donc une règle
permettant d'y aboutir et essaye d'en vérifier chaque prémisse. Si les prémisses appartiennent à la
base des faits, le problème est résolu. Sinon, les conditions non vérifiées deviennent des sous-buts à
prouver, et on réitère le processus jusqu'à vérification des prémisses de la règle initialement
considérée. Si celle-ci n'a pu être déclenchée, le système en recherche une autre permettant
d'aboutir au but fixé. L'avantage d'une telle démarche réside dans le fait que seules les règles
participant à la démonstration du but sont prises en compte.
page 14
4. Conclusion
Le moteur d'inférence constitue la partie mécanique d'un système expert. Ses techniques
de réalisations peuvent avoir différents caractères de différenciation, différents modes de résolution
et de raisonnements logiques... C'est pourquoi la base de connaissances d'un domaine d'expertise
quelconque spécialise un moteur d'inférence, et le transforme en système expert. Celle-ci caractérise
alors véritablement la qualité d'un système expert.
Nous allons donc étudier ces différentes possibilités pour la réalisation de notre système
expert, ainsi que l'existant dans la partie suivante.
Plutôt que de nous lancer directement dans le développement d’un moteur d’inférence
nous avons examiné l’existant et tenté de déterminer si nous pouvions réutiliser une bibliothèque de
moteur d’inférence existante.
D. Les systèmes experts existants
1. Nos critères
a. Le chaînage :
Il existe deux types de moteur d’inférence : les moteurs d’inférence fonctionnant en
chainage avant, et les moteurs d’inférence fonctionnant en chainage arrière :
Au vu de la base de règles que nous utiliserons, ainsi que de la puissance de calcul
disponible sur un Smartphone (le chainage avant étant plus complexe à mettre en œuvre), nous
avons choisi d’utiliser le chainage avant.
b. Les contraintes des données
Notre objectif étant de créer un moteur capable d’effectuer de la maintenance sur un
système, il faut que le moteur d’inférence soit capable de chainer des règles, et non de simplement
inférer des données statistiques.
c. Les contraintes de l’embarqué
Notre projet ayant pour vocation de tourner sur un système embarqué, il faut que le
moteur d’inférence que nous choisissons soit léger et performant.
d. La licence
Notre projet pouvant devenir à terme un logiciel commercial, il faudrait idéalement que les
outils que nous utilisons soient sous des licences compatibles avec un produit commercial. Dans ce
cadre, seule quelques licences correspondent, entre autre la licence LGPL, le domaine publique, et
certaines versions des licences CeCill.
e. Le langage de programmation
Le langage dans lequel est développé le moteur est également un problème potentiel : en
effet, le Smartphone ne dispose pas d’interpréteur/de compilateur pour tout les langages. De plus le
projet devant être développable sous Visual studio 2005, les langages potentiels se ramènent alors
au C,C++,C#, possiblement avec le « .net Compact Framework » (abrégé .net CF). Le langage java ne
fait pas partie des possibilités, éliminant de fait une partie importante des moteurs utilisables.
page 15
Ces critères étant trop restrictif (une simple requête sur moteur de recherche pourra vous
en convaincre), il nous a paru judicieux de revoir nos critères.
2. Révision des critères
Nous avons alors choisi de rechercher les moteurs d’inférence qui :
• Soit correspondaient exactement à nos critères (comme précédemment),
• Soit pouvaient correspondre au prix de modifications mineures à nos critères.
Quels critères peuvent être revus à la baisse ?
Le critère sur le langage n’est clairement pas négociable, il dépend du cahier des charges
original (demande de Télélogos). Le critère de légèreté n’est pas non plus négociable, étant
justement le cœur du projet. Le seul élément sur lequel nous avons une marge de manœuvre est
l’utilisation du .net framework. En effet, sous Windows mobile, seul le .net CF est disponible, mais le
.net Framework « classique » est extrêmement corrélé à celui-ci, il est donc possible d’adapter une
application basée sur .net vers .net CF, au prix de retouches légères (si toutefois le moteur
sélectionné est basé sur les éléments communs à .net et .net CF).
page 16
Ci-dessous un extrait du poster de présentation des namespaces présents dans les deux
Framework. Vous y noterez l’absence de System.XML.Xpath dans .net CF. Namespace utilisé le plus
fréquemment pour l’analyse de fichier XML.
Figure 3: extrait du poster de présentation des différents .net Framework (source : microsoft.com)
Remarque : Xpath est un langage de description de recherche d’élément dans des fichiers
XML. Son absence du .net CF est problématique, car il n’existe pas, à notre connaissance, de moteur
d’inférence développé sous .net n’utilisant pas cet outil.
3. Les Framework retenus
Avant toute chose, il est à remarquer que même avec cet assouplissement dans les
contraintes, peu de choix s’offrent à nous.
Nous allons vous présenter dans les prochains paragraphes les Framework les plus
intéressants, en mettant en lumière autant leurs points forts que leurs points faibles.
a. Drools.net
Portage .net de Jboss, moteur d’inférence Java, dont il hérite des qualités à savoir :
• Une puissance d’expression des règles très importante
• Le choix entre chaînage avant, chaînage arrière et chaînage hybride.
Le logo CF indique la
présence de cet élément
au sein du .net Compact
Framework
page 17
• Une bonne fiabilité : il s’agit à l’origine d’un logiciel supporté par Redhat
• La bibliothèque embarque tout le nécessaire, que ce soit le moteur d’inférence,
le logiciel d’édition des règles, le tout avec des affichages graphiques déjà
réalisés.
Cependant, de part sa complétude, Drools.net ne peut pas être adapté à notre projet :
• Drools .net se base sur le Framework .net classique, et fait appel à de nombreux
éléments non présents du .net CF, ce qui nous forcerait en cas de portage à
recoder de nombreuses parties.
• Drools.net est une bibliothèque très lourde : plusieurs milliers de lignes de
codes, d’où une perte de temps importante si nous décidons de l’adapter.
Cette bibliothèque aurait pu être un bon choix sur une machine moins limitée, mais dans
notre cas, son utilisation nous semble contre-productive.
b. NXBRE
Autre bibliothèque puissante d’inférence en .net. Il dispose d’une puissance de calcul et de
fonctionnalités similaires à Drools.net et a, de ce fait les mêmes problèmes, à savoir, un code obscur
et de trop nombreux appels à des méthodes n’appartenant pas au .net CF.
c. Simple Rule Engine
Moteur d’inférence en chaînage avant disponible en C#. Ce moteur d’inférence est très
simple. Ses fonctionnalités n’en restent pas moins suffisantes :
• Accepte les règles au format XML
• Code simple, lisible et structuré
• Peu d’appel à des méthodes non partagées entre les différents Framework
Quelques problèmes subsistent toutefois :
• Le développement de Simple Rule engine est en veille depuis 2005
• Les quelques appels aux méthodes non présentes dans le .net CF pourraient
nous obliger à revoir le fonctionnement complet de la bibliothèque, voir a
choisir un autre format de description de règles.
• Le code de la bibliothèque n’est peut être pas optimisé pour un client embarqué.
page 18
4. Bilan : Les choix possibles
Après cette étude, seules les possibilités suivantes nous paraissent viables :
• Codage complet d’un moteur d’inférence
• Adaptation de Simple Rule Engine
Codage Complet Adaptation de SRE
Adéquation avec les besoins Totale Partielle une fois les méthodes .net transformée en méthodes .net CF, totale si adaptation plus en profondeur
Documentation - Moyenne : des exemples sont fournis avec la classe, mais pas de documentation complète de chaque méthode
Temps nécessaire Important Moyen
Puissance d’expression des règles
Dépendante de notre
développement
Opérateurs booléens, operateurs arithmétiques
Rapidité d’exécution sur le Smartphone
Dépendante de
l’implémentation
À tester.
Dans les sections précédentes nous avons vus le système Windows Mobile, les systèmes
experts. Maintenant, nous allons étudier une partie exploratoire concernant l’apprentissage de
règles.
E. Apprentissage
1. Introduction
La création d'un système d'apprentissage est définie comme suit:
Une fonction cible c qu'on désire apprendre Une représentation de c Un ensemble d'apprentissage A qui est l'ensemble à partir duquel on pourra apprendre
c Un algorithme qui permettra d'apprendre c à partir de A Un ensemble de test T qui nous permettra de valider ou d'invalider notre fonction h
apprise
Comme dans notre problème nous cherchons à partir de couple (val,val) et apprendre à
reconnaitre des structurations ,les algorithmes de classification (c'est à dire affecter un objet à une
catégorie d'un ensemble fini de catégories), nous ont semblés intéressants.
Un ensemble d'apprentissage est représenté par A={(e,c)}, avec e∈ X représentant l'entité
que l'on veut classifier et « c » la catégorie de cette entité.
La première question qu'il faut se poser concerne la forme de A: possédons-nous des
exemples positifs et négatifs ou seulement des exemples positifs?
page 19
Il faut ensuite se poser la question de la sélection des exemples présents dans A et
permettant d'apprendre. Il faut que notre ensemble de test T et notre ensemble d'apprentissage A
soient indépendants, il faut donc définir T et A.
2. La classification
Une classification est définie ainsi:
Soit X, l'ensemble de toutes les instances possibles et C={c1,c2,...,cn} un ensemble fini de
catégories. Une fonction de classification c est définie ainsi :
c: X → C x → c(x) Dans notre cas, C={0 : erreur, 1 : vrai}
Nous voulons donc apprendre une classification. Les données que nous possédons sont
celles présentes dans notre ensemble d'apprentissage A={(x,c(x)) où x ∈ X et c(x) ∈ C}
Le but est donc d'apprendre une fonction h: X → C
x → h(x)
tel que ∀ (x,c(x)) ∈ A, h(x)=c(x).
Une chose essentielle dans le choix de h, est que h puisse généraliser l'information pour
classifier correctement les instances qui ne sont pas dans A. En effet mémoriser simplement les
exemples présents dans A est une hypothèse qui ne généralise pas. On prend donc comme
hypothèse:
Si ∀ (x,c(x)) ∈ A, h(x)=c(x) alors h approxime c pour tout x ∉ A.
Afin d'arriver à une meilleure fonction h possible, il faut restreindre l'ensemble H={h,
approximation de c}.
H peut être défini ainsi: H={<c1,c2,...,cn>}où -ci = ? signifie toute valeur possible
-ci= val spécifie la valeur val
-ci= ∅ signifie aucune valeur possible
On suppose que les hypothèses h sont représentées par des conjonctions sur les valeurs des
variables. Pour apprendre la fonction cible, il faut se demander quelles sont les valeurs communes
aux exemples positifs:
Exemple Taille Couleur Forme Catégorie 1 Petit Rouge Cercle Positif 2 Grand Rouge Cercle Positif 3 Petit Rouge Triangle Négatif 4 Grand Bleu Cercle Négatif
page 20
La règle apprise est ici: rouge ^ cercle ⇒ positif
Il faut ensuite vérifier la consistance de l'hypothèse avec les exemples négatifs:
Si l'hypothèse est cohérente, alors la règle est bonne. Si l'hypothèse est incohérente, alors il n'existe pas de règles conjonctives.
Les règles conjonctives sont cependant assez limitatives.
Reprenons notre exemple:
Exemple Taille Couleur Forme Catégorie 1 Petit Rouge Cercle Positif 2 Grand Rouge Cercle Positif 3 Petit Rouge Triangle Négatif 4 Grand Bleu Cercle Négatif 5 Moyen Rouge Cercle Négatif
Ici les règles apprises sont:
petit ^ cercle ⇒ positif grand ^ rouge ⇒ positif
Le problème est de savoir comment trouver ces règles. On peut utiliser l'espace des
hypothèses et la notion de généralisation pour rechercher h.
On définit ainsi la notion de généralisation: soit h1 ∈ H et h2 ∈ H:
h1 ≥ h2 (h1 est plus générale que h2) si et seulement si h2(x)=1 ⇒ h1(x)=1
On dit que x ∈ X saesfait h si et seulement si h(x)=1.
On peut, grâce à la généralisation, établir une relation d’ordre sur l’espace de recherche:
<M,?>
<G,R> <G,V>
Est plus générale que
<?,?>
<G,B> <M,V> <M,R> <P,B> <M,B> <P,V> <P,R>
<P,?> <?,R>
<?,?>
<G,?> <?,B> <?,V>
page 21
3. Algorithmes de classification
a. Le Find-S algorithme.
Il permet l'apprentissage de l'hypothèse la plus spécifique (il est aussi appelé least general
generalization LGG).
Voici cet algorithme :
h=<∅,∅,…,∅>
Pour tous les exemples positifs x de A faire
Pour chaque variable vi faire
si hvi n’est pas consistente avec xvi
alors si hvi=∅ alors hvi=xvi
sinon hvi=?
Fsi
fsi
refaire
Refaire
Si h est compatible avec les exemples négatifs de A
Alors retourner h
Sinon il n’existe pas d’hypothèse consistante
Voici le déroulement de l’algorithme sur le premier exemple :
H=<Ø ,Ø ,Ø >
H=<petit,rouge,cercle>
H=<?,rouge,cercle>
e=(petit,rouge,cercle)
e=(grand,rouge,cercle)
page 22
Le principe de cet algorithme est la mise à jour incrémentale de l'hypothèse après chaque
nouvel exemple positif: on généralise un minimum pour simplement prendre en compte le nouvel
exemple.
b. Espace des versions
L’espace des versions est l’ensemble des hypothèses qui sont cohérentes avec A. Un mode
de construction naïf pourrait être d’énumérer toutes les hypothèses, et d’éliminer celles qui sont non
cohérentes avec A. Cependant ce mode de construction est irréaliste sur des gros ensembles
d’hypothèses. Il existe une représentation compacte de l’espace des versions. Ce dernier utilise deux
ensembles d’hypothèses :
S : l’ensemble des hypothèses les plus spécifiques (peut utiliser le Find-S) G : l’ensemble des hypothèses les plus générales Les hypothèses cohérentes sont donc respectivement les sur et sous-ensembles de S et
G. On initialise nos ensembles S et G :
S0={<∅,∅,…,∅>}
G0={< ?, ?, …, ?>} Le calcul de S et G est incrémental, on prend exemple par exemple :
Si l’exemple est positif, G est identique et on calcule S à partir de l’hypothèse la plus
spécifique cohérente avec le nouvel exemple positif. Il faut ensuite vérifier que l’hypothèse est <= G.
Si l’exemple est négatif : S reste identique. G doit être raffinée afin d’exclure les exemples
négatifs, de plus il faut que G soit compatible avec S.
On déroule cet algorithme sur tous les exemples. Si S=G, il n’y a qu’une hypothèse
cohérente avec les exemples. Si S=G=∅, il n’y a pas d’hypothèse cohérente avec les exemples. Dans
ce cas, l’hypothèse de conjonction n’est pas bonne.
Si l’espace des versions n’a pas convergé, on peut classifier un exemple e de l’ensemble de
test de la manière suivante :
Si h S, h(e)=1 e est positif.
Si h S, h(e)=0 e est négatif. Sinon : Soit np(respectivement nn) le nombre d’hypothèses de l’espace des versions
classant e positivement (respectivement négativement), e est positif avec une probabilité de np/(nn+np).
Il faut noter que l’algorithme de calcul de l’espace des versions va converger vers c si et
seulement si les exemples fournis sont bien classés et que l’espace d’hypothèses de départ contient
la fonction cible.
4. Arbres de décisions
Une des méthodes les plus utilisées pour l’apprentissage est l’apprentissage par arbre de
décision. En effet, elle permet d’apprendre avec des données bruitées et est capable d’apprendre
des expressions disjonctives.
Une instance de variable doit être de la forme {(Attribut, valeur)}. Il faut que le nombre de
valeurs de l’attribut soit petit. La fonction cible doit avoir des valeurs de sortie discrètes, si elles ne le
page 23
sont pas, il faut les discrétiser. Les exemples d’apprentissage peuvent ne pas avoir de valeur sur
certains attributs. L’espace de recherche étant complet, il évite le risque de ne pas avoir la fonction
cible dans l’espace de recherche.
Un arbre de décision est un arbre tel que :
À un nœud est associée une variable, À une branche est associée une valeur, À une feuille est associée une catégorie.
La classification d’une instance se fait par parcours de l’arbre.
Cet arbre peut ainsi être écrit comme un ensemble de règles :
Bleu négatif
Vert positif
Rouge ^ cercle positif
Rouge ^ carré négatif
Rouge ^ triangle négatif
L’algorithme ID3 permet la construction « top down » de l’arbre, il recherche un arbre qui
correspond à A dans l’espace de tous les arbres de décisions. Voici cet algorithme:
ID3(Examples,Target_attribute,Attributes)
Create a Root node for the tree
If all Examples are positive, Return the single-node tree Root, with label = +
If all Examples are negative, Return the single-node tree Root, with label = -
Couleur
Forme
Posit if Négatif Négati f
Négati f Posit if
Rouge
Bleu
Vert
Cercle
Carré Triangle
page 24
If attributes is empty is empty, Return the single-node tree Root, with label = most common
value of Target_attribute for Root ← A
Otherwise Begin
Add a new tree branch below Root, corresponding to the test A= vi
Let Examples vi be the subset of Examples that have value vi for A
If Examples vi is empty
Then below this new branch add a leaf node with label = most common value of
Target_attribute in Examples
Else below this new branch add the subtree
ID3(Examplesvi, target_attribute, Attributes-{A})
Le choix de l’attribut se fait grâce à une fonction de gain qui est une propriété statistique et
qui mesure comment l’attribut sépare les exemples. Cette fonction utilise la fonction d’entropie qui
permet de mesurer la pureté d’un ensemble d’exemples.
ID3 utilise à chaque étape tous les exemples de A, ce qui est très lourd, contrairement à
FIND-S et l’algorithme de l’espace des versions
5. Conclusion
La réalisation de l’apprentissage est la partie exploratoire du projet, elle dépend du temps
que nous aurons passé sur le reste du projet. Nous devrons donc adapter notre projet à la réalisation
possible de l’apprentissage. Il existe plusieurs méthodes d’apprentissage, et nous devrons donc
vraiment nous poser la question du choix à prendre.
page 25
F. Conclusion Au cours de cette pré-étude, nous nous sommes documentés sur les différentes
composantes de notre projet. À savoir, les caractéristiques du projet, la partie développement
logiciel mobile (Windows Mobile, Visual Studio, émulateur…), la partie système expert et l’étude de
l’existant, et finalement l’apprentissage de règles.
Pour la partie technologie, l'utilisation de la librairie COREDLL.DLL va s’avérer assez ardue,
celle-ci n’étant pas très bien documentée. De plus pour résoudre le problème des communications il
nous faut étudier l'outil mediaContact de Telelogos. Pour la partie Systèmes experts, le
développement du moteur d’inférence embarqué nécessitera une importante réflexion sur son
implémentation (utilisation de l’existant ou création).
Enfin pour la partie apprentissage tout est encore ouvert, pour l'instant nous n'avons étudié
que les algorithmes de base et les choix sont encore à faire.
page 26
G. Annexes
1. Code de l’application Hello world using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace DeviceApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_KeyDown(object sender, KeyEventArgs e) { if ((e.KeyCode == System.Windows.Forms.Keys.Up)) { // Bouton ? bascule haut // Haut } if ((e.KeyCode == System.Windows.Forms.Keys.Down)) { // Bouton ? bascule bas // Bas } if ((e.KeyCode == System.Windows.Forms.Keys.Left)) { // Gauche } if ((e.KeyCode == System.Windows.Forms.Keys.Right)) { // Droite } if ((e.KeyCode == System.Windows.Forms.Keys.Enter)) { label1.Text = "vous avez appuy? sur entr?e"; } } }
}
page 27
2. Code de l’application d’obtention des données
a. Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace DeviceApplication2 { public partial class Form1 : Form { Mem m ; String memorystring; public Form1() { InitializeComponent(); m = new Mem(); memorystring=m.ShowMemory(); label1.Text = memorystring; progressBar1.Value = 50; } private void Form1_KeyDown(object sender, KeyEventArgs e) { if ((e.KeyCode == System.Windows.Forms.Keys.Up)) { // Up progressBar1.Value += 1; } if ((e.KeyCode == System.Windows.Forms.Keys.Down)) { // Down progressBar1.Value -= 1; } if ((e.KeyCode == System.Windows.Forms.Keys.Left)) { progressBar1.Value -= 1; } if ((e.KeyCode == System.Windows.Forms.Keys.Right)) { progressBar1.Value += 1; } if ((e.KeyCode == System.Windows.Forms.Keys.Enter)) { // Enter Application.Exit(); } } private void progressBar1_ParentChanged(object sender, EventArgs e) { } }
}
page 28
b. Mem.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace DeviceApplication2 { class Mem { public struct MEMORYSTATUS { public UInt32 dwLength; public UInt32 dwMemoryLoad; public UInt32 dwTotalPhys; public UInt32 dwAvailPhys; public UInt32 dwTotalPageFile; public UInt32 dwAvailPageFile; public UInt32 dwTotalVirtual; public UInt32 dwAvailVirtual; } [DllImport("CoreDll.dll")] public static extern void GlobalMemoryStatus ( //Param?tre de la m?thode GlobalMemoryStatus r?cup?r?e dans la dll CoreDll ref MEMORYSTATUS lpBuffer ); //Signature de la m?thode GetSystemMemoryDivision [DllImport("CoreDll.dll")] public static extern int GetSystemMemoryDivision ( ref UInt32 lpdwStorePages, ref UInt32 lpdwRamPages, ref UInt32 lpdwPageSize ); public String ShowMemory() { UInt32 storePages = 0; UInt32 ramPages = 0; UInt32 pageSize = 0; int res = GetSystemMemoryDivision(ref storePages, ref ramPages, ref pageSize); // Call the native GlobalMemoryStatus method // with the defined structure. MEMORYSTATUS memStatus = new MEMORYSTATUS(); GlobalMemoryStatus(ref memStatus); // Use a StringBuilder for the message box string. StringBuilder MemoryInfo = new StringBuilder(); MemoryInfo.Append("Memory Load: " + memStatus.dwMemoryLoad.ToString() + "\n"); MemoryInfo.Append("Total Physical: "
page 29
+ memStatus.dwTotalPhys.ToString() + "\n"); MemoryInfo.Append("Avail Physical: " + memStatus.dwAvailPhys.ToString() + "\n"); MemoryInfo.Append("Total Page File: " + memStatus.dwTotalPageFile.ToString() + "\n"); MemoryInfo.Append("Avail Page File: " + memStatus.dwAvailPageFile.ToString() + "\n"); MemoryInfo.Append("Total Virtual: " + memStatus.dwTotalVirtual.ToString() + "\n"); MemoryInfo.Append("Avail Virtual: " + memStatus.dwAvailVirtual.ToString() + "\n"); // Show the available memory. return(MemoryInfo.ToString()); } }
}
page 30
3. Planification
N° Nom de la tâche Durée
1 Liste des évenements à surveiller 7 jours?
2 Rechercher toutes les infos système que l'on peut remonter 7 jours
3 Tester qu'on arrive à acceder à chacun d'eux 7 jours
4 Etablir la liste des évenements que l'on peut surveiller 1 jour
5 Lister les actions à effectuer 5 jours
6 Tester chacune de ces actions 5 jours
7 Etudier MediaContact 19 jours
8 Envoi d'un rapport avec MediaContact 7 jours
9 Etude de l'interface administrateur 7 jours
10 Vérifier si on peut embarquer un interpreteur Prolog 9 jours
11 Tester Simple Rules Engine 9 jours
12 Spécification ou test plus avancé 9 jours
Liste des évenements à surveillerRechercher toutes les infos système que l'on peut r emonter
Tester qu'on arrive à acceder à chacun d'euxEtablir la liste des évenements que l'on peut surve iller
Lister les actions à effectuerTester chacune de ces actions
Etudier MediaContactEnvoi d'un rapport avec MediaContact
Etude de l'interface administrateurVérifier si on peut embarquer un interpreteur Prolo g
Tester Simple Rules EngineSpécification ou test plus avancé
L M M J V S D L M M J V S D L M M J V S D L M M J V S D L M M J V S D L M M J V S D L19 Oct 09 26 Oct 09 02 Nov 09 09 Nov 09 16 Nov 09 23 Nov 09 30 Nov 09
Recommended