rapport (4229B)
1 #!/usr/bin/env python3 2 # 3 # rapport.py -- Produire un rapport sur la performance du modèle. 4 # 5 # $1 - Chemin vers l’extension 6 # $2 - Chemin vers l’échantillon 7 # $3 - Chemin vers les préfixes 8 9 import sys 10 11 # Charger dans un ensemble de tuples les paires contenues dans un fichier. Ces 12 # paires doivent figurer une par ligne et leurs éléments doivent être séparés 13 # par un caractère de tabulation. 14 def charger_paires(fichier): 15 paires = set() 16 with open(fichier, "r") as f: 17 for ligne in f: 18 champs = ligne.rstrip().split("\t") 19 if len(champs) != 2: 20 raise ValueError(f"{fichier}: {len(champs)} champ(s) plutôt que 2.") 21 paires.add((champs[0], champs[1])) 22 return paires 23 24 def charger_lignes(fichier): 25 lignes = set() 26 with open(fichier, "r") as f: 27 lignes = {ligne.rstrip() for ligne in f} 28 return lignes 29 30 # Convertir les paires d’un ensembe de couples à un dictionnaire dont la clé en 31 # est le premier élément et la valeur le second. Aucune information n’est 32 # perdue si le transducteur est séquentiel. 33 def paires_vers_dict(paires): 34 return {paire[0]:paire[1] for paire in paires} 35 36 # Tester la séquentialité de l’extension dans le sens de la génération. Une 37 # description abstraite doit correspondre à une seule forme. Renvoie un 38 # ensemble contenant les descriptions abstraites qui rendent l’extension 39 # non-séquentielle. 40 def tester_sequentialite(extension): 41 desc = set() 42 doublons = set() 43 for paire in extension: 44 if paire[0] not in desc: 45 desc.add(paire[0]) 46 else: 47 doublons.add(paire[0]) 48 return doublons 49 50 # Renvoyer les formes générés correctes. 51 def vrais_positifs(echantillon, extension): 52 vp = set() 53 for c in echantillon: 54 if c in extension and echantillon[c] == extension[c]: 55 vp.add(c) 56 return vp 57 58 # Renvoyer les formes générées incorrectes. 59 def faux_positifs(echantillon, extension): 60 fp = set() 61 for c in echantillon: 62 if c in extension and echantillon[c] != extension[c]: 63 fp.add(c) 64 return fp 65 66 # Renvoyer les formes non générées qui auraient dû l’être. 67 def faux_negatifs(echantillon, extension): 68 fn = set() 69 for c in echantillon: 70 if c not in extension: 71 fn.add(c) 72 return fn 73 74 def precision(vp, fp): 75 return len(vp) / (len(vp) + len(fp)) * 100 76 77 def rappel(vp, fn): 78 return len(vp) / (len(vp) + len(fn)) * 100 79 80 def f1(pre, rap): 81 return 2 * (pre * rap) / (pre + rap) 82 83 # Afficher le rapport un sortie standard. 84 def rapporter (echantillon, extension): 85 print("=== RAPPORT ===") 86 print() 87 res = tester_sequentialite(extension) 88 if res: 89 print("NON SÉQUENTIEL!") 90 for desc in res: 91 print(desc) 92 return 93 # Convertir les paires 94 echantillon = paires_vers_dict(echantillon) 95 extension = paires_vers_dict(extension) 96 print(f"Nombre de formes générées: {len(extension)}") 97 res = len({extension[c] for c in extension}) 98 print("Nombre de formes uniques générées: " 99 f"{res} ({res/len(extension)*100:.2f}%)") 100 print(f"Taille de l’échantillon: {len(echantillon)} " 101 f"({len(echantillon)/len(extension)*100:.2f}%)") 102 print() 103 vp = vrais_positifs(echantillon, extension) 104 fp = faux_positifs(echantillon, extension) 105 fn = faux_negatifs(echantillon, extension) 106 print("--- FAUX POSITIFS ---") 107 print() 108 for f in fp: 109 print(f"{f}: {echantillon[f]} ({extension[f]})") 110 if fp: 111 print() 112 print("--- FAUX NÉGATIFS ---") 113 print() 114 for f in fn: 115 print(f"{f}: {echantillon[f]}") 116 if fn: 117 print() 118 print(f"Nombre de vrais positifs: {len(vp)}") 119 print(f"Nombre de faux positifs: {len(fp)}") 120 print(f"Nombre de faux négatifs: {len(fn)}") 121 pre = precision(vp, fp) 122 print(f"Précision: {pre:.2f}") 123 rap = rappel(vp, fn) 124 print(f"Rappel: {rap:.2f}") 125 f = f1(pre, rap) 126 print(f"F1: {f:.2f}") 127 128 if __name__ == "__main__": 129 if len(sys.argv) != 3: 130 raise RuntimeError("Mauvais arguments.") 131 132 ext = charger_paires(sys.argv[1]) 133 ech = charger_paires(sys.argv[2]) 134 135 rapporter(ech, ext)