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

SAS Base Discussion :

Détection de clients en double avec expression régulière


Sujet :

SAS Base

  1. #1
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut Détection de clients en double avec expression régulière
    Bonjour,

    Je suis sur un projet de détection des clients en double dans le système.
    Dans ce projet j'ai déjà détecté ceux qui ont les mêmes appelation de Nom , prénom , nom de la mère (à l'aide SOUNDEX), et la même date de naissance.

    Dans un second temps pour les clients potentiellement en double trouvés je vais comparer les adresses de résidence pour avoir une certitude qu'il s'agit des mêmes personnes (avant de chercher d'autres pistes).

    C'est un peu là que les choses se compliquent et que je sollicite votre soutien.

    Je suis capable (heureusement) de détecter les adresses parfaitement identique par contre je constate que j'en échappe quelques une, c'est pour cela je voudrais utiliser des expressions régulières pour décomposer l'adresse et la formater pour pouvoir l'utiliser plus facilement.
    Attention: je connais rien aux expressions régulières (nouveau défit), j'ai épluché la doc sas et le post suivant:

    Exemple:

    J'ai deux clients soupconnés d'être des doubles (no_benf=105843437) avec des adressess:
    518 RUE FAIRFIELD
    518 FAIRFIELD ST (pour street)

    Comment faire en sorte que ce type d'exemple soit détecté comme des doubles avec même adresse?
    En remplacant ST par RUE, en enlevant Rue ou st ou boul et comparer uniquement le nom et le numéro ?

    Dans mon code ci-dessous je tente d'extraire le numéro, et le nom mais sans succès.
    PS: le numéro de rue peut-être jumelé au numéro d'appartement (séparer par un - ou espace et contenir des lettres)

    Merci de votre aide.

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
     
     
    DATA WORK.tab_Adresse;
        LENGTH
            NO_BENF            8
            client             8
            Adr_lig_1        $ 30
            adr_lig_2        $ 22
            copos            $ 6
            Raison           $ 13
            Commentaire      $ 28 ;
        FORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFILE DATALINES4
            DLM='7F'x
            MISSOVER
            DSD ;
        INPUT
            NO_BENF          : BEST32.
            client           : BEST32.
            Adr_lig_1        : $CHAR30.
            adr_lig_2        : $CHAR22.
            copos            : $CHAR6.
            Raison           : $CHAR13.
            Commentaire      : $CHAR28. ;
    DATALINES4;
    105821367121341167 2400 RUE SAINT-JEAN-BAPTISTE JONQUIERE QCG8A1X1  
    105821367947338550 3446 RUE DU ROI-GEORGES JONQUIERE QCG7S5T5  
    105843437546359759 518 RUE FAIRFIELDGREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105843437759354442 518 FAIRFIELD ST GREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105850010217135116 3-124 LAVERGNE VANIER ONK1L5E7  
    105850010259317647 187 RTE DU ROCHER-PERCE CHAMBORD QCG0W1G0  
    105853766746379541 253 RUE DES GRIVES SAINT-NICOLAS QCG7A3G6  
    105853766806370452 1204-610 BULLOCK DR MARKHAM ONL3R0G1  
    105857759418391166 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105857759730305543 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105862486563306436 201 TIPPERARYSHEDIAC NBE4P2V7  
    105862486638303041 1651 RUE PRINCIPALE CHAMBORD QCG0W1G0  
    105873228265335331 327A RUE HILAIRE BOIS-DES-FILION QCJ6Z1C9  
    105873228578353641 3 RUE DE LA CHATELAINE TERREBONNE QCJ6X4C4  
    105877039208354726 211-12590 RUE SHERBROOKE E POINTE-AUX-TREMBLES QCH1B1C9  
    105877039764395539 2-7920 RUE MADELEINE-HUGUENINMONTREAL QCH1L6M7  
    105877443309341934 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse 
    105877443671338223 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse  
    ;;;;
     
     
     
    /*TOUT UN DÉFI*/
     
    Data essai;
    set tab_adresse;
    retain prxid;
    IF _N_=1 then do;
    		expression = "/([0-9].[a-z]*?||-[0-9]*?)[ ]*(.+)/";
    		prxid=prxparse(expression);
    		IF missing(prxid) Then do;
    			putlog "ERREUR:Expression Régulière Invalide :" expression;
    			stop;
    		end;
    end;
     
    if ^prxmatch(prxid,Adr_lig_1 )then 
    	putlog "AVERTISSEMENT:pas d'adresse valide dans la ligne :" Adr_lig_1 ;
    else do;
     
    call prxposn(prxid,1,position,taille);
    numero =substr(Adr_lig_1 ,position,taille);
    call prxposn(prxid,2,position,taille);
    nom =substr(Adr_lig_1 ,position,taille);
    putlog "NOTE: numero :" numero;
    putlog "NOTE: nom :" nom;
    end;
     
    run;

  2. #2
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Bonjour,

    je travaille sur des choses similaires aux tiennes (regroupement d'adresses semblables, auto apprentissage des adresses alternatives).

    Les expressions régulières peuvent sembler dans un premier abord la chose à utiliser, cependant de par mon expérience c'est chose complexe, du fait de la variabilité des adresses (selon aussi si tu récupère dans la même variable adresse des bâtiments numéro de porte etc...). Les expressions régulières ne reconnaitrons pas tout, par contre elles permettent de normaliser les choses avant de faire des comparaisons plus ou moins sioux...

    Compte tenu du caractère très spécifique et de la complexité variable qui dépend de la source, je ne peux pas te proposer ici une recette générale, mais quelques recettes en message privé qui pourrons s'accommoder plus ou moins bien à la forme de tes données.


    Bon courage.

  3. #3
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Merci ce sera déjà un début...je ne me mets pas de stress, je vois cela comme une occasion d"apprendre autres choses.

    En effet la variabilité est telle qu'il faut faire attention à des programmes standards.

    L'avantage de ce type de projet c'est la liberté de réflexion sur les méthodes à appliquer...en mode essai-erreur-essai...jusqu'à trouver quelque chose de concluant.

  4. #4
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Euh...je voulais poster ce message dans SAS Base...quelqu'un avec les droits pourrait-'il le dépalcer ?

  5. #5
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Double post je n'avais pas vu ton exemple.
    Tes adresses ont l'air d'être propre.

    Dans ce cas spécifique favorable voici comment je m'y prendrais.
    Enfin je n'ai pas trop le temps devant moi pour m'attarder aujourd'hui.

    Si tu veux être sûr d'avoir vraiment des choses qui sont "bonnet blanc" et "blanc bonnet"
    du genre effectivement FAIRFIELD ST et RUE FAIRFIEL

    Je me confectionnerais d'abord une table-dictionnaire "bilingue"

    Langue Texte Type
    FR RUE RU
    FR R RU
    FR ROUTE RD
    EN ROAD RD
    EN STREET RU
    EN ST RU
    FR VOIE V
    FR V V
    EN LANE V

    etc...

    Langue : la langue d'origine
    Texte : le texte désignant le type de voie ou l'abréviation du type de voie
    Type : une variable "bi-lingue" de classification des types de voie , ici on choisi que STREET en ANGLAIS est de type "RU" , de même que RUE en français (en clair que les désignations sont équivalents RUE(FR)=RU=STREET(EN))

    Cette table je l'utiliserais pour confectionner autant d'expressions régulières (via une macro) qu'il y a de lignes dans dans la table dictionnaire.

    De REGEX_FR1 à REGEX_FRn si il y a n entrées françaises dans ta table dictionnaire.
    De REGEX_EN1 à REGEX_ENm si il y a m entrées anglaises dans ta table dictionnaire.

    Il te faut pour ça te définir un "motif" de numéro de rue
    Tu parle de numero (par exemple 4 chiffres maxi) suivi d'un blanc ou - suivi de chiffres ou lettres)

    Tu peux définir alors un motif_num (par exemple , je ne sais pas à quoi ressemble tes numéros d'appartement).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %LET motif_num=[0-9]{4}(?:(?:\-|\s)(?:[0-9]{1,2}[A-Z]?|[A-Z][0-9]{1,2}))??  (je ne suis pas tout a fait sûr de la place du ??)
    Tu définie une forme "française" d'expression régulière et une forme "anglaise"

    REGEX_FR1=PRXPARSE("s/(&motif_num.)\s(&TEXT_FR1.)\s([A-Z\-\s]+)/*$1*$2*$3*&TYPE_FR1/");

    Une forme anglaise REGEX_EN1=PRXPARSE("s/(&motif_num.)\s(&TEXT_EN1.)\s([A-Z\-\s]+)/*$1*$2*$3*&TYPE_EN1/");

    en ayant eu soin de créer auparavant les macro variables &TEXTE_ENk(k=1 à m) &TYPE_ENk(k=1 à m) à partir de la table dictionnaire pour k=1 à m et des variables Texte et Type.

    Tu créé de la même façon &TEXTE_FRk(k=1 à n) et &TYPE_FRk(k=1 à n).

    Ensuite tu créé les variables en passant en revue toutes les expressions régulières de chaque langue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    boucle sur k=1 à n
    IF PRXMATCH(REGEX_EN&k,adresse) THEN adresse_reconnue_EN=PRXCHANGE(REGEX_EN&k,1,adresse);
     
    boucle sur k=1 à m
    IF PRXMATCH(REGEX_FR&k,adresse) THEN adresse_reconnue_FR=PRXCHANGE(REGEX_FR&k,1,adresse);
    une fois que tu as fait ça tu as transformée
    ton adresse="518 RUE FAIRFIELD" en adresse_reconnue_FR="*518*RUE*FAIRFIELD*RU*"

    et ton adresse "518 FAIRFIELD ST" en
    adresse_reconnue_EN="*518*FAIRFIELD*ST*RU*"

    ensuite il te suffit de faire une comparaison entre les CLE1_FR , CLE3_FR et CLE4_FR
    (adresse_reconnue_FR étant du type "*CLE1_FR*CLE2_FR*CLE3_FR*CLE4_FR*")
    et les clés CLE1_EN ,CLE2_EN et CLE4_EN
    (adresse_reconnue_EN étant du type "*CLE1_EN*CLE2_EN*CLE3_EN*CLE4_EN*")

    avec CLE1_FR=CLE2_FR , CLE3_FR=CLE2_EN et CLE4_FR=CLE4_EN

    Ici j'ai conservé CLE2_FR et CLE3_EN pour éventuellement lever des indéterminations sur le dictionnaire par des test adhoc supplémentaires (dans le cas de R de RUE ou le R de ROUTE en français par exemple).

    CLE1_FR=518=CLE1_EN
    CLE3_FR=FAIRFIELD=CLE2_EN
    CLE4_FR=RU=CLE4_EN



    Alors ça peut paraitre très compliqué, mais le fait est qu'on se fatigue très vite à faire des expression régulières compliquées et les reprendre 15 fois parce qu'on a un type de voie supplémentaire etc...
    Ca devient très compliqué dès qu'on a quelques cas différents et
    les expressions deviennent très très gourmandes en temps d'évaluation.

    Là tu génère des expressions régulière "à la volée", sans les écrire, etrapidement évaluées,
    et si tu as besoin de rajouter un type de voie ou une abréviation de type de voie qui n'est pas encore connue tu n'as qu'à rajouter une ligne au dictionnaire, qui ensuite créera automatiquement l'expression régulière correspondante.

    Et tu peux même au besoin la rendre un peu plus intelligente (moyennant du code supplémentaire) mais je n'irais pas plus loin c'est déjà suffisamment compliqué !!!

    Tu peux au besoin tester des "physionomies" alternatives d'expressions régulières pour traiter par exemple si tu as des cas plus exotique (je n'en sais rien) FAIRFIELD ST,518 , sans tout refaire, que la forme de l'expression régulière de base (ici c'était celle-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    REGEX_langue(k)=PRXPARSE("s/(&motif_num.)\s(&TEXT_langue(k))\s([A-Z\-\s]+)/*$1*$2*$3*&TYPE_langue(k)/");
    ).

    Alors il faut être rigoureux au début, ça prend du temps à coder, c'est pas tout à fait immédiat, c'est un vrai investissement, mais par la suite ça devient incroyablement souple d'utilisation.

    Dans l'écriture de la macro par contre faire attention, quelque fois on a besoin de %STR() pour masquer certains caractères ne pas oublier).

    Concrètement pour la mise en oeuvre, j'ai un programme qui créé la table dictionnaire, il créé les différentes macro variables, et ensuite ce programme créé un fichier .sas codant une macro définissant toutes les expressions régulières (en "dur")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    %macro REGEX;
    RETAIN REGEX1_FR REGEX2_FR REGEX1_EN REGEX2_EN etc... ;
    IF _N_=1 THEN DO;
    REGEX1_FR=PRXPARSE(....);
    REGEX2_FR=PRXPARSE(...) ;
    REGEX1_EN=PRXPARSE(....);
    REGEX2_EN=PRXPARSE(...) ;
    etc...
    END;
    DROP REGEX1_FR REGEX2_FR REGEX1_EN REGEX2_EN etc....
     
    %mend;
    Comme ça tu peux voir simplement le code généré si tout semble OK, et tester des alternatives d'écriture en partant de REGEX toutes faites.

    Ensuite dans ton programme de comparaison tu insère %regex;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    %INCLUDE(chemin de regex.sas) ;
     
    DATA COMPARE;
    SET SOURCE;
    %regex;
     
    utilisation des regex définies
     
    blabla;
     
    RUN;

  6. #6
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Tes adresses ont l'air d'être propre.
    C'est juste un micro extrait de la base....

    ...tout un défi !

    Je vais pas me dégonfler en si bon chemin....

    Je vais essayer y aller étape par étape...et reviens bientôt.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Et oui... faut s'armer de courage !

    N'hésite pas à me demander des choses.

    Bonne journée et COURAGE

  8. #8
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    @jérôme : si les regex sont compliquées à l'emploi, est-ce que FCMP permettrait de les appliquer plus facilement ?
    Par exemple on aurait une fonction recherche() ou similitude(champ1,champ2) qui cacherait derrière du code assez lourd en regex.
    Se serait quelque chose d'intéressant ?
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  9. #9
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Bonjour Datametric,
    je n'ai pas trop compris ce que tu propose.

    Mettre des expression régulières dans une proc FCMP ? J'ai jamais fait

    Et quelque part si c'est pour mettre du code lourd de Regex derriere la fmcp ça reviens à faire une macro, mais oui c'est "plus portable" on va dire.

    Oui je pense plutot que générer une %regex on pourrait générer une fonction "similitude" ou même plusieurs

    Après c'est une question de choix d'utilisation, et de choix de test (les fameux essais/erreurs), perso débugguer des expression régulières créées dans une FCMP ça me ferrait un peu peur !! alors que dans une macro, on a accès facilement au code de la regex et on peut la tester séparément de la chaine pour éventuellement revoir ensuite le code de génération de la macro, c'est cette partie de mise au point plus aisée qui m'a fait opter pour l'option macro plutôt que fonction.

    Pour les autres tests sans regex, j'ai créé effectivement des fonctions via FCMP, mais franchement je n'ai pas osé m'aventurer sur cette pente là avec les REGEX connaissant les multiples essais nécessaires a trouver la bonne regex. Mais si c'est possible ça peut être pratique effectivement.

    J'aurais quand même tendance à rester sur du code macro, pour son côté "boite à outils" (réutilisation d'une partie du code en cours de programmation pour une utilisation jusque là non prévue "tiens il me faut ça, ah mais c'est déjà calculé dans la macro " ).

  10. #10
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    J'imaginais également un run_macro() dans la fcmp.
    Comme j'écris un petit cours sur la FCMP, je me posais cette question car j'ai du mal à trouver de la pertinence à la FCMP connaissant les autres possibilités (macro) et son jeunisme. Je cherchais un peu de prétexte à ne pas faire le dinosaure sur SAS en rejetant d'emblée la nouveauté...

    Merci. Je voulais ton avis.
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  11. #11
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Ah un exemple où la proc FCMP est utile ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    PROC SQL;
    CREATE TABLE CONCORDE
    AS SELECT TAB1.*,TAB2.*
    FROM Adresses_a_valider AS TAB1,Referentiel_adresses AS TAB2
    WHERE SIMILARITE(TAB1.adresse,TAB2.adresse);
    QUIT;
    C'est quand même pratique quelques fois, la fonction SIMILARITE étant complexe à calculer elle ne pouvait pas rentrer dans une SQL directement (hors c'est ce que j'avais envie de faire) et avec la FCMP c'était réglé

    Cependant c'est rare que la FCMP soit incontournable..., elle plus fréquemment "plus pratique" quand à l'écriture du code, surtout si on génère plein de variables et que l'on utilise des structures en ARRAY et qu'on pas envie de faire un DROP pour toute les citer, plutôt qu' "incontournable".

  12. #12
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    L'utilisation des fonctions en tant que produit fini est effectivement très intéressante. C'est au développeur de se concentrer sur le contenu et c'est là où les problèmes peuvent surgir. En attendant l'utilisation telle que tu le montres paraît très séduisante.
    Concernant le développeur il doit gérer les array et autre spécificité de la sorte. Mais ces arrays apparaissent quand même assez loufoque notamment lorsqu'il s'agit de passer un ensemble de variables à la fonction (cf. Varargs) il faut en effet créer un array temporaire pour y enregistrer les valeurs une à une.

    J'ai trouvé un intérêt en créant une fonction similaire à une espèce de grand total qui remettrait cette valeur dans la table pour une colonne spécifique (Le langage SQL le fait déjà très bien je ne vois pas pourquoi on ne pourra pas faire pareil dans une Data)
    Le bémol que j'ai trouvé pour le moment est qu'il faut nommer dans l'appel de la fonction le nom de la table.
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  13. #13
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    J'ai trouvé ça sur le sujet (initial).

    http://analytics.ncsu.edu/sesug/2008/CC-028.pdf
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  14. #14
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Bonjour,

    Exemple très utile. J'ai quelques difficultés à adapter les expressions (surtout le numéro) à mon cas.

    Par contre j'arrive facilement à isoler le numéro d'appartement et celui de la rue du numéro de l'adresse avec des simples SCAN et SUBSTR.
    Avec cette méthode j'arrive pas à extraitre la suite après le numéro.

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
     
     
    DATA WORK.tab_adresse;
        LENGTH
            NO_BENF            8
            client             8
            Adr_lig_1        $ 30
            adr_lig_2        $ 22
            copos            $ 6
            Raison           $ 13
            Commentaire      $ 28 ;
        FORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFILE DATALINES4
            DLM='7F'x
            MISSOVER
            DSD ;
        INPUT
            NO_BENF          : BEST32.
            client           : BEST32.
            Adr_lig_1        : $CHAR30.
            adr_lig_2        : $CHAR22.
            copos            : $CHAR6.
            Raison           : $CHAR13.
            Commentaire      : $CHAR28. ;
    DATALINES4;
    105821367121341167 2400 RUE SAINT-JEAN-BAPTISTE JONQUIERE QCG8A1X1  
    105821367947338550 3446 RUE DU ROI-GEORGES JONQUIERE QCG7S5T5  
    105843437546359759 518 RUE FAIRFIELDGREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105843437759354442 518 FAIRFIELD ST GREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105850010217135116 3-124 LAVERGNE VANIER ONK1L5E7  
    105850010259317647 187 RTE DU ROCHER-PERCE CHAMBORD QCG0W1G0  
    105853766746379541 253 RUE DES GRIVES SAINT-NICOLAS QCG7A3G6  
    105853766806370452 1204-610 BULLOCK DR MARKHAM ONL3R0G1  
    105857759418391166 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105857759730305543 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105862486563306436 201 TIPPERARYSHEDIAC NBE4P2V7  
    105862486638303041 1651 RUE PRINCIPALE CHAMBORD QCG0W1G0  
    105873228265335331 327A RUE HILAIRE BOIS-DES-FILION QCJ6Z1C9  
    105873228578353641 3 RUE DE LA CHATELAINE TERREBONNE QCJ6X4C4  
    105877039208354726 211-12590 RUE SHERBROOKE E POINTE-AUX-TREMBLES QCH1B1C9  
    105877039764395539 2-7920 RUE MADELEINE-HUGUENINMONTREAL QCH1L6M7  
    105877443309341934 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse 
    105877443671338223 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse  
    ;;;;
     
     
    data adressees;
    	set tab_adresse;
    	length
    		adresse $55.
    		RueNum $10.
    		Ruenom $40.
    	;
     
    	/*suppression des blancs, remplacement de blancs successifs par un seul*/
    	adresse = left(trim(compbl(adr_lig_1)));
     
    	/*METHODE BASIQUE D'EXTRACTION DE COMPOSANTS CARACTÈRES*/
     
    	Numero=scan(adresse,1,' '); /*OK*/
    	IF find(Numero,"-")>0 then do;
    		appartement=scan(Numero,1,'-') ; /*OK*/
    		numero=compress(scan(Numero,2,'-')); /*OK*/
    	end;
     
    	 /*Extraction classique rue PAS OK veut scanner la suite et pas juste le mot suivant*/
    	IF find(Numero,"-")>0 then
    		rue=compress(scan(adresse,3, ' '));
    	ELSE rue=compress(scan(adresse,2, ' ')) ;
     
     /*UTILISATION EXPRESSION REGULIÈRE*/
     
    	/*definition des modèles*/
    	if _N_ = 1 then
    		do;
    			modeleadresse = "/(\d+)[\s\w\#]+/i"; /*PAS OK ne prend pas en compte les noms composés*/
    			modele_adresse = prxparse(modeleadresse);
    			modeleRueNum = "/(\d+)\w*/i"; /* PAS OK bug si appartement prendre numéro entre - et 1er blanc*/
    			modele_RueNum = prxparse(modeleRueNum);
    		end;
     
    	retain  modele_adresse modele_RueNum;
     
     
    	/* modele_adresse is Rue number, nom */
    	call prxsubstr(modele_adresse, adresse, position, length);
     
    	if position ^= 0 then
    		do;
    			match = substr(adresse, position, length);
    			call prxsubstr(modele_RueNum, match, position2, length2);
     
    			if position2 ^= 0 then
    				do;
    					match2 = substr(match, position2, length2);
    					RueNum = match2;
    					Ruenom = trim(compress(substr(match, length2+1 ),','));
    				end;
    			else
    				do;
    					Ruenom = match;
    				end;
    		end;
     
    run;
    @jerome_pdv2: mon client me conseille d'essayer le dictionnaire qu'en dernier recours, un département se casse déjà la tête avec...les formats d'adresses n'ont de limite que l'imagination des agents donc pour lui mieux vaut comparer le numéro (de la rue) et le code postal. Les clients identifiés sont déjà potentiellement des doubles (donc à vérifier par les agents de toute façon) on veut en comparant les adresses avoir des certitudes et des pistes de recherches.

    Merci.

  15. #15
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Ca vient de me revenir je supprimais les mots faibles des adresses pour ne conserver que les mots forts. Ainsi, tous les RUE, ST, STREET, DE, LA, "-" tirets, et même blanc entre les mots etc ... supprimés allégeaient l'adresse et permettaient de travailler sur le vrai contenu avec SOUNDEX et toutes les autres fonctions similaires.
    SOUNDEX sur ce type de nettoyage permet de trouver une similitude entre FAIRFIELDGREENFIELD et FAIRFIELD ST GREENFIELD
    surtout quand copos est le même.
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  16. #16
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Citation Envoyé par datametric Voir le message
    Ca vient de me revenir je supprimais les mots faibles des adresses pour ne conserver que les mots forts. Ainsi, tous les RUE, ST, STREET, DE, LA, "-" tirets, et même blanc entre les mots etc ... supprimés allégeaient l'adresse et permettaient de travailler sur le vrai contenu avec SOUNDEX et toutes les autres fonctions similaires.
    SOUNDEX sur ce type de nettoyage permet de trouver une similitude entre FAIRFIELDGREENFIELD et FAIRFIELD ST GREENFIELD
    surtout quand copos est le même.
    Très intéressant ...dans ma tête je me disais la même chose, ce serait tellement cool de faire cela, là où ca ce gate C'EST COMMENT LE FAIRE

    Raison pour laquelle j'aime bien
    je supprimais les mots faibles des adresses pour ne conserver que les mots forts

    Question qui suit : Tu as fais comment? S'agit-il encore de ton histoire de FCMP ?

  17. #17
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Et bien je cherchais les chaînes et je remplace par un blanc. Puis je supprime les blanc avec Compress.
    Un peu comme là
    http://www.developpez.net/forums/d67...lusieurs-mots/
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  18. #18
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Citation Envoyé par MDsas Voir le message

    @jerome_pdv2: mon client me conseille d'essayer le dictionnaire qu'en dernier recours, un département se casse déjà la tête avec...les formats d'adresses n'ont de limite que l'imagination des agents donc pour lui mieux vaut comparer le numéro (de la rue) et le code postal. Les clients identifiés sont déjà potentiellement des doubles (donc à vérifier par les agents de toute façon) on veut en comparant les adresses avoir des certitudes et des pistes de recherches.

    Merci.
    Bonjour,
    "les formats d'adresses n'ont de limite que l'imagination des agents..."

    effectivement, c'est pour ça que les méthodes trop générales sont condamnées à l'échec et/ou des succès partiels.

    Mon principe est de réaliser sur ces problèmes de reconnaissance d'adresses une attaque que je qualifierais de "multi-fronts" constituée de stratégies successives et non d'une seule stratégie simultanée.

    Tout simplement déjà parce qu'une bonne part des adresses que l'on ne reconnait pas ont une variabilité relativement "régulière" sans pour autant être des cas tordus, et qu'il y a lieu de s'intéresser à ces cas en priorité.

    Les cas les plus délicats, nécessitant des méthodes plus élaborées sont noyées dans la masse des cas "gentils" ce qui empêche d'avoir une évaluation correcte de leur proportion et parfois compromet l'élaboration de stratégies d'attaques du fait du faible nombre d'exemple "immédiatement" distinguables noyés au milieu dans les cas les plus simple et du coup aussi souvent beaucoup plus abondants (les individus (agents, propriétaires, locataires, urbaniste, administration postales, informaticien) tordus étant par définition moins communs que les "normaux" , leur production est du coup également moins courante ! ).

    Cela permet en outre de savoir à quel moment on s'arrête en se fixant un seuil de rebus au-delà duquel on souhaite ne pas aller (ce qui n'est pas toujours évaluable je le conçois bien, notamment dans ton problème).

    Il y a aussi un intérêt certain en combinant ces méthode avec des méthodes d'auto-apprentissage plus complexe (qui nous emmène un peu plus loin).

    Comme je te l'avais dit, ce que je te proposais n'était pas une méthode générale. Mais une première approche. Cela permet un premier dégrossissage.

    Le cas que tu soulève avec les cas numéro d'appartement + numéro de voie.
    Apparemment au Québec c'est dans cet ordre là, en France c'est beaucoup plus communément l'inverse.
    Il peut-être intéressant, surtout si les numeros d'une voie ne correspondent que rarement à des numéros d'appartements de la même voie à ne pas choisir le numéro de voie comme clé unique de reconnaissance d'adresse (dans une optique de géolocalisation de grand quartiers collectifs par exemple), mais éventuellement à dupliquer les adresses avec le numéro de voie comme clé pour l'une et le numéro d'appartement pour l'autre.

    Mais là encore tout dépend de ton problème. Car sur des numéro d'appartement surtout si codés sur plusieurs chiffres, la présence du libellé de voie + du numéro d'appartement + du nom de la personne peut être considérés comme des indices sérieux qu'il s'agit de la même personne.
    Et d'un autre côté sur une clé plus faible constituée d'un seul chiffre peut-être pas....c'est un choix à faire, une calibration à faire sur le test, et éventuellement un risque à prendre (avoir une idée des coûts/avantages sachant qu'on part d'une situation initiale d'échec, ce qu'il ne faut pas perdre de vue).

    Enfin des stratégie de duplication peuvent être dans certains cas intéressantes dès lors que chacun des doublons peuvent être considérés comme des clés sérieuses.

    En résumé, si de la Clé1 on envisage des versions probables Clé2 et Clé3 , générer automatiquement Clé2 et Clé3 comme versions possibles dès lors que l'on rencontre Clé1 peut permettre de reconnaitre un match sur Clé1 avec Clé2 sans avoir recours a des fonctions d'identifications trop lourdes.
    Car Clé2 et Clé3 si on les envisage, l'agent les envisagent également, et en choisi une parmi les 3.

    Donc pour moi pas de méthode générales, mais des méthodes particulières et distinctes ET successives, du plus "commun" au plus "spécifique".

    Etape 1 - Fichier0 / Methode 1
    (par exemple sur dictionnaire simple sans abréviations ).

    ->Quelles sont les adresses non reconnues dans l'absolu par cette méthode ?
    On Place ce rebus un fichier1
    Etape 2 - Fichier1 / Méthode 2
    (par exemple sur dictionnaire avec prise en compte des abréviations)
    On place le rebus dans un fichier2

    Etape 3 - Fichier2 / Methode 3

    blablabla méthode
    On place le rebus dans un fichier 3

    Etape 4 - Fichier 3 / Méthode 4

    blablabla....
    rebus --> Fichier 4

    Bon j'ai pris mon exemple, j'aurais pu prendre celui de Stéphane, ou d'autres, juste pour montrer le squelette de la méthode (globale, globale mais pas générale)

    Et tu peux également alterner phase de "normalisation" et de "test d'identification".

    Pour moi il n'y a pas de méthode générale. Y a des recettes.

    Il est plus facile de multiplier les méthode légères et simples que de concevoir une méthode lourde, difficile à mettre au point et difficile à maintenir.

    Il ne faut pas être rigide, accepter la variabilité et au besoin s'en servir et s'en faire une alliée (méthode de duplications de clé par exemple comme expliquée au dessus).

    Et instaurer en méthode la mise de côté systématique de la majorité qui semble "carré" et mettre au points les méthodes successives sur les seuls rebus successifs (car ce sont eux qui créent les échecs).


    Car pour moi ton problème, c'est d'abord des normalisations successives.
    Dans un premier temps on normalise le maximum de choses (et à cet occasion au besoin créé des doublons qui permettent aussi parfois non seulement de traiter la variabilité mais également les ambiguités, et il n'y a pas une seule méthode de normalisation).

    Et dans la deuxième phase seulement passer aux méthodes de comparaison.

    Edit :
    Ne pas oublier dans ton processus le code postal, qui est me semble particulièrement important au Quebec du fait de sa forme variable (malheureusement) mais aussi de sa précision (heureusement).
    Par exemple pour localité de Plaisance tu vas rencontrer J0V 1S0 je crois mais aussi JOVISO avec des numéros remplacés par des lettres (et vice versa).
    Vos codes postaux sont plus précis que les codes postaux français et lors de la comparaison cela peut-être fort utile pour écarter les adresses semblables ou les détecter.

    Enfin dans les méthodes de comparaisons, des méthodes plus hybrides de comparaison par "scores voisins" peuvent être intéressant pour combiner plusieurs tests.

    Par exemple

    Test1 : test sur code postal, non match ->0 , match non ambigüe -> 12 , match ambigüe (exemple 2 fois nombre de lettre ou chiffre communs dans le même emplacement du code postal) ex JOVISO et J0V 1S0 --> 6
    Test2 : sur adresse, 0 , 10 et ? de 1 à 9 par exemple (fonction inverse de distance normalisée)
    Test 3 : distance inverse normalisée (de 0 à 6 par exemple) entre les deux patronymes
    Score Global=Score1+Score2+score3

    Si Score global>20 par exemple alors on peut considérer qu'on a un doublon.
    Le score considéré permet alors des jointures "floues" mais contrôlées (cf discussion avec Stéphane sur la FCMP et l 'exemple de la SQL)

  19. #19
    Membre actif
    Femme Profil pro
    Analyste en Intelligence d'Affaires (BI)
    Inscrit en
    Avril 2008
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : Analyste en Intelligence d'Affaires (BI)
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 245
    Points : 290
    Points
    290
    Par défaut
    Bonjour,

    Merci de vos réactions...ca me désespère encore plus

    Jerome_pdv2 j'abonde certe dans ton sens mais je me dis que si j'arrive même pas à écrire correctement une expression reg c'est presque peine perdue et c'est pas faute d'essayer

    Pour info:

    Par exemple pour localité de Plaisance tu vas rencontrer J0V 1S0 je crois mais aussi JOVISO avec des numéros remplacés par des lettres (et vice versa).
    Je ne pense pas que je vais rencontrer ce genre de cas, le système de code postal est assez rodé et la plupart des systèmes ne permettent pas la saisie de 2 lettres consécutives, depuis que je vis ici j'ai jamais rencontrer ce cas de figure (données, ou réalité). Donc je n'ai pas à prévoir cela.


    Donc si je recapitule :

    Pour le moment sur l'échantillon sur lequel je travaille j'obtiens les résultats suivants:

    Méthode 1 : comparaison bête et méchante des adresses postales (numéro apt s'il y a lieu, numéro de rue, rue)+code postal...je récupère 35 % de cas où pour chaque couple détecté j'ai la même adresse (832/2365)

    Méthode 2 (avec SCAN et SUBSTR) : comparaison du numéro de la rue+code postal ...je récupère 40 % de cas où pour chaque couple identifié j'ai la même adresse (948 cas). En effet avec cette technique en regardant quelques éléments je récupère des cas semblables à ceux là :
    adresse numrue code postal
    518 RUE FAIRFIELD 518 J4V2A2
    518 FAIRFIELD ST 518 J4V2A2

    8380 14E AV 8380 H1Z3M3
    8380 14E AVENUE 8380 H1Z3M3

    404-5805 GRANDE-ALLEE 5805 J4Z3G4
    404-5805 BOUL GRANDE-ALLEE 5805 J4Z3G4

    1511 RANG SAINT-AUGUSTIN RR 2 1511 G0X3A0
    1511 RANG ST-AUGUSTIN 1511 G0X3A0

    731 CHEMIN DU LAC-GOULET 731 G0X1N0
    731 CH DU LAC-GOULET 731 G0X1N0

    108 AV PREMIERE O 108 J8T6L5
    108 1RE AV O 108 J8T6L5
    Méthode 3 (que je tente désespérement) (test sur un sous échantillon fournit dans les codes plus haut et remis plus bas)

    Utiliser les expressions régulières pour extraire le numéro et la rue:

    Le modèle que j'ai pris dans l'exemple de Stéphane marche presque donc je voudrais au moins le faire fonctionner dans un premier temps:
    Ce qui marche presque:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    modeleadresse = "/(\d+)[\s\w*\#]+/i"; 
    modele_adresse = prxparse(modeleadresse);
     
    modeleRueNum = "/(\d+)\w*/i"; 
    modele_RueNum = prxparse(modeleRueNum);
    L'adresse ne fonctionne pas pour les nom composés :
    85 RUE PAUL-ALBERT devient RUE PAUL
    Solution qui me semble logique selon TOUS les écrits que j'ai épluchés:
    Adresse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    modeleadresse = "/(\d+)[\s\w*\[-|s]*\w*]+/i";
    Traduction : Je croise un chiffre puis un espace puis plusieurs caractères puis 0 ou plusieurs tirets ou un espace puis plusieurs caractères

    Le modèle du numéro ne fonctionne pas également lorsque'il y a un appartement et pas toujours bizarrement ???


    1204-610 BULLOCK DR donne 1204
    2-7920 RUE MADELEINE-HUGUENIN donne 7920 ????
    Je voudrais prendre le numéro entre " - " si existe et 1er blanc
    Numéro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    modeleRueNum = "/(\d+)[-]?(\d+)\w*/i";
    Traduction : je croise un chiffre ouis 0 ou 1 tirets puis un chiffre et après des caractères
    Qu'est-ce qui cloche dans mes modèles pour que ca donne rien en résultat?

    Méthode 4 : on va d'abord résoudre la méthode 3 après penser à :

    Supprimer les mots superflues et utiliser SOUNDEX s'il le faut cf Stéphane.


    Code intégral:

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
     
    DATA WORK.tab_adresse;
        LENGTH
            NO_BENF            8
            client             8
            Adr_lig_1        $ 30
            adr_lig_2        $ 22
            copos            $ 6
            Raison           $ 13
            Commentaire      $ 28 ;
        FORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFORMAT
            NO_BENF          BEST12.
            client           BEST12.
            Adr_lig_1        $CHAR30.
            adr_lig_2        $CHAR22.
            copos            $CHAR6.
            Raison           $CHAR13.
            Commentaire      $CHAR28. ;
        INFILE DATALINES4
            DLM='7F'x
            MISSOVER
            DSD ;
        INPUT
            NO_BENF          : BEST32.
            client           : BEST32.
            Adr_lig_1        : $CHAR30.
            adr_lig_2        : $CHAR22.
            copos            : $CHAR6.
            Raison           : $CHAR13.
            Commentaire      : $CHAR28. ;
    DATALINES4;
    105821367121341167 2400 RUE SAINT-JEAN-BAPTISTE JONQUIERE QCG8A1X1  
    105821367947338550 3446 RUE DU ROI-GEORGES JONQUIERE QCG7S5T5  
    105843437546359759 518 RUE FAIRFIELDGREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105843437759354442 518 FAIRFIELD ST GREENFIELD PARK QCJ4V2A2 devrait être la même adresse
    105850010217135116 3-124 LAVERGNE VANIER ONK1L5E7  
    105850010259317647 187 RTE DU ROCHER-PERCE CHAMBORD QCG0W1G0  
    105853766746379541 253 RUE DES GRIVES SAINT-NICOLAS QCG7A3G6  
    105853766806370452 1204-610 BULLOCK DR MARKHAM ONL3R0G1  
    105857759418391166 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105857759730305543 85 RUE PAUL-ALBERT BLAINVILLE QCJ7E4H5Même adresse 
    105862486563306436 201 TIPPERARYSHEDIAC NBE4P2V7  
    105862486638303041 1651 RUE PRINCIPALE CHAMBORD QCG0W1G0  
    105873228265335331 327A RUE HILAIRE BOIS-DES-FILION QCJ6Z1C9  
    105873228578353641 3 RUE DE LA CHATELAINE TERREBONNE QCJ6X4C4  
    105877039208354726 211-12590 RUE SHERBROOKE E POINTE-AUX-TREMBLES QCH1B1C9  
    105877039764395539 2-7920 RUE MADELEINE-HUGUENINMONTREAL QCH1L6M7  
    105877443309341934 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse 
    105877443671338223 202-1440 RUE ONESIME-VOYER QUEBEC QCG1Y3L1Même adresse  
    ;;;;
     
     
    data adressees;
    	set tab_adresse;
    	length
    		adresse $55.
    		RueNum $10.
    		Ruenom $40.
    	;
     
    	/*suppression des blancs, remplacement de blancs successifs par un seul*/
    	adresse = left(trim(compbl(adr_lig_1)));
     
    	/*METHODE BASIQUE D'EXTRACTION DE COMPOSANTS CARACTÈRES*/
     
    	Numero=scan(adresse,1,' '); /*OK*/
    	IF find(Numero,"-")>0 then do;
    		appartement=scan(Numero,1,'-') ; /*OK*/
    		numero=compress(scan(Numero,2,'-')); /*OK*/
    	end;
     
    	 /*Extraction classique rue PAS OK veut scanner la suite et pas juste le mot suivant*/
    	IF find(Numero,"-")>0 then
    		rue=compress(scan(adresse,3, -1));
    	ELSE rue=compress(scan(adresse,2,-1)) ;
     
     /*UTILISATION EXPRESSION REGULIÈRE*/
     
    	/*definition des modèles*/
    	if _N_ = 1 then
    		do;
    			 modeleadresse = "/(\d+)[\s\w*\#]+/i";
    /*PAS OK ne prend pas en compte les noms composés*/
    		/*modeleadresse = "/(\d+)[\s\w*\[-|s]*\w*]+/i"; */
    			modele_adresse = prxparse(modeleadresse); 
    			modeleRueNum = "/(\d+)\w*/i";
    /* PAS OK bug si appartement prendre numéro entre - et 1er blanc*/
    			/*modeleRueNum = "/(\d+)[-]?(\d+)\w  i";*/
    			modele_RueNum = prxparse(modeleRueNum);		end;
     
    	retain  modele_adresse modele_RueNum;
     
     
    	/* modele_adresse is Rue number, nom */
    	call prxsubstr(modele_adresse, adresse, position, length);
     
    	if position ^= 0 then
    		do;
    			match = substr(adresse, position, length);
    			call prxsubstr(modele_RueNum, match, position2, length2);
     
    			if position2 ^= 0 then
    				do;
    					match2 = substr(match, position2, length2);
    					RueNum = match2;
    					Ruenom = trim(compress(substr(match, length2+1 ),','));
    				end;
    			else
    				do;
    					Ruenom = match;
    				end;
    		end;
     
    run;
    Merci.

  20. #20
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Citation:
    Par exemple pour localité de Plaisance tu vas rencontrer J0V 1S0 je crois mais aussi JOVISO avec des numéros remplacés par des lettres (et vice versa).
    Je ne pense pas que je vais rencontrer se genre de cas, le système de code postal est assez rodé et la plupart des systèmes ne permettent pas la saisie de 2 lettres consécutives, depuis que je vis ici j'ai jamais rencontrer ce cas de figure (données, ou réalité). Donc je n'ai pas à prévoir ce cas de figure.
    Bon tant mieux alors, je le disais au cas où ! Car moi je l'ai rencontré, certes sur des fichiers émanant d'administrations françaises et pas forcément au fait de la numérotation des codes postaux québecois..

    Oui la méthode de ton client est efficace grâce à la précision des codes postaux... ah si la poste française avait la (très) bonne idée de réformer les codes postaux en s'inspirant des CP canadiens et britanniques !

Discussions similaires

  1. [PEAR][HTML_QuickForm] Création de filtre avec expression régulière
    Par audran12 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 26/06/2007, 11h31
  2. pb avec expression régulière (regex)
    Par rudhf dans le forum C#
    Réponses: 12
    Dernier message: 10/05/2007, 15h20
  3. [RegEx] Contrôle avec expression régulière
    Par lodan dans le forum Langage
    Réponses: 8
    Dernier message: 23/10/2006, 19h32
  4. [RegEx] Problème avec expressions régulières.
    Par Cygnus Saint dans le forum Langage
    Réponses: 12
    Dernier message: 14/08/2006, 11h55
  5. [C#] Caractères hexadécimal avec expressions régulières
    Par shinchan dans le forum Windows Forms
    Réponses: 4
    Dernier message: 16/01/2006, 11h41

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