IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Étiquetage morphosyntaxique d'un texte


Sujet :

Langage Perl

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Étiquetage morphosyntaxique d'un texte
    Bonjour,
    J'ai un programme qui fait l'étiquetage d'un texte.
    -Le problème c'est avec l'affichage, quand je met "if( $m eq $cle){print "$m $val \n";}" tout fonctionne bien. Mais si j'ajoute " else { print "$m UNK \n"}, le programme n'affiche que quelques premiers mots qui se repetent à l' infini.
    Voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #!/usr/bin/perl -w
     
    use strict;
     
    my ($fichier, $ligne, $ligne1, $m, $cle, $val, $i);
    my $mots_imb=0;
     
    my (@zlo, @mots, @mots_imb);
    my %stocke;
     
    open (F, "<", "lefff-ext-3.2-pos.txt");
    while (defined ($ligne= <F>)){
    	chomp ($ligne);
    	@zlo=split (/\t/, $ligne);
    	if ( defined $stocke{$zlo[0]}){
    	$stocke{$zlo[0]}.=",".$zlo[1];
    	} else {
    	$stocke{$zlo[0]}=$zlo[1];
    	}
    	}
     
    print "Entrez le chemin vers le fichier a traiter: \n";
    $fichier=<STDIN>;
    chomp($fichier);
    open (FI,"<", $fichier);
    	while (defined ($ligne1=<FI>)){
    	chomp($ligne1);
    	@mots = split(/(\pP|\pS|\s)/,lc $ligne1 );
    		while ( my ($cle, $val) = each(%stocke)) {
    			foreach $m(@mots){
    				if( $m eq $cle){
    					print "$m $val \n";
    } else {
    	print "$m UNK \n";}
    }			 
    }}
     
    }}
    PS. Je m'excuse pour mon français, ce n'est pas ma langue natale.
    Images attachées Images attachées  

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    difficile d'être sûr sans voir des données de tes deux fichiers en entrée, mais, si j'ai bien compris ce que tu cherches à faire, je pense qu'il y a un gros problème de logique dans ton programme.

    D'après ce que j'ai compris, tu charges d'abord un dictionnaire de données dans ton hash %stocke. Ensuite, tu lis ton fichier en entrée ligne par ligne et splitte ta ligne dans le tableau @mots. Jusque là, tout va bien. Mais c'est là que ça se gâte: tu fais deux boucles imbriquées, la première bouclant sur les clés et valeurs de ton hash et la seconde sur les mots de ta ligne. Si le mot correspond à ta clé tu affiches ton mot et la valeur correspondante du hash, ce qui est correct, sinon tu imprimes le mot en le déclarant inconnu, ce qui va dire que tu vas faire cette dernière action pour toutes les autres clés du hash, même si le mot existait bien dans le hash.

    En fait, il faudrait boucler sur les mots du tableau @mots, et pour chacun déterminer si c'est une clé de ton hash (donc une seule boucle, pas deux).

    Essaie de modifier cette partie de ton programme comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    open my $FI,"<", $fichier or die "Ouverture impossible de $fichier $!";
    while (my $ligne1=<$FI>) {
    	chomp($ligne1);
    	my @mots = split(/(\pP|\pS|\s)/,lc $ligne1 );
    	foreach my $m (@mots){
    		if (exists $stocke{$m}) {
    			print "$m $stocke{$m} \n";
    		} else {
    			print "$m UNK \n";
    		}
    	}
    }
    Je n'ai évidemment pas testé, n'ayant pas de données en entrée.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup. Ça marche bien maintenant, sauf que le programme traite les espaces comme les mots inconnus. J'ai essayé de modifier les critères de split, mais ça n'a pas aidé.
    Le devoir a la deuxieme partie. Il faut compter le nombre des mots ambigus. Si je comprends bien, le critère de l'imbiguité va être la présence de plusiers étiquettes pour un seul mot. Donc il faut prendre toutes les valeurs affichiés et les transformer en tableau.
    Ensuite, il faut traiter chaque case du tableau, pour voir s'il contient la vergule, ce qui va signaler la présence de plusiers étiquettes. Mais je ne comprends pas comment le faire, ou peut-être il me manque de logique?

  4. #4
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    L'erreur de logique, je pouvais la deviner sans connaître les données, les détails d'implémentation, non, ce n'est pas possible sans voir les données. Poste un échantillon de ton dictionnaire (j'appelle ainsi ton premier fichier) et de tes données (le second fichier), ainsi que le code de ton programme actuel.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!/usr/bin/perl -w
     
    use strict;
     
    my ($fichier, $ligne, $ligne1, $m, $cle, $val, $i);
    my $mots_imb=0;
     
    my (@zlo, @mots, @mots_imb);
    my %stocke;
     
    open (F, "<", "lefff-ext-3.2-pos.txt");
    while (defined ($ligne= <F>)){
    	chomp ($ligne);
    	@zlo=split (/\t/, $ligne);
    	if ( defined $stocke{$zlo[0]}){
    	$stocke{$zlo[0]}.=",".$zlo[1];
    	} else {
    	$stocke{$zlo[0]}=$zlo[1];
    	}
    	}
     
    print "Entrez le chemin vers le fichier a traiter: \n";
    $fichier=<STDIN>;
    chomp($fichier);
    open (FI,"<", $fichier);
    	while (defined ($ligne1=<FI>)){
    	chomp($ligne1);
    	@mots = split(/(\pP|\pS|\s)/,lc $ligne1 );
    		foreach my $m (@mots){
    		if (exists $stocke{$m}) {
    			print "$m $stocke{$m} \n";
    		} else {
    			print "$m UNK \n";
    		}
    	}
    }
    J'ai modifié le code comme vous avez conseillé. Mais avec le nombre des mots ambigues, je n'ai aucune idée comment le réaliser.
    Fichiers attachés Fichiers attachés

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Hum, pas trop le temps maintenant de regarder les fichiers.

    Sur les espaces supplémentaires, peut-être que modifier la regex comme suit résoudra le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @mots = split(/(\pP|\pS|\s+)/,lc $ligne1 );
    Si ça ne suffit pas, il faut peut-être pré-traiter la ligne pour remplacer les espaces multiples par des espaces simples. En fait, je ne sais pas à quoi correspondent les clauses "\pP|\pS" de ton expression régulière.

    Ou peut-être que cette regex beaucoup plus simple fonctionnerait mieux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @mots = split(/\W+/,lc $ligne1 );
    Sur les mots ambigus, il faudrait expliquer plus précisément quel est le problème.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Par exemple, pour le mot "atterrés" l'affichage va être comme ça: " atterrés adj, v". Deux étiquettes à un seul mot. Et il faut compter le nombre des mots avec plusieurs étiquettes dans le fichier a traiter.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		if (exists $stocke{$m}){ 
    		my @mots_imb=values(%stocke);
    			foreach $i( 0 .. $#mots_imb) {
    				if (grep /,/, $mots[$i]) {
    						$mots_imb++;}
    						}
    L'idée était de créer la liste des valeurs. La scalaire $mots_imb- c'est le nombre des mots ambigus. Si le programme voit la vergule dans la valeur, il ajoute 1. Mais ça n'a pas marché.

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Peut-être une solution, décrite sous la forme d'une session dans le debugger Perl:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      DB<1> $str = " atterrés adj, v"
     
      DB<2> @c = split /,/, $str;
     
      DB<3> print scalar @c
    2

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Merci, vous m'avez beaucoup aidé.

Discussions similaires

  1. afficher du texte
    Par Mau dans le forum OpenGL
    Réponses: 10
    Dernier message: 24/06/2003, 15h31
  2. taille du texte dans un viewport
    Par pitounette dans le forum OpenGL
    Réponses: 3
    Dernier message: 22/07/2002, 12h06
  3. combobox->text
    Par clovis dans le forum C++Builder
    Réponses: 18
    Dernier message: 21/06/2002, 15h43
  4. fichier binaire ou texte
    Par soussou dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/06/2002, 13h39
  5. Réponses: 2
    Dernier message: 10/06/2002, 11h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo