Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/06/2014, à 16:28

csm

Comparaison complexe de fichiers volumineux

Bonjour,

je suis à la recherche d'un moyen de comparer deux fichiers ascii d'une manière très spécifique :

J'ai un fichier que l'on nommera source, qui contient 5000+ lignes, chaque ligne une référence composée d'un nom, d'un titre, année, code.

J'ai un fichier que l'on nommera cible, qui contient 60 000+ ligne, chaque ligne une référence composée d'un nom, titre, année, code, etc.

Je cherche un outils pour me faire la liste des références ne se trouvant PAS dans le fichier cible mais se trouvant dans le fichier source. Mais j'ai besoin d'un outil "intelligent", travaillant sur une probabilité plutôt que sur une identité. En effet, les lignes de la source et de la cible peuvent différer. Exemple : ma source peut contenir "DUFFER David", ma cible "David Duffer" ; le titre peut avoir été modifié : "Résolution de problèmes algébriques" peut devenir "Résolution des problème algébriques", etc.

Je cherche un outil qui cherchant une ligne de la source dans la cible trouve cette ligne. Il y a "Duffer, résolution, problèmes, algébriques", donc 90% de chance que les lignes décrivent la même chose.

Un tel outils existe t'il ? Merci.

Hors ligne

#2 Le 01/06/2014, à 17:34

Zakhar

Re : Comparaison complexe de fichiers volumineux

A mon sens non.

Ce que tu décris serait de l'intelligence artificielle, je crains que tu ne doives faire le travail "à la main" pour qu'il soit 100% correct.

Maintenant, ce que tu peux faire, c'est faire une première passe en "case-insensitive" pour éliminer les lignes qui sont sûres de se trouver dans cible, ça devrait te réduire considérablement le fichier source aux lignes où on n'est pas sûr.

Dernière modification par Zakhar (Le 01/06/2014, à 17:34)


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#3 Le 01/06/2014, à 20:31

csm

Re : Comparaison complexe de fichiers volumineux

Je ne vois pas ça si compliqué. Je dirai que c'est une question de mot-clef et de probabilité.

1/ Prendre les principaux mots-clefs d'une ligne dans le fichier source (ex: duffer david résolution problème algébrique) - sélecteur de longueur ? Ne prendre que les mots supérieurs ou égaux à 4 lettres.
2/ Chercher s'il existe une ligne contenant tous ces mots dans le fichier cible
  2.1/ si elle existe, ne rien faire
  2.2 / si elle n'existe pas, écrire la ligne du fichier source dans un fichier.

Dernière modification par csm (Le 01/06/2014, à 20:33)

Hors ligne

#4 Le 01/06/2014, à 23:28

Zakhar

Re : Comparaison complexe de fichiers volumineux

Tu as l'algo, tu n'as qu'à le programmer donc vu que c'est "pas compliqué" ! tongue


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#5 Le 02/06/2014, à 10:18

csm

Re : Comparaison complexe de fichiers volumineux

Super l'aide... Si je pouvais le faire, je le ferai. Ne le pouvant, j'ai demandé des outils. Peut-être qu'une bonne combinaison de commandes avec les outils déjà existant (sed, awk..) pourrait faire l'affaire... Bref, je demande de l'aide et des outils, on me répond "t'as qu'à le faire"....

Hors ligne

#6 Le 02/06/2014, à 11:17

Sibe

Re : Comparaison complexe de fichiers volumineux

la commande "diff" te permet de comparer automatiquement les différences entre 2 fichiers.


Pc port1: Core i7 2.4GHz | 16 Go ram | GeForce 650m GT | SSD 256 Go + 1 To HD + 5 To en EXT | Linux Mint 17 x64 (Cinnamon)
Pc port2 (old): Core2duo 2.2GHz | 4 Go ram | GeForce 9600m GT | 500 Go HD | Xubuntu 14.04 x64 (Xfce)
Pc bur famille: Core2duo 3.2GHz | 4Go ram | GeForce 405 | 1 To HD | Debian 7 x64 (Kde)
Pc bur trav: Core i5 | 4 Go ram | GeForce 7600 GS | 250 Go HD | Debian 7 x64 (Mate)

Hors ligne

#7 Le 02/06/2014, à 14:47

csm

Re : Comparaison complexe de fichiers volumineux

Diff seul ne me paraît pas assez puissant. Il ne s'agit pas de comparer des différences entre fichiers (qui son complètement différents d'ailleurs), mais de recherche si une ligne de la cible correspond à une ligne de la source réduite à des mots clefs. Sinon, comment feriez-vous avec diff pour cette ligne ?

Source :

C12 ; Michel Patreo ; L'arrivée de l'onde du temps ; P3FJ-F45 ;

Cible :

PATREO Michel ; arrivée, onde, temps ; 1343896AN ; C12 ;

Extraire les principaux mots-clefs (4 lettres ou plus) de la source, chercher si au moins 3 / 4 / 5 de ces mots figurent sur une seule ligne de la cible. Si ils y figurent, ne rien faire, sinon écrire la ligne source dans un fichier.

Dernière modification par csm (Le 02/06/2014, à 14:49)

Hors ligne

#8 Le 02/06/2014, à 15:02

Sibe

Re : Comparaison complexe de fichiers volumineux

C'est possible mais cela demande de cumuler plusieurs commandes avec pas mal de paramètre, le mieux pour toi est d'écrire un script qui fait ça.


Pc port1: Core i7 2.4GHz | 16 Go ram | GeForce 650m GT | SSD 256 Go + 1 To HD + 5 To en EXT | Linux Mint 17 x64 (Cinnamon)
Pc port2 (old): Core2duo 2.2GHz | 4 Go ram | GeForce 9600m GT | 500 Go HD | Xubuntu 14.04 x64 (Xfce)
Pc bur famille: Core2duo 3.2GHz | 4Go ram | GeForce 405 | 1 To HD | Debian 7 x64 (Kde)
Pc bur trav: Core i5 | 4 Go ram | GeForce 7600 GS | 250 Go HD | Debian 7 x64 (Mate)

Hors ligne

#9 Le 02/06/2014, à 16:35

pingouinux

Re : Comparaison complexe de fichiers volumineux

Bonjour,
Peux-tu donner un échantillon un peu plus long des fichiers source et cible (une dizaine de lignes de chaque, dont certaines communes (selon tes critères)).

Hors ligne

#10 Le 03/06/2014, à 00:19

csm

Re : Comparaison complexe de fichiers volumineux

Merci. Voici 10 lignes du fichier cible

3140793629;MIR;00 PRI 08;The Princeton companion to mathematics [Texte imprimé]  / editor Timothy Gowers, ... ; associate editors June Barrow-Green, ... Imre Leader;Gowers, Timothy;
3140600453;MIR;00.1 GUI 93;A Guide to library service in mathematics : the non-trivial mathematics librarian / edited by Nancy D. Anderson, Lois M. Pausch;Anderson, Nancy D. (1940-);
3140023160;MIR;00.1 THO 62;Vocabularium bibliothecarii [Texte imprimé]  / compilateur... Anthony Thompson, ... ; coopérateur pour le russe... E. I. Shamurin... ; coopérateur pour l'espagnol... Domingo Buonocore;Thompson, Anthony (1911-1979);
3140890762;MIR;00.2 ALL 09;Langenscheidt Groβes Taschenwörterbuch Französisch [Texte imprimé]  : Französisch-Deutsch, Deutsch-Französisch;Klausmann-Molter, Birgit;
3140890427;MIR;00.2 ALL 09-2;Le Robert & Collins poche allemand [Texte  imprimé]  : français-allemand, allemand-français;;
3140391245;MIR;00.2 ALL 56;German-English mathematical vocabulary [Texte imprimé]  / Sheila Macintyre..., and Edith Witte... ; with a grammatical sketch by Lilias W. Brebner;Macintyre, Sheila (1910-1960);
3140000055;MIR;00.2 ALL 64-1;Sachs-Villatte Enzyklopädisches französisch-deutsches und deutsch-französisches Wörterbuch. Erster Teil Franzosisch-Deutsch / Karl Ernst August Sachs;Sachs, Karl (1829-1909);
3140876438;MIR;25 ORB 87-1 A;Orbites unipotentes et représentations. I [Texte imprimé] Groupes finis et algèbres de Hecke;;1977
3140248419;MIR;30 AMI 75;Les nombres p-adiques [Texte imprimé]  / Yvette Amice;Amice, Yvette (1936-1993);2003
3140876346;MIR;25 ORB 87-2 A;Orbites unipotentes et représentationsx. II Groupes p-adiques et réels [Texte imprimé];;1985

Et quelques lignes du fichier source :

AMICE Les nombres p-adiques - P.U.F 1975 AVN-TRA-PBS
MAHLER p-adis numbers and their functions - Cambridge 1981 (2e ed) BAS-TRA-PBS-MTV
NAGATA Local rings (rept) - Krieger AVN-MON-PBS
STEWART Galois theory - Chapman and Hall 1973 BAS-TRA-PBS-HIS-MTS

Seul l'ouvrage Les nombres p-adiques de Yvette Amice figure dans la source et dans la cible. Le script / commande, dans l'idéal, devrait donc écrire dans un fichier les 3 références manquantes de la source dans la cible.

Merci de votre aide ! Je fais ça bénévolement aussi pour une amicale de bibliothèque.

Dernière modification par csm (Le 03/06/2014, à 00:19)

Hors ligne

#11 Le 03/06/2014, à 06:50

pingouinux

Re : Comparaison complexe de fichiers volumineux

Voici le script comparaison.py, en python3.

#!/usr/bin/python3

# ./comparaison.py fichier_source fichier_cible fichier_resultat nb_mots_communs

import sys, re

source,cible,resul=sys.argv[1:4]
n_comm=int(sys.argv[4])

separ=re.compile("[][)(;,'\"\s]+")
# On ne garde qu'un exemplaire des mots de longueur >= 4, convertis en minuscules
def extrac(lig,n=4) :
   return frozenset(filter(lambda x:len(x)>=n,map(lambda x:x.lower(),separ.split(lig))))

# Fichier cible modifie par la fonction extrac
with open(cible,'r') as cib : cible_modif=tuple(map(extrac,cib))

with open(source,'r') as src, open(resul,'w') as res :
   for lig in src :
 # Pour chaque ligne de source, on boucle sur les lignes de cible (arrêt à la 1ère concordance)
      lig1=extrac(lig)
      ajouter=True
      for lig2 in cible_modif :
         if len(lig1&lig2) >= n_comm : ajouter=False; break
      if ajouter : res.write(lig)

À utiliser ainsi

./comparaison.py fichier_source fichier_cible fichier_resultat nb_mots_communs

Dans ton exemple, la ligne relative à amice n'a que 3 mots communs, il ne faut donc pas demander plus.

./comparaison.py fichier_source fichier_cible fichier_resultat 3
$ cat fichier_resultat
MAHLER p-adis numbers and their functions - Cambridge 1981 (2e ed) BAS-TRA-PBS-MTV
NAGATA Local rings (rept) - Krieger AVN-MON-PBS
STEWART Galois theory - Chapman and Hall 1973 BAS-TRA-PBS-HIS-MTS

Principe de la méthode :
On ne conserve dans chaque ligne que les mots de longueur >=4 (un seul exemplaire de chaque), les caractères étant convertis en minuscules.
Les séparateurs de mots sont : ] [ ) ( ; , " espaces
On boucle sur les lignes du fichier source modifié, que l'on compare à chaque ligne du fichier cible modifié (arrêt à la première concordance).
J'ai fait un test avec un fichier source de 5500 lignes, et un fichier cible de 61000 lignes (qui ne contenait pas de lignes de sources, pour que les boucles aillent jusqu'au bout) : le résultat est obtenu en un peu moins de 3 mn 30 s.
Quelqu'un trouvera peut-être une méthode plus rapide.

Édité : Petites corrections

Dernière modification par pingouinux (Le 03/06/2014, à 12:19)

Hors ligne

#12 Le 03/06/2014, à 15:55

csm

Re : Comparaison complexe de fichiers volumineux

Merci pour ce superbe petit scrit. Je viens de faire un essai sur une petite partie du catalogue (toujours en cours de numérisation / ocrisation ...) et cela a donné de bons résultats et quelques faux-positifs.

Exemple de faux-positif (mots communs 3)
Source

ABRAMOVITZ/STEGUN Handbook of mathematical functions.

Cible

3140360944;MIR;79.8 ABR 65;Handbook of mathematical functions [Texte imprimé]  : with formulas, graphs, and mathematical tables / edited by Milton Abramowitz and Irene A. Stegun;Abramowitz, Milton (1915-1958);1987

Le fichier résultats me donnait cette référence, qui figure pourtant dans la cible.  Les deux possèdent bien au moins 3 mots communs : STEGUN Handbook mathematical functions.

Mais c'est déjà une bonne approximation. Et qu'est-ce que 4 minutes par rapport aux 4 mois qu'il faudrait pour le faire à la main...

Dernière modification par csm (Le 03/06/2014, à 15:55)

Hors ligne

#13 Le 03/06/2014, à 16:10

pingouinux

Re : Comparaison complexe de fichiers volumineux

C'est parce que ABRAMOVITZ/STEGUN est considéré comme un mot, ainsi que fonctions. (avec le point)
J'ai rajouté les séparateurs de mots "/" et ".", mais il y en aura peut-être d'autres.

#!/usr/bin/python3

# ./comparaison.py fichier_source fichier_cible fichier_resultat nb_mots_communs

import sys, re

source,cible,resul=sys.argv[1:4]
n_comm=int(sys.argv[4])

separ=re.compile("[][)(;,'\"\s\./]+")
# On ne garde qu'un exemplaire des mots de longueur >= 4, convertis en minuscules
def extrac(lig,n=4) :
   return frozenset(filter(lambda x:len(x)>=n,map(lambda x:x.lower(),separ.split(lig))))

# Fichier cible modifie par la fonction extrac
with open(cible,'r') as cib : cible_modif=tuple(map(extrac,cib))

with open(source,'r') as src, open(resul,'w') as res :
   for lig in src :
 # Pour chaque ligne de source, on boucle sur les lignes de cible (arrêt à la 1ère concordance)
      lig1=extrac(lig)
      ajouter=True
      for lig2 in cible_modif :
         if len(lig1&lig2) >= n_comm : ajouter=False; break
      if ajouter : res.write(lig)

Hors ligne

#14 Le 03/06/2014, à 19:56

Zakhar

Re : Comparaison complexe de fichiers volumineux

csm a écrit :

Super l'aide... Si je pouvais le faire, je le ferai. Ne le pouvant, j'ai demandé des outils. Peut-être qu'une bonne combinaison de commandes avec les outils déjà existant (sed, awk..) pourrait faire l'affaire... Bref, je demande de l'aide et des outils, on me répond "t'as qu'à le faire"....

Relis tes messages.

Tout est une question de forme. Il est bon aussi de faire l'exercice de se mettre à la place de ceux qui te liront.

Suppose qu'on s’adresse à toi dans une matière où tu es compétent et qu'on te dise :

1) Pourtant ce n'est pas si compliqué, on pourrait faire ci puis ça...

2) Ce n'est certainement pas compliqué pour vous qui connaissez le sujet, mais ça dépasse mes compétences. Je vois les choses comme ci et comme ça, est-ce que vous pourriez m'aider à lancer le truc.

Et dis-toi qu'est-ce que tu préférerais lire, et laquelle des deux formulations ferait que tu as envie d'aider.


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#15 Le 04/06/2014, à 08:38

miniSeb

Re : Comparaison complexe de fichiers volumineux

@pingouinux : pour exclure plus facilement les "séparateurs", tu pourrais utiliser les classes POSIX [:space:] et [:punct:]. Ca réduit la regexp, la rend plus claire et contient les caractères que tu inclus dans

pingouinux a écrit :

mais il y en aura peut-être d'autres

wink

Hors ligne

#16 Le 04/06/2014, à 09:35

pingouinux

Re : Comparaison complexe de fichiers volumineux

miniSeb a écrit :

tu pourrais utiliser les classes POSIX [:space:] et [:punct:]

Initialement je pensais que seuls espace, point-virgule, simple et double quotes devaient être pris en compte. J'ai ensuite allongé la liste.

Je viens de tester, et ne suis pas certain que [:space:] et [:punct:] puissent s'utiliser en python. On a cependant d'autres raccourcis dans les expressions régulières :
\s : Caractère "whitespace" quelconque
\S : Caractère non "whitespace" quelconque
\w : Caractère "alphaNumeric" quelconque
\W : Caractère non "alphaNumeric" quelconque

Hors ligne

#17 Le 04/06/2014, à 10:03

pires57

Re : Comparaison complexe de fichiers volumineux

travailler à la main? jamais lu une chose aussi absurde, en programmation on peut tout faire ...


Utilisateur d'Archlinux, Ubuntu et Kali Linux
Administrateur système et réseau spécialisé Linux.
LinkedIn

Hors ligne

#18 Le 04/06/2014, à 14:40

miniSeb

Re : Comparaison complexe de fichiers volumineux

Le problème de \W (en tout cas en Perl), c'est que ça matche les diacritiques alors qu'ils ne doivent pas être supprimés dans ce contexte. Je ne connais pas Python wink Je suis allé voir, il semble qu'il faille utiliser un module spécifique pour utiliser les classes POSIX. Désolé pour l'intervention inutile, du coup !

Hors ligne

#19 Le 04/06/2014, à 14:54

pingouinux

Re : Comparaison complexe de fichiers volumineux

En python, ^ et ¨ sont effectivement aussi reconnus par \W.

Hors ligne

#20 Le 04/06/2014, à 18:52

csm

Re : Comparaison complexe de fichiers volumineux

Bonjour,

merci encore pour le script. J'ai refait des tests sur une partie du catalogue, puis j'ai fait quelques vérifications manuelles sans trouver de faux positifs. Le reste du catalogue est en cours de numérisation. Je vous tiendrai informer lorsqu'il serat complet. Je pense avoir compris comment rajouter moi-même des signes qui poseraient problème.

Je vous tiens informer, merci encore smile.

Hors ligne