#!/usr/bin/perl
#  FaitCooccurrencesDansFenetre.pl

<<DOC; 
B. Habert
lun mar 20 16:07:55 CET 2006

               FaitCooccurrencesDansFenetre.pl :


Format d'entrée : 


Exemple :  perl  FaitCooccurrencesDansFenetre.pl PHILOLynx-dump-normaliseCordialLemmeCatBreve.ArticleEgalFenetre 'Np|Nc|A' 20 3 > PHILOLynx-dump-normaliseCordialLemmeCatBreveArticleEgalFenetre.CoocMaxDistance20MinCooc3


real    0m17.549s
user    0m17.440s
sys     0m0.100s

wc -l PHILOLynx-dump-normaliseCordialLemmeCatBreve.ArticleEgalFenetre.CoocMaxDistance20MinCooc3
15884 PHILOLynx-dump-normaliseCordialLemmeCatBreve.ArticleEgalFenetre.CoocMaxDistance20MinCooc3

Format de sortie :

<cooccurrent1><cooccurrent2><co-fréquence><distance moyenne>

<?xml version="1.0" encoding="iso-8859-1"?>
<cooccurrences>
<t c1="contexte_Nc" c2="chose_Nc" cf="1" dm="11.00"/>
<t c1="japonais_A" c2="wushutao_Nc" cf="1" dm="20.00"/>
<t c1="logique_A" c2="responsabilité_Nc" cf="1" dm="13.00"/>
<t c1="esprit_Nc" c2="différent_A" cf="1" dm="7.00"/>
<t c1="cerf_Nc" c2="Adorno_Np" cf="1" dm="5.00"/>
...
</cooccurrences>

A faire :

Bugs et problèmes :

DOC



$ChaineUsage = "Usage : FaitCooccurrencesDansFenetre.pl <fichier un token par ligne avec fins de fenêtres><catégories à garder séparées par la barre verticale><distance plafond><cooccurrence plancher>\n" ; 
if (@ARGV != 4) {die $ChaineUsage ; }  
$FichierEntree = $ARGV[0] ;  
$CategoriesGardees = $ARGV[1] ;  
$DistancePlafond   = $ARGV[2] ;  
$CooccurrencePlancher   = $ARGV[3] ;  
%Cooccurrence2Frequence = () ;
%Cooccurrence2Distance = () ;
@TokensGardes = () ;
@PositionTokensGardes = () ;
$SeparateurTokens   = "\t" ;
$SeparateurTokenCategorie   = "_" ;
$NumeroLigne ;
$Trace = 0 ; 
$PourWindows = 1 ;
if ($PourWindows == 0) {
  $FinLigne     = "\n" ; 
}
else {
  $FinLigne     = "\r\n" ; 
}
$FinFenetre      = "<FinFenetre/>$FinLigne" ;

open(ENTREE, $FichierEntree) ;  
while ($Ligne = <ENTREE>){
  if ($Trace == 1) {print "$NumeroLigne\t$Ligne" ; }
  if ($Ligne eq $FinFenetre) {
    if ($Trace == 1) {print $Ligne ; }
    for ($l1 = 0 ; $l1 < $#TokensGardes ; $l1++) {
       for ($l2 = $l1 + 1 ; $l2 <= $#TokensGardes ; $l2++) {
         $Distance = $PositionTokensGardes[$l2] - $PositionTokensGardes[$l1] ;
         if ($Distance <= $DistancePlafond) {
           $Cooccurrence = "$TokensGardes[$l1]$SeparateurTokens$TokensGardes[$l2]" ;
           $Cooccurrence2Frequence{$Cooccurrence}++ ;
           $Cooccurrence2Distance{$Cooccurrence} .= "$Distance " ;
         }
       }
    }
    @TokensGardes         = () ;
    @PositionTokensGardes = () ;
    $NumeroMot            = 1 ;
  }
  else {
    chomp($Ligne) ;
    if ($PourWindows == 1) {
      chop($Ligne) ; 
    }
    @ListeTokenCategorie = split(/$SeparateurTokenCategorie/, $Ligne) ;
    $Categorie = $ListeTokenCategorie[$#ListeTokenCategorie] ; 
    if ($Categorie =~ /$CategoriesGardees/) {
      if ($Trace == 1) {print "\t\t$Ligne$FinLigne" ; }
      push(@TokensGardes, $Ligne) ;
      push(@PositionTokensGardes, $NumeroMot) ;
    }
    $NumeroMot++ ;
  }
  $NumeroLigne++ ;
}
close(ENTREE) ;


imprimeEnTete() ;
foreach $Cooccurrence (keys %Cooccurrence2Frequence) {
  @ListeCooccurrents = split(/$SeparateurTokens/, $Cooccurrence) ; 
  $Cooccurrent1      = $ListeCooccurrents[0] ;
  $Cooccurrent2      = $ListeCooccurrents[1] ;
  $Frequence         = $Cooccurrence2Frequence{$Cooccurrence} ;
  if ($Frequence >= $CooccurrencePlancher) {
    $Distances         = $Cooccurrence2Distance{$Cooccurrence} ;
    chomp($Distances) ;
    @ListeDistances    = split(/ /, $Distances) ;
    if (scalar(@ListeDistances) == 1) {
      $DistanceMoyenne = $ListeDistances[0] ;
    }
    else {
      $TotalDistances = 0 ;
      for ($i = 0 ; $i <= $#ListeDistances ; $i++) {
        $TotalDistances += $ListeDistances[$i] ;
      }
      $DistanceMoyenne = $TotalDistances / $Frequence ,
    }
    print "<t c1=\"$Cooccurrent1\" c2=\"$Cooccurrent2\" cf=\"$Frequence\" dm=\"" ;
    printf "%1.2f", $DistanceMoyenne ;
    print "\"/>$FinLigne" ;
  }
}
imprimeEnPied() ;

sub imprimeEnTete{
  print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>$FinLigne<cooccurrences>$FinLigne" ; 
}

sub imprimeEnPied{
  print "</cooccurrences>$FinLigne" ;
}
