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

Python Discussion :

optimisation fichier long


Sujet :

Python

  1. #61
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Oui, avec la méthode rstrip() appliquée à la chaine:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dico[mot[0]] = mot[1].rstrip('\n')
    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  2. #62
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    merci tyrtamos

    Maintenant que j'ai mon fichier de cooccurrence.

    Il me reste plus qu'une chose après ça sera terminé!!!!! je vous laisserai tranquille !!!!

    Je vous explique la suite.

    j'ai une liste de mot séparé par des "\n" (on appelle le fichier d'évaluation fichierEvalution.log)
    ex :

    j'ai un fichier d'apprentissage (fichierApprentissage.log) sous ce format
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    France    Top
    Obama    Hum
    Entre France et Top, il y a un "\t".


    Le but est de charger les deux fichiers.
    Le premier le stocker dans une liste
    le second, le stocker dans un dico avec clé = Obama et valeur = Hum

    L'objectif est d'affecter des traits sémantiques à la liste du fichier "fichierEvalution.log"

    Pour cela,

    je vous explique le principe et après je vous montre le bout de code.

    Après avoir chargé les deux fichiers (l'une dans une liste et l'autre dans un dico)

    je parcours la liste d'évaluation.
    pour chaque mot MOTLISTE de la liste
    je regarde s'il est dans la matrice de cooccurrence.
    si oui
    je récupère sa liste "LISTEA" de cooccurrent avec matrice[mot]
    ensuite je parcours pour chaque mot MOTMATRICE de la matrice en récupérant pour chaque clé leur liste "LISTEB" et je fais une intersection de LISTE B & LISTE A pour récupérer le nombre de cooccurrent commun.
    si le nombre de cooccurrent commun est supérieur à max (une valeur que je défini), je met dans la liste (LISTEEQUIVALENCE) de MOTLISTE, le mot MOTMATRICE.

    ensuite je retourne la liste d'équivalence.

    Ensuite je traite la liste d'équivalence récupérant le meilleur trait sémantique en m'aidant du dico d'apprentissage.

    Je parcours LISTEQUIVALENCE
    pour chaque mot, je regarde s'il se trouve dans le dico d'apprentissage
    si oui, je récupère son trait sémantic (par ex pour Obama, le trait sémantique est Hum)
    j'incrémente le trait Hum de 1

    et à la fin je retourne le trait "TRAITAFFECTE" qui est apparu le plus de fois dans la liste d'équivalence

    puis j'assigne à MOTLISTE le trait TRAITAFFECTE dans le fichier

    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
     
    def evaluation(matrice,fichier,random,unknown,nbCooccurrent):
        count = listeTrait() # je récupére la liste des traits sémantique stocké dans un dico, il y en 5
        # les deux lignes suivantes récupère la liste des mots qui se trouve dans les deux fichiers expliqués ci dessus    
        lexiqueApprentissage = treatLexiqueApprentissage()
        listeDeMot = treatEvaluationFile(fichier)
        fichierResultat = open("newLexique1.log","w")
        i=0
        #pour chaque mot de la liste d'évaluation
        for mot in listeDeMot:
            i += 1
            if i % 1000 == 0: print i
            if (random == False): #laisser tomber le random, ça marche très vite, le pb n'est pas là
                #on teste si le mot est dans le corpus à l'aide de matrice.has_key(mot)
                if motInCorpus(mot,matrice):
                    #on recupere sa liste de meilleure cooccurrent de deuxieme ordre
    #le pb est dans la fonction treatsemantic
                    listeOfBestCooccurrent =  treatSemantic(matrice,mot,nbCooccurrent)
                    #s'il possede une liste 
                    if(len(listeOfBestCooccurrent) > 0):
                        #on recupere le meilleur de trait semantique de la liste
                        p= listeEquivalence(listeOfBestCooccurrent,lexiqueApprentissage)
                        #on incremente le trait recupere 
                        count[p[0][0]] += 1
                        fichierResultat.write (mot + "\t" + p[0][0] + "\n")
                    else:
                        #s'il n'a pas de liste, on recupere le mot le plus frequent
                        fichierResultat.write (mot + "\t" + maxTrait(count) + "\n")
                else:
                    #si le mot n'est pas dans le corpus, on a le choix de le stocker ou de l'ignorer
                    if (unknown == False):
                        #on ignore pas et on ecrit dans le fichier le mot avec comme le trait le plus frequent
                        fichierResultat.write (mot + "\t" + maxTrait(count) + "\n")
            else:
                #on affecte les traits au mots aleatoirement
                trait = randomSemantic()
                if motInCorpus(mot,matrice):
                    count[trait] += 1
                    fichierResultat.write(mot + "\t" + trait + "\n")
                else:
                    if (unknown == False):
                        fichierResultat.write(mot + "\t" + maxTrait(count)+"\n")
        fichierResultat.close()
    la fonction qui pose problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    def treatSemantic(matrice,mot,max):
        listeequivalence = []
        listeA = matrice[mot]
        for word,listeCooccurrent in matrice.items():
            if (word <> mot):
                if len(set(listeCooccurrent)&set(listeA)) >= max:
                    listeequivalence.append(word)
        return listeequivalence
    en gros le pb c'est que ça met à peu près 7 min pour terminer.

    je me demande si c normal.

    car là, on est obligé de comparer la liste des mots avec tous les autres de la matrice.

    et comme j'ai augmenté le nombre de mot qui était à 44000 à 88000.

    je me demande si c normal ?

    si ça l'est, c bon alors !!!!

  3. #63
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut ekremyilmaz
    Je suis en train de travailler sur une autre solution.
    Celle de dividee est ébouriffante de maîtrise, elle m'a laissé baba, mais elle a quelques défauts à mon avis. Je reviens dans 2 heures environ.

  4. #64
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    moi aussi, je suis resté scotché !!!
    maintenant j'essai d'optimiser l'autre problème que j'ai énoncé dans mon post précédent

  5. #65
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    L'utilisation du type ensemble (set) est une bonne idée; une optimisation simple serait de stocker dans la matrice directement l'ensemble (set) des cooccurents au lieu d'une liste de cooccurents; cela éviterait de devoir les convertir en set dans la boucle intérieure; qui deviendrait (en renommant les variables pour que ce soit cohérent):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if len(setCooccurrent & setA) >= max:
                    listeequivalence.append(word)
    Mais algorithmiquement on peut sans doute faire mieux, pour éviter d'avoir à parcourir toute la matrice. Une idée comme ça: Du fait de la symétrie de la relation de cooccurrence, tu devrais pouvoir ne considérer que les lignes de la matrice qui sont des cooccurrents des mots dans listeA. Cela donnerait (en incluant l'optimisation ci-dessus pour l'utilisation des ensemble):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def treatSemantic(matrice,mot,max):
        listeequivalence = []
        setA = matrice[mot]
        candidats = set(coocc for word in setA for coocc in matrice[word])
        # ou bien:
        # candidats = reduce(operator.or_, (matrice[word] for word in setA))
        candidats.discard(mot)
        for word in candidats:
            if len(matrix[word] & setA) >= max:
                listeequivalence.append(word)
        return listeequivalence
    Je n'ai pas testé alors il y a peut-être une erreur, mais l'idée est là.
    Je n'ai pas regardé le reste du code, mais en fonction de ce que tu en fais ensuite, listeequivalence pourrait peut-être aussi devenir setequivalence ?

  6. #66
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    On est obligé de parcourir tous les mots de la matrice.

    je vais t'expliquer pourquoi :

    imagine
    dans la matrice :
    on a
    <institueur>école#enfants#collège</instituteur>
    <professeur>université#école#mathématique</professeur>
    <foot>ballon#argent</foot>


    maintenant dans la liste des mots du fichier d'évaluation.

    on doit affecter un trait sémantique à professeur.
    pour cela, je regarde si professeur est dans la matrice.

    elle y est.
    donc je récupère sa liste université#école#mathématique
    ensuite je parcours tous les mots de la matrice

    donc il y a le mot institueur, on récupère sa liste école#enfants#collège

    et on fait une intersection, et on obtient nombre de cooccurent = 1 (enfants)
    1>max ==> donc on ajoute à la liste d'équivalence le mot instituteur

    ensuite on a le mot foot, on récupère sa liste ballon#argent
    on fait une intersection, nombre de cooccurent == 0
    donc on fait rien

    ton algo fait ça ?

  7. #67
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    j'ai lancé l'algo,
    en 3s

    mais le résultat statistique que j'ai fait, j'obtiens pas totalement les memes résultats, mais ce n'est pas loin.


    c'est pourquoi j'aimerai juste que tu m'explique ces lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    candidats = set(coocc for word in setA for coocc in matrice[word])
     # ou bien:
     # candidats = reduce(operator.or_, (matrice[word] for word in setA))
     candidats.discard(mot)
    merci

  8. #68
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par ekremyilmaz Voir le message
    ton algo fait ça ?
    Normalement oui; si la matrice est complète elle doit aussi contenir une entrée:

    <école>professeur##instituteur##...</école>

    Mon algo va rechercher cette entrée (ainsi que celles de "université" et "mathématique") et limite la recherche à ces mots-là.

    Je craignais un peu en effet que le résultat ne soit pas parfaitement identique; c'est je pense à cause du filtrage qui est fait sur la relation de cooccurrence (et plus spécifiquement, sans doute le fait de se limiter aux 'm' meilleurs résultats), qui fait que la matrice n'est pas parfaitement symétrique. Si tu augmentes la valeur de 'm', tu devrais voir le résultat de cet algo se rapprocher du tien, si je ne me trompe pas.
    Pour que ce soit parfaitement identique, il faudrait peut-être ne pas limiter le nombre de résultats, mais il faut voir si ça reste gérable au niveau mémoire et temps de calcul.

    [edit:] En fait, si tu veux quand-même filtrer un peu, au lieu de limiter le nombre de résultat à un constante 'm', tu pourrais filtrer sur la valeur de dice, par exemple dice > 0,0001 (valeur optimale à déterminer). Comme la valeur de dice est symétrique, la matrice produite devrait toujours rester symétrique.

  9. #69
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     candidats = set(coocc for word in setA for coocc in matrice[word])
     # ou bien:
     # candidats = reduce(operator.or_, (matrice[word] for word in setA))
     candidats.discard(mot)
    La première ligne va rechercher les cooccurrents des mots de setA, et construit l'union de ces ensembles (plutôt que de les stocker dans une liste, afin d'éliminer les doublons). Encore une autre façon de l'écrire serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    candidats = set()
    for word in setA:
        candidats |= matrice[word]
    Le discard c'est pour éliminer 'mot', afin d'éviter le test (if word <> mot) dans la boucle qui suit.

  10. #70
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    t un génie !!! y a rien à dire !!!

    j'ai augmenté le m à 30.

    j'ai testé les résultats, j'atteint 68% de bon résultats. (en plus l'algo tourne en moins de 30s)

    je m'explique, j'ai un lexique d'évaluation avec les mots et leur traits déjà défini.

    ce que je fais, c juste récupérer les mots et leur affecter un trait.

    et après je compare mon nouveau lexique avec le lexique d'origine pour voir le taux de réussite.

    et j'ai atteint 68% !!!, c super, la valeur max qui se trouve dans treatsemantic(), je l'ai mise à 7, qui est pas mal du tout.


    pour info, le random que j'utilise, c'est juste un paramètre qui dit au pg, d'affecter d'aléatoirement un trait à tous les mots de la liste !!!

    merci pour tout franchement !!!!!, là c'est vraiment géniale !!!!

    là, je suis vraiment satisfait, maintenant, il me reste plus qu'à améliorer mon programme de stat en prenant en compte les mots simples et composés et là ça sera le top !!!!

    dire que c'est à rendre pour demain soir !!!, la semaine dernière, j'ai bloqué pendant 1 semaine, et je me suis dit, va demander de l'aide au forum python !!!! et j'ai bien fait

  11. #71
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    68% c'est bien ? Enfin, tu es le seul à pouvoir en juger...

    Je suis content d'avoir pu aider, et c'est intéressant comme domaine d'application.

  12. #72
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    c pas mal du tout 68% !!!!!!

    c'est vrai c'est un domaine intéressant: la linguistique

    je t'envoie le lien du projet, actuellement le serveur est en panne, demain tu pourra le voir je pense

    http://igm.univ-mlv.fr/ens/Master/M2...AL/project.php

    merci pour tous !!

  13. #73
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut Voilà
    J'ai l'impression que le peloton est loin devant mais ça ne fait rien je me suis bien amusé à trouver ce qui suit.

    -------------------------------------------

    ekremyilmaz, tu as expliqué dans le message #44, en réponse à ma question sur la provenance du fichier mat1, qu'il y a la succession suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
          2 fichiers texte avec des délimiteurs {S}
    ---> dico1 = {1:{A,B,C,D,E};2{A,C,D,E};3{B,D,E}}
    ---> dico2 = {A:{1,2};B:{1,3};C:{1,2};D:{1,2,3};E:{1,2,3}}
    ---> fichier mat1 qui est:
           <A>1##2</A>
           <B>1##3</B>
           <C>1##2</C>
           <D>1##2##3</D>
           <E>1##2##3</E>
    Comme dividee a proposé une solution qui utilise dico1, j'ai d'abord pensé que c'était pour exploiter le fait que dico1, qui contient une information différente de dico2, existe obligatoirement comme passage obligé puiqu'il découle directement du traitement des 2 fichiers texte de départ, et qu'il était dommage de ne pas utiliser cette information, et que c'est ce qu'il avait fait avec le programme très malin qu'il a proposé.

    Avec les données dont on dispose, c'est à dire le fichier mat1, il a proposé le schéma de programme suivant, qui repose sur la création d'un troisième dico à partir des deux précédents exploités conjointement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ---> fichier mat1 qui est:
           <A>1##2</A>
           <B>1##3</B>
           <C>1##2</C>
           <D>1##2##3</D>
           <E>1##2##3</E>
    ---> dico2 = {A:{1,2};B:{1,3};C:{1,2};D:{1,2,3};E:{1,2,3}}
    ---> dico1 = {1:{A,B,C,D,E};2{A,C,D,E};3{B,D,E}}
    ---> dico 3 = {A:{B:1,C:2,D:2,E:2} , B:{A:1,C:1,D:2,E:2} , C:{A:2,B:1,D:2,E:2} , D:{A:2,B:2,C:2,E:3} , E:{A:2,B:2,C:2,D:3} }
    ---> traitement pour trouver les co-occurents les plus fréquents
    Bien sûr, comme tu disposes des fichiers de départ, ekremyilmaz, dividee doit penser que tu utiliseras en réalité le schéma suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          2 fichiers texte avec des délimiteurs {S}
    ---> dico1 = {1:{A,B,C,D,E};2{A,C,D,E};3{B,D,E}}
    ---> dico2 = {A:{1,2};B:{1,3};C:{1,2};D:{1,2,3};E:{1,2,3}}
    ---> dico 3 = {A:{B:1,C:2,D:2,E:2} , B:{A:1,C:1,D:2,E:2} , C:{A:2,B:1,etc} ,etc }
    ---> traitement pour trouver les co-occurents les plus fréquents

    J'ai mis un sacré bout de temps avant de bien comprendre le code de dividee et j'en suis resté baba.
    Mais j'ai fini par sentir que quelque chose n'allait pas.

    D'abord il y a des calculs qui se répètent puisqu'on trouve le dice(3,7)==9 par exemple à la fois dans l'item mot3:{mot7:9,..} et dans l'item mot7:{mot3:9,....} de dico3.
    Ensuite, au niveau algorithmique, je trouve peu satisfaisant de créer un dico2 à partir de dico 1, c'est à dire de réorganiser l'information, puis de devoir encore créer un dico3 et pour cela par dessus le marché en recourant à nouveau à dico1, c'est à dire en quelque sorte en remontant à l'information première.

    Je me suis dit qu'il devait être possible de créer une variable dans laquelle il y aurait à la fois l'information de dico 1 et celle de dico 2 sans avoir à descendre jusqu'à dico2 en perdant l'organisation de l'information de dico1.

    J'ai trouvé qu'à partir de dico1 il vaut mieux rassembler les numéros de phrases par couples de mots que par mot solitaire ---> d'où création d'un seul dictionnaire dicoBINX (pour BINôme:X) au lieu de dico2 et dico3:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dicoBINX = { (A,B):1 , (A,C):1 , (A,D):2 , (A,E):2 , (B,C):1, (B,D):2 , (B,E):2 , (C,D):2 , (C,E):2 , (D,E):3 }
    Du point de vue mémoire, dicoBINX prend moins de place (10 variables)
    que dico3 (45 variables dans l'exemple)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dico3 = {A:{B:1,C:2,D:2,E:2} , B:{A:1,C:1,D:2,E:2} , C:{A:2,B:1,D:2,E:2} , D:{A:2,B:2,C:2,E:3} , E:{A:2,B:2,C:2,D:3} }
    puisque le dicoBINX évite les répétitions.

    Ensuite on passe de dicoBINX à liBINX pour profiter de l'agilité des listes dans les calculs suivants. Nota bene: les binômes dans dicoBINX et les sous-listesl dans liBINX sont ordonnées.

    ---

    Comme je ne dispose aussi que de mat1, je suis obligé de faire comme dividee pour tester mes programmes: recréer dico1 à partir de mat1.
    Mais pour toi le véritable programme est celui ci dessous, qui n'a besoin que d'une chose, c'est qu'on lui fournisse dico1, soit sous forme de fichier, soit dans la foulée du traitement des 2 fichiers avec {S} de départ quand ce programme prend la main. Et il n'y a pas besoin de traiter mat1.

    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
    from collections import defaultdict
    from operator import itemgetter
     
    dico1 = open('dico1')
    f1 = open("matricecooccurrenceTest","w") 
    m = 3
    dicoBINX = defaultdict(int)
    N = defaultdict(int)
     
    for words in dico1.values():
        for mot in words:
            N[mot]+=1
            for autre_mot in words:
                if autre_mot>mot:
                    dicoBINX[(mot,autre_mot)] += 1
     
    liBINX = list(dicoBINX.iteritems()) # c'est une liste de doublets ( (A,B) , 6 )
     
    for mot in N.keys():
        coocs_dice = [ (binome[binome[0]==mot],2.0*float(x)/float(N[binome[0]]+N[binome[1]])) for binome,x in liBINX if mot in binome ]
        coocs_dice.sort(key=itemgetter(1),reverse=True)
        # coocs_dice est alors une liste de doublets (co-occurent de mot,valueDice)
     
        frequcoocs = [ cd[0] for cd in coocs_dice[0:m] ]
        if frequcoocs==[]:    frequcoocs = ['---']
        # frequcoocs est la liste des m co-occurents les plus frequents de 'mot'
        print '\n<',mot,'> ',
        for f in frequcoocs:  print f,', ',
        f1.writelines('<' + mot + '>' + '##'.join(frequcoocs) + '</'+mot+'>\n')
     
    f1.close()

  14. #74
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Est-ce que l'un de vous deux, dividee ou ekremyilmaz pourrait satisfaire ma curiosité en faisant tourner mes deux codes, svp ?

    J'ai téléchargé le fichier mat1 de 64 Mo mais je ne peux pas l'exploiter parce qu'il est dans un format word non reconnu par les programmes Python et je ne sais pas changer son type.

    Je suis curieux de savoir ce que donnent mes deux codes, celui du message #51 et celui du message précédent #73.
    Ils tournent correctement, je les ai testés sur un mini fichier, mais ce sont les temps d'exécution qui m'intéressent.
    Je pense que du fait qu'il ne calculent pas deux fois un même dice, ils tournent plus vite que celui de dividee. Le dernier, du message #73, doit normalement tourner encore plus vite. J'aimerais vérifier s'il en est bien ainsi.

    Attention à m:
    il est fixé à 20 dans le premier code(51) et à 3 dans le second73). Ce n'est pas ça qui va influerr beaucoup sur la vitesse , mais il faut fixer le même m pour les comparaisons.

  15. #75
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    je le teste cette après midi eyquem !!!!!, j'enverrai un post

    merci !!!!!

  16. #76
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    j'ai pas compris le

    'dico1' c'est un fichier ou un dico car après tu itéres sur dico1 ?

  17. #77
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    La ligne # dico1 = open('dico1') est une ligne-noeud au mouchoir.
    J'ai mis cette instruction batarde avec un # devant pour rappeler qu'il faut fournir dico1 comme donnée de départ pour que la suite puisse être effectuée.

    -- Explication:

    Tu as expliqué dans le message #44 (j'ai simplement rajouté un 1 et un 2 pour nommer les dicos tels qu'on les appelle depuis le message #46 de dividee):
    Au départ, J'ai deux fichiers qui me sont fournis, ce sont des corpus de texte avec {S} qui est un délimiteur de phrase.
    Je traite ces deux fichiers en mêmes temps. je récupère pour chaque phrase les mots simples (qui se trouve dans un fichier) et les mots composés (qui se trouve dans l'autre fichier)
    à la fin j'obtiens un dico
    qui ressemble à ça :

    dico1 = {1:{A,B,C,D,E};2{A,C,D,E};3{B,D,E}} : ça signifie
    que la phrase 1 contient la liste des mots A,B,C,D,E et ainsi de suite.
    Ensuite je parcours ce dico pour stocker pour chaque mot la liste des phrases où il apparait.

    donc j'obtiens le dico suivant :
    dico2 = {A:{1,2};B:{1,3};C:{1,2};D:{1,2,3};E:{1,2,3}}
    Donc première possibilité:
    dico1 résulte du programme CREATION DE DICO1 qui te permet de faire ce que tu décris ci-dessus (programme que nous n'avons pas vu), et alors il suffit d'ajouter mon code à la suite du code de CREATION DE DICO1, sans avoir à écrire une instruction du genre open(dico1).

    Deuxième possibilité:
    tu travailles toujours sur les mêmes corpus de texte avec {S} et tu as stocké les données de dico1 dans un fichier; dans ce cas au lieu de refaire tourner CREATION DE DICO1, tu vas chercher les données de dico1 dans le fichier.
    Par exemple, si on crée un fichier 'dico1' avec ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        f = open('dico1','w')
        f.write('1'+'#'+'A'+'#'+'B'+'#'+'C'+'#'+'D'+'#'+'E'+'\n')
        f.write('2'+'#'+'A'+'#'+'C'+'#'+'D'+'#'+'E''\n')
        f.write('3'+'#'+'B'+'#'+'D'+'#'+'E''\n')
        f.close()
    alors il faut mettre le code suivant à la place de l'instruction # dico1 = open('dico1') :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        dico1 = {}
        f = open('dico1','r')
        rd = f.readline()[:-1]
        while rd:
            li = rd.split('#')
            cle = int(li[0])
            val = tuple(li[1:])
            dico1[cle] = val
            rd = f.readline()[:-1]
        f.close()
        print 'dico1 =',dico1
    Les [:-1] sont pour enlever les '\n' en bout de ligne lue.


    ============================


    Remarque:
    je me suis aperçu d'une petite erreur d'écriture dans mon message #73, qui ne porte pas à conséquence puisque elle n'est pas dans du code.

    Dans
    dico2 = {A:{1,2};B:{1,3};C:{1,2};D:{1,2,3};E:{1,2,3}}
    dico1 = {1:{A,B,C,D,E};2{A,C,D,E};3{B,D,E}}
    j'ai écrit les valeurs avec des symboles { } alors qu'elles ne sont pas des dictionnaires.
    C'est seulement les valeurs de
    dico 3 = {A:{B:1,C:2,D:2,E:2} , B:{A:1,C:1,D:2,E:2} , C:{A:2,B:1,D:2,E:2} , D:{A:2,B:2,C:2,E:3} , E:{A:2,B:2,C:2,D:3} }
    qui sont des dictionnaires.

    En réalité, quand je teste des codes, je ne fais ni la première possibilité (je n'ai pas les fichiers de départ avec {S} ), ni la deuxième (je n'ai pas enregistré dico1) pour obtenir dico1; en tête de mes programmes, je mets le début du code de dividee dans son message #47, à savoir

    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
    import re
     
    motif = re.compile(r"</|>|<|#+")
     
    f = file('mat1')
    dico2 = {}
    for line in f:
        l = motif.split(line)
        dico2[l[1]] = map(int,l[2:-2])
    f.close()
    print 'dico2 =',dico2
     
    dicoun = defaultdict(list)
    for mot, phrases in dico2.iteritems():
        for phrase in phrases:
            dicoun[phrase].append(mot)
    # dicoun = { 1:[A,B,C,D,E] , 2:[A,C,D,E] , 3:[B,D,E] }
    print '\ndicoun =',dicoun
     
    dico1 = {}
    for k,v in dicoun.iteritems():
        dico1[k] = tuple(v)
    # dicoun = { 1:(A,B,C,D,E) , 2:(A,C,D,E) , 3:(B,D,E) }
    print '\ndico1 =',dico1

    J'ai simp[lement ajouté la fin
    for k,v in dicoun.iteritems():
    dico1[k] = tuple(v)
    pour obtenir dico1 avec des clés qui sont des tuples parce que les tuples sont mieux quand le programme tournera pour un gros fichier comme le tien: les tuples prennent moins de place en mémoire.

    =======
    Rappel:

    mon code n'a besoin que de dico1 comme données de départ pour tourner.
    Il crée un dictionnaire dicoBINX transformé en liste liBINX avant le traitement qui calcule les dices et les co-occurents de chaque mot.

    Le programme de dividee implique la création d'un autre fichier dico2 à partir de dico1 (en fait il fait l'inverse puisqu'il n'a pas dico1 comme donnée de départ, il remonte de dico2 obtenu à partir de mat1) puis encore d'un fichier 3 qui doit être grosso modo d'une taille double de dicoBINX.

    Voilà cette fois, je crois que c'est complet comme explications.

  18. #78
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut décorticage de mon code
    Pendant que j'y suis , j'explique rapidement mon code

    ======================

    On part de:
    dico1 = { 1 : (A,B,C,D,E) ; 2 : (A,C,D,E) ; 3 : (B,D,E) }
    On crée
    dicoBINX = { (A,B):1 , (A,C):1 , (A,D):2 , (A,E):2 , (B,C):1, (B,D):2 , (B,E):2 , (C,D):2 , (C,E):2 , (D,E):3 }
    et
    N = { A:2 , B:2 , C:2 , D:3 , E:3 }
    On peut remarque que dicoBINX n'est pas redondant en information et qu'il est moins lourd que
    dico 3 = {A:{B:1,C:2,D:2,E:2} , B:{A:1,,C:1,D:2,E:2} , C:{A:2,B:1,D:2,E:2} , D:{A:2,B:2,C:2,E:3} , E:{A:2,B:2,C:2,D:3} }
    Les tuples (A,B) (A,C) (A,D) (A,E) (B,C) (B,D) (B,E) (C,D) (C,E) (D,E)
    listent tous les couples possibles à partir de ABCDE sans tenir compte de l'ordre des deux mots, c'est à dire qu'il n'y a pas (B,A) (C,A) (C,B) etc.
    Ça résulte directement de la symétrie des dices: dice(A,E) == dice(E,A) qui vient du fait que le nombre de co-occurences de E avec A est le même que le nombre de co-oocurences de A avec E. Il suffit donc de référencer une seule fois la valeur X commune à un couple (A,B) etc. Il résulte que les tuples sont apparemment ordonnés, mais cet ordonnancement ne sert à rien en lui même, il résulte simplement de l'instruction if autre_mot>mot: dans le code qui permet d'éviter le décompte dicoBINX[(mot,autre_mot)] += 1 de co-occurences déjà vues. On ne décompte la co-occurence (A,E) qu'une fois, celle de E avec A, et pas celle de A avec E en quelque sorte. C'est pour ça que les entiers en valeurs du dictionnaire dicoBINX sont des valeurs X telles que tu as défini X.

    On change dicoBINX en
    liBINX = { ((A,B),1) , ((A,C),1) , ((A,D),2) , ((A,E),2) , ((B,C),1), ((B,D),2) , ((B,E),2) , ((C,D),2) , ((C,E),2) , ((D,E),3) }
    Ensuite, prenons le mot C par exemple, on calcule la liste coocs_dice pour C de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    coocs_dice = [ [b[b[0]==mot],2.0*float(x)/float(N[b[0]]+N[b[1]])] for b,x in liBINX if C in b ]
    Les variables b et x prennent successivement les valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    b = (A,C)   x=1
    b = (B,C)   x=1
    b = (C,D)   x=2
    b = (C,E)   x=2
    parce que le mot C est présent dans toutes les valeurs de b. Mais il est soit en première position, soit en deuxième position à cause de l'ordre au sein de chaque tuple.

    Pour b = (A,C) on a b[0]==C qui vaut False c'est à dire 0 en langage Python. C n'est donc pas en position 0 et c'est donc la valeur à cette position qui doit être prélevée:
    b[b[0]==mot] est b[0] c'est à dire A
    On enregistre alors dans coocs la liste [A,0.5] car x==1 , N[A]==2 , N[C]==2

    Puis ça passe à b = (B,C): idem ---> enregistre [B,0.5]

    Ensuite b = (C,D) x=2
    b[0]==C vaut True c'est à dire 1 , C est en première position, il faut donc prendre le mot à la deuxième position, qui est justement désignée par b[0]==C
    D'où enregistrement de [D,0.4]

    Puis b = (C,E) x=2 ---> enregistrement de [E,0.4]

    Finalement coocs pour le mot C est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    coocs == [ [A,0.5] , [B,0.5] , [D,0.4] , [E,0.4] ]
    Ensuite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    coocs_dice.sort(key=itemgetter(1),reverse=True)
    frequcoocs = [ cd[0] for cd in coocs_dice[0:m] ]
    conduisent à
    frequcoocs = [ A, B, D ] si m=3
    '##'.join(frequcoocs) vaut 'A##B##D'
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f1.writelines('<' + mot + '>' + '##'.join(frequcoocs) + '</'+mot+'>\n')
    enregistre
    '<C>'A##B##D</C>
    Ça itère ensuite sur les mots suivants D et E.


    Et hop !


    PS
    Je n'ai pas compris grand chose au problème supplémentaire décrit dans ton message #62.
    Si ton rapport est à remettre ce soir, ce n'est sans doute pas la peine que je cherche à m'y mettre.

  19. #79
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut Il ne faut pas oublier le conseil de kedare
    Pour accélérer l'exécution, il faudra faire appel à Psyco, quand tu auras le temps. Ça ne doit pas être essentiel pour le moment. J'ai commencé à regarder ce module mais de façon embryonnaire.

  20. #80
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Points : 117
    Points
    117
    Par défaut
    j'ai pas trop le temps de tester mon pg, j'essaierai en fin de soirée, je dois absolument finir et faire le rapport.

    mais ton code m'a l'air vraiment clean.
    je verrai ce soir, pour le moment j'ai repris le code de dividee.


    merci encore eyquem !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. importer fichier long
    Par mizou00 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 13/08/2010, 08h15
  2. Impossible de transferer des fichiers long
    Par feldene dans le forum Langage
    Réponses: 4
    Dernier message: 24/03/2010, 17h38
  3. Copier les fichiers long Win98/ME
    Par compdev dans le forum Windows 2000/Me/98/95
    Réponses: 1
    Dernier message: 11/09/2009, 21h50
  4. nom de fichier long
    Par karim_usthb dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 02/06/2008, 11h50
  5. [Win XP] Optimisation (fichier de "swap" et RAM)
    Par BiM dans le forum Windows XP
    Réponses: 11
    Dernier message: 05/04/2006, 12h13

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