Partiel du 15/01/2008
Durée : 2h00
Les documents sont autorisés. Vous rendrez votre travail sous format numérique (format .doc), en envoyant un fichier attaché à Olivier.Kraif@u-grenoble3.fr. L'enseignant accusera réception avant votre sortie de la salle d'examen.
Pour chaque exercice, vous donnerez d'abord une explication en français de votre code (structures de données, algorithmes) et argumenterez vos choix. Soyez concis ! Vous donnerez ensuite le code Perl comportant des commentaires appropriés, faisant apparaître les différentes étapes de vos traitements. Les barèmes sont donnés à titre indicatif et pourront être modifiés à la correction.
Si des bogues persistent ne vous acharnez pas : un code légèrement bogué pourra recevoir néanmoins une excellente note.
	Exercice 1 (4 points)
On veut ajouter à l'étiqueteur HMM txt2txs (dont le code est fourni ci-joint), un module d'analyse morphologique permettant de deviner les catégories probables d'une forme inconnue du dictionnaire. Pour cela on va d'abord implémenter les règles suivantes :

- si la forme comporte une majuscule à l'initiale, sans être en début de phrase, alors c'est un nom propre (catégorie "npr").

- si la forme correspond à un des types suivants identifiés lors de la tokenisation : "eml","url","num","pon","car" alors sa catégorie est traduite, respectivement, par les étiquettes "aut","aut","num","pon" et "sym".

Modifier le code de la fonction text2txs( ) pour implémenter ces règles.

Correction des exercices 1 et 4:
Les catégories possibles pour une forme doivent être enregistrées dans le hash %ana (analyses possibles) et non pas dans la variable $type issue de la tokenisation (qui n'est pas utilisée dans l'algorithme de Viterbi). Dans la solution ci-dessous, on a utilisé le label SWITCH et l'instruction last afin de simuler une structure conditionnelle de type case (qui n'existe pas en Perl). On peut aussi utiliser une structure if () {} elsif () {} elsif (){ }… else {}

Ligne 237, on ajoute :
	if ($inc) {
		${$ana}{$form."#inc"}="";
	} else {
		
		# 2/ on détermine la liste des catégories les plus probables en fonction de la forme
		SWITCH: {
			# noms propres
			if ($i>1 and uc(substr($form,0,1)) eq substr($form,0,1)) { # on teste la majuscule à l'initiale en se basant sur la fonction uc, qui tient compte des diacritiques
				${$ana}{$form."#npr"}="guessed"; 	
				last SWITCH;
			}
			
			# ponctuations
			if ($type eq "pon") {
				${$ana}{$form."#pon"}=""; 	
				last SWITCH;
			}
			
			# symboles
			if ($type eq "car") {
				${$ana}{$form."#sym"}="guessed";	
				last SWITCH;
			}
			
			# nombres
			if ($type eq "num") {
				${$ana}{$form."#num"}="";	
				last SWITCH;
			}
			
			# emails et url -> autres
			if ($type eq "eml" || $type eq "url") {
				${$ana}{$form."#aut"}="$type";	
				last SWITCH;
			} 
			# SOLUTION DE L'EXERCICE 4
			# si la forme contient plus de $suffixLength car., on extrait le suffixe 
			if (($type eq "mot" || $type eq "fc") && length($form)>=$suffixLength) {
				$form=~/(.{$suffixLength})$/;
				my $suffix=lc($1);
				my $cats=$suffix2cats{$suffix}; 		# on récupère la liste des catégories probables dans le hash %suffix2cats
				if (defined($cats)) {
					foreach my $c (split(/#/,$cats)) {
						${$ana}{$form."#".$c}="guessed";
					}
					last SWITCH;
				}
			} 
			
			# par défaut on affecte toutes les catégories possibles
			foreach my $c (@categories) {
				${$ana}{$form."#".$c}="guessed";
			}
		}
	}
	Exercice 2 (8 points)
Pour les autres formes inconnues, de type "mot" ou "fc", si leur longueur est d'au moins 5 caractères, on peut calculer les catégories les plus probables en  s'appuyant sur leur suffixe (de longueur 5).
Afin de calculer ces catégories, on va d'abord extraire un hachage %form2freq dont les clés  correspondent à des formes et les valeurs à la fréquence observée dans Frantext. Ces données sont enregistrées dans le fichier FrantextAvr.txt.

2.1 Ecrire une fonction readFreqDic() qui effectue le remplissage du hachage global %form2freq. Lier ce hachage à une DBM via le module DBM::Deep.

2.2 On construit un hachage %suffix2cats2freqs qui contient pour chaque suffixe de longueur 5 (utilisés comme clé) une référence vers un 'sous-hachage' dont les clés sont des catégories, et les valeurs la fréquence cumulée des formes correspondantes (c'est-à-dire  la fréquence cumulée de toutes les formes qui se terminent par un certain suffixe et qui correspondent à une certaine catégorie). Par exemple, si les adjectifs en « -esque » totalisent 456
 occurrences dans le corpus Frantext, on aura : 
$suffix2cat2freqs{'esque'}->{'adj'} == 456 

La fonction calc_suffix2cats2freqs() se charge du remplissage du hachage global  %suffix2cats2freq à partir des hachages globaux %dic et %form2freq. Cette fonction est écrite, mais ne comporte pas d'indentation, ni de déclarations, comporte un problème de fermeture de bloc {} plus un bogue lié à l'initialisation des 'sous-hachages'.
Corrigez.

	Exercice 3 (6 points)
Le hachage global %suffix2cats doit contenir, pour chaque suffixe (utilisé comme clé) la liste des catégories les plus probables (cette liste de catégories sera enregistrée sous la forme d'une chaîne contenant les catégories concaténées et séparées par le symbole '#'). 
Ces catégories correspondent, pour un suffixe donné, à celles qui totalisent une fréquence supérieure à un certain pourcentage de la fréquence globale du suffixe (ce pourcentage est enregistré dans la variable $minRatio). Cette condition pourra s'écrire :

$suffix2cat2freqs{$suffix}->{$cat}/$totFreq >= $minRatio
 
ou $totFreq contient la fréquence totale de $suffix.

Ecrire la fonction calc_suffix2cats(), qui remplit le hachage global %suffix2cats. Liez le hachage à une DBM via le module DBM::Deep

	Exercice 4 (2+1 points)
Une fois ce hachage calculé, il est possible d'effectuer facilement une désambiguïsation partielle des catégories d'une forme inconnue. Modifier le code de la fonction txt2txs() afin de mettre en oeuvre cette désambiguïsation partielle, avant l'application de l'algorithme de Viterbi. Les formes ainsi catégorisées ne seront pas lemmatisées (la forme et le lemme seront identiques) et ne porteront aucun trait (sauf l'indication 'guessed').