Création de site Internet Intranet Extranet Création de sites Internet Intranet Extranet
Spécialiste bases de données et solutions "Open Source"
 
Accueil 

 
Termes similaires d'une liste

 
  • I : Introduction
    Cette étude est le fruit d'une analyse sur la problématique suivante : Comment faire un regroupement efficace de terme d'une liste donnéee ?
    Cela implique de regrouper les pluriels et singuliers, les fautes d'orthographes, ...

    Typiquement, l'utilisation en est faites pour
    Wysistat, outil de mesure d'audience dans lequel une analyse des mots clés saisis sur les moteurs de recherche est proposé afin de regrouper les mots clés similaires pour afficher un résultat synthétique.
    Les recherches ont montré qu'il existait 2 principes pour comparer 2 mots ou termes :
  • Le Soundex : qui transforme un mot en un code basé sur la sonorité
  • Le "similar text" qui se base sur la longueur de chaine commune au 2 termes pour en déduire le taux de similitude.
    L'étude présente dans un premier temps chacune des 2 solutions puis notre solution "synthèse" qui unit les 2 principes amenant à une solution très performante.

  •  II : Algorythme du Soundex Avancé
    Présentation du Soundex ?
    Soundex est un système de codification pour des mots. D'un mot, vous produisez un code d'une lettre et de trois nombres. Ce code décrit la manière dont un mot donné retentit (sonorité du mot). Les mots retentissants de manière semblable auront des codes semblables. Il pourrait être employé, par exemple, par 411 (l'information de téléphone), pour rechercher d'autres épellations d'un dernier nom. Il a été employé par le bureau de recensement des Etats-Unis pour trouver les noms semblables dans des disques de recensement.
    Algorythme :
    La première lettre du code soundex d'un mot est simplement la première lettre du mot. Les nombres restants s'étendent de 1 à 6 (soundex initial) ou de 1 à 9 (Soundex avancé présenté ici), indiquant différentes catégories des bruits créés par les consonnes suivant la première lettre. Si le mot est trop court pour produire de 3 nombres, 0 est additionné comme nécessaire. Si le code produit est plus long que 3 nombres, les nombres supplémentaires sont enlevés.
    Pour former le code Soundex, on supprime les lettres suivantes :
    A, E, H, I, O, U, W, Y
    et on remplace les consonnes restantes avec la correspondance :

    Code Lettres
    1 B, P
    2 F, V
    3 C, K, S
    4 G, J
    5 Q, X, Z
    6 D, T
    7 L
    8 M, N
    9 R

    Il y a plusieurs cas spéciaux en calculant un code de soundex :
    Les lettres donnant le même soundex qui sont immédiatement à côté l'une de l'autre sont supprimées (dédoublonnage). Ainsi Pfizer devient Pizer, le sac devient sac, Czar devient voiture (;-) enfin ... car), Collins devient Colins, et Mroczak devient Mrocak.
    Exemples de Soundex :

    Mot Soundex
    Washington W252
    Wu W000
    DeSmet D253
    Gutierrez G362
    Pfister P236
    Jackson J250
    Tymczak T522
    Ashcraft A261


    On voit que le soundex est très grossier dans son analyse : seuls les 3 premières consonnes sont conservées.
    De plus, il n'est pas adapté à des mots longs voir à des expressions (du type "application soundex").
    Le point intéressant est surtout le principe d'amalgame des lettres resemblantes, i.e. m et n sont équivalentes ...

     III : Algorythme de "similar text"
    Ici, l'objectif coincide plus précisément avec notre problématique étant donné que cet algorythme compare 2 termes pour en ressortir la longueur de chaine "commune" au 2 termes.
    Cela s'apparente tout à fait au PGCD (Plus Grand Dénominateur Commun) bien connu en mathématique.
    Un exemple pour être explicite :
    terme 1 : application
    terme 2 : apicudation (mot inventé)
    L'algorythme va comparer les 2 termes lettres à lettre et incrémenter un "compteur" quand elle sont égale :
    Dans ce cas, on a 2 pour "ap" au début des 2 termes + 1 pour le i + 5 pour "ation" à la fin. Ce qui nous donne 8.
    On constate de suite que le résultat va dépendre de la longueur des termes et qu'il faut donc rapporter le résultat obtenu à la longueur des 2 chaines. La proportion (%) sera donc calculé par rapport à la longueur des chaines.


    Algorythme :
    Cet algorythme réalise une matrice de similarité des 2 termes comme illustré ci-dessous :
    metre matrice

    t e s t e
    0 0 0 0 0
    t 0 1 0 0 1 0
    e 0 1 2 2 2 2
    x 0 1 2 2 2 2
    t 0 1 2 2 3 3
    s 0 1 2 3 3 3

    On voit que cet algorythme est en o(n2) ce qui peut rapidement poser des soucis en terme de temps de traitement. Exemple de script PERL qui réalise ce calcul :
    sub LCS_Length($s1, $s2)
    {
       my($s1,$s2)=@_;
       my(@LCS_Length_Table,$m,$n,$i,$j);
       $m = length($s1);
       $n = length($s2);
       for($i=1; $i < $m; $i++){$LCS_Length_Table[$i][0]=0;}
       for($j=0; $j < $n; $j++){$LCS_Length_Table[0][$j]=0;}
      
       for ($i=1; $i <= $m; $i++) {
         for ($j=1; $j <= $n; $j++) {
           if (substr($s1,$i-1,1) eq substr($s2,$j-1,1)){$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j-1] + 1;}
           elsif ($LCS_Length_Table[$i-1][$j] >= $LCS_Length_Table[$i][$j-1]){$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j];}
           else {$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i][$j-1];}
           }
          }
     $result=$LCS_Length_Table[$m][$n];
     undef(@LCS_Length_Table);
      return $result;
     }

    Cette algorythme est bien adapté à la comparaison de terme, par contre il manque de souplesse au niveau des effets de bord (lettre quasi similaire, erreur de frappe, pluriel, ...).

     
  • IV : Algorythme de comparaison textuel
    En réalisant un agglomérat de ces 2 algorythmes, nous allons pouvoir faire un regroupement efficace de notre liste de termes.
    Le principe est simple :
  • Prendre la correspondance des lettres du soundex (en l'adaptant quelque peu)
  • Puis calculer la similarité entre les termes obtenus

    Le travail sur les sonorités va se faire sur toute la longueur des chaîne de caractère, mais sans supprimer les voyelles. Nous aboutissons alors aux transformations faites dans la fonction add_soundex_rule ci-dessous.
    Cette partie peut être modifiée aisément à souhait en s'adaptant aux problématiques linguistiques spécifiques.
    Ensuite, une fois les 2 termes transformés, on va mesure leur taux de ressemblance grâce à l'algorythme similar text.

    Exemple sur un script PERL :
    sub LCS_Length($s1, $s2)
    {
       my($s1,$s2)=@_;
       my(@LCS_Length_Table,$m,$n,$i,$j);
       $m = length($s1);
       $n = length($s2);
       for($i=1; $i < $m; $i++){$LCS_Length_Table[$i][0]=0;}
       for($j=0; $j < $n; $j++){$LCS_Length_Table[0][$j]=0;}
      
       for ($i=1; $i <= $m; $i++) {
         for ($j=1; $j <= $n; $j++) {
           if (substr($s1,$i-1,1) eq substr($s2,$j-1,1)){$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j-1] + 1;}
           elsif ($LCS_Length_Table[$i-1][$j] >= $LCS_Length_Table[$i][$j-1]){$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i-1][$j];}
           else {$LCS_Length_Table[$i][$j] = $LCS_Length_Table[$i][$j-1];}
           }
          }
     $result=$LCS_Length_Table[$m][$n];
     undef(@LCS_Length_Table);
      return $result;
     }


    # Transformation du Mots $saq suivant les regles "soundex" amélioré :
    # On supprime les caractères non alpha, on enleve les h, on fait une correspondance p->b ...on enlève les accents
    sub add_soundex_rule($saq){
    my($saq)=@_;
    $saq =~ s/é/e/gio;
    $saq = lc($saq);
    $saq =~ tr/a-zA-Z//s;
    $saq =~ tr/h/ /;
    $saq =~ s/[^a-z0-9]//gio;
    $saq =~ tr/pwkgxzdm/bvcjqqtn/;
    $saq =~ tr/éèêëàáâãäåìíîïòóôõöùúûüç/eeeeaaaaaaiiiiooooouuuuc/;
    $saq =~ s/ //gio;
    return $saq;
    }

    sub get_lcs($s1, $s2)
    {
    my($s1,$s2)=@_;
    my($ms,@tab,$lcs);
    $s1 = &add_soundex_rule($s1);
    $s2 = &add_soundex_rule($s2);

    $lcs=0;
    if (abs(length($s1)-length($s2))<6){$lcs = &LCS_Length($s1,$s2);} #longest common sub sequence
    else{$lcs = 0;}
    $ms = (length($s1) + length($s2)) / 2;

    if ($ms>0){
    $tab[0]=($lcs*100)/$ms;
    $tab[1]=$lcs;}
    else{$tab[0]=0;$tab[1]=0;}
    return (@tab);
    }



  •  
  • V : Conclusions

    En s'appuyant sur 2 algorythme bien connu, cette étude amène à la réalisation d'un algorythme assez puissant dans la comparaison des termes d'une liste.
    La transformation soundex peut être adaptée à une langue particulière pour prendre en compte une propriété linguistique spéciale.
    La fonction get_lcs retourne un pourcentage représentant la ressemblance entre les 2 termes. On peut donc jouer sur le taux de ressemblance à atteindre pour regrouper plus ou moins.
    Le seul inconvénient de cet algorythme est son temps d'exécussion qui est en o(n2) ou plus justement o(n*m) où n et m sont les longueurs des chaines traitées.
    Une optimisation peut être mise en place en restreignant la comparaison de type similar text qu'au terme de longueur proche (ABS(long(chaine1)-long(chaine2))<5).


    Etude réalisée par Laurent Patureau.
    www.idfr.net

  •    
     
    © 2004 IDfr
    Mentions légales | Plan du site |