Je ne suis pas sûr de la façon dont cela devrait être appelé, alors corrigez-moi si vous connaissez un meilleur terme.
J'ai deux listes. L'un des 55 éléments (par exemple: un vecteur de chaînes), l'autre de 92. Les noms des éléments sont similaires mais non identiques.
Je souhaite trouver les meilleurs candidats de la liste dans la liste 55 92 aux articles (je puis passer par là et choisissez le montage correct).
Comment ceci peut être fait?
Les idées que j'ai eues où:
- Voir tous ceux qui correspondent (en utilisant quelque chose? Correspondance)
- Essayez une matrice de distance entre les vecteurs de chaînes, mais je ne sais pas comment la définir au mieux (nombre de lettres identiques, qu'en est-il de l'ordre des chaînes?)
Alors, quel paquet / fonctions / domaine de recherche traite d’une telle tâche et comment?
Mise à jour: Voici un exemple des vecteurs que je souhaite associer
vec55 <- c("Aeropyrum pernix", "Archaeoglobus fulgidus", "Candidatus_Korarchaeum_cryptofilum",
"Candidatus_Methanoregula_boonei_6A8", "Cenarchaeum_symbiosum",
"Desulfurococcus_kamchatkensis", "Ferroplasma acidarmanus", "Haloarcula_marismortui_ATCC_43049",
"Halobacterium sp.", "Halobacterium_salinarum_R1", "Haloferax volcanii",
"Haloquadratum_walsbyi", "Hyperthermus_butylicus", "Ignicoccus_hospitalis_KIN4",
"Metallosphaera_sedula_DSM_5348", "Methanobacterium thermautotrophicus",
"Methanobrevibacter_smithii_ATCC_35061", "Methanococcoides_burtonii_DSM_6242"
)
vec91 <- c("Acidilobus saccharovorans 345-15", "Aciduliprofundum boonei T469",
"Aeropyrum pernix K1", "Archaeoglobus fulgidus DSM 4304", "Archaeoglobus profundus DSM 5631",
"Caldivirga maquilingensis IC-167", "Candidatus Korarchaeum cryptofilum OPF8",
"Candidatus Methanoregula boonei 6A8", "Cenarchaeum symbiosum A",
"Desulfurococcus kamchatkensis 1221n", "Ferroglobus placidus DSM 10642",
"Halalkalicoccus jeotgali B3", "Haloarcula marismortui ATCC 43049",
"Halobacterium salinarum R1", "Halobacterium sp. NRC-1", "Haloferax volcanii DS2",
"Halomicrobium mukohataei DSM 12286", "Haloquadratum walsbyi DSM 16790",
"Halorhabdus utahensis DSM 12940", "Halorubrum lacusprofundi ATCC 49239",
"Haloterrigena turkmenica DSM 5511", "Hyperthermus butylicus DSM 5456",
"Ignicoccus hospitalis KIN4/I", "Ignisphaera aggregans DSM 17230",
"Metallosphaera sedula DSM 5348", "Methanobrevibacter ruminantium M1",
"Methanobrevibacter smithii ATCC 35061", "Methanocaldococcus fervens AG86",
"Methanocaldococcus infernus ME", "Methanocaldococcus jannaschii DSM 2661",
"Methanocaldococcus sp. FS406-22", "Methanocaldococcus vulcanius M7",
"Methanocella paludicola SANAE", "Methanococcoides burtonii DSM 6242",
"Methanococcus aeolicus Nankai-3", "Methanococcus maripaludis C5",
"Methanococcus maripaludis C6", "Methanococcus maripaludis C7",
"Methanococcus maripaludis S2", "Methanococcus vannielii SB",
"Methanococcus voltae A3", "Methanocorpusculum labreanum Z",
"Methanoculleus marisnigri JR1", "Methanohalobium evestigatum Z-7303",
"Methanohalophilus mahii DSM 5219", "Methanoplanus petrolearius DSM 11571",
"Methanopyrus kandleri AV19", "Methanosaeta thermophila PT",
"Methanosarcina acetivorans C2A", "Methanosarcina barkeri str. Fusaro",
"Methanosarcina mazei Go1", "Methanosphaera stadtmanae DSM 3091",
"Methanosphaerula palustris E1-9c", "Methanospirillum hungatei JF-1",
"Methanothermobacter marburgensis str. Marburg", "Methanothermobacter thermautotrophicus str. Delta H",
"Nanoarchaeum equitans Kin4-M", "Natrialba magadii ATCC 43099",
"Natronomonas pharaonis DSM 2160", "Nitrosopumilus maritimus SCM1",
"Picrophilus torridus DSM 9790", "Pyrobaculum aerophilum str. IM2",
"Pyrobaculum arsenaticum DSM 13514", "Pyrobaculum calidifontis JCM 11548",
"Pyrobaculum islandicum DSM 4184", "Pyrococcus abyssi GE5", "Pyrococcus furiosus DSM 3638",
"Pyrococcus horikoshii OT3", "Staphylothermus hellenicus DSM 12710",
"Staphylothermus marinus F1", "Sulfolobus acidocaldarius DSM 639",
"Sulfolobus islandicus L.D.8.5", "Sulfolobus islandicus L.S.2.15",
"Sulfolobus islandicus M.14.25", "Sulfolobus islandicus M.16.27",
"Sulfolobus islandicus M.16.4", "Sulfolobus islandicus Y.G.57.14",
"Sulfolobus islandicus Y.N.15.51", "Sulfolobus solfataricus P2",
"Sulfolobus tokodaii str. 7", "Thermococcus gammatolerans EJ3",
"Thermococcus kodakarensis KOD1", "Thermococcus onnurineus NA1",
"Thermococcus sibiricus MM 739", "Thermofilum pendens Hrk 5",
"Thermoplasma acidophilum DSM 1728", "Thermoplasma volcanium GSS1",
"Thermoproteus neutrophilus V24Sta", "Thermosphaera aggregans DSM 11486",
"Vulcanisaeta distributa DSM 14429", "uncultured methanogenic archaeon RC-I"
)
r
text-mining
Tal Galili
la source
la source
stringdist
paquet semble être la meilleure ressource pour ce genre de chose.Réponses:
J'ai eu des problèmes similaires. (vu ici: https://stackoverflow.com/questions/2231993/merging-two-data-frames-using-fuzzy-approximate-string-matching-in-r )
La plupart des recommandations que j'ai reçues se sont articulées autour de:
pmatch()
Etagrep()
,grep()
,grepl()
trois fonctions que si vous prenez le temps de regarder à travers vous donnera un aperçu de correspondance de chaîne approximative soit par chaîne approximative ou regex approximative.Sans voir les chaînes, il est difficile de vous donner un exemple concret de la façon de les faire correspondre. Si vous pouviez nous fournir des exemples de données, je suis sûr que nous pourrions trouver une solution.
Une autre option que j'ai trouvée fonctionne bien est d'aplatir les chaînes,
tolower()
en regardant la première lettre de chaque mot de la chaîne, puis en comparant. Parfois, cela fonctionne sans accroc. Ensuite, il y a des choses plus complexes comme les distances mentionnées dans d'autres réponses. Parfois, ces travaux, parfois ils sont horribles - cela dépend vraiment des cordes.Peut-on les voir?
Mise à jour
Il semble qu'agendp () fasse l'affaire pour la plupart d'entre eux. Notez que Agrep () est juste l'implémentation de la distance de Levenshtein par R.
Certains ne calculent pas bien, cependant, je ne suis même pas sûr si Ferroplasm acidaramus est identique à Ferroglobus placidus DSM 10642, par exemple:
Je pense que vous pouvez être un peu SOL pour certains d'entre eux et peut-être créer un index à partir de zéro est le meilleur pari. c'est à dire,. Créez une table avec des identifiants pour vec55, puis créez manuellement une référence à l'identifiant dans vec55 dans vec91. Douloureux, je sais, mais cela peut être fait en grande partie avec Agrep ().
la source
Il existe de nombreuses façons de mesurer les distances entre deux chaînes. Deux approches importantes (standard) largement mises en œuvre dans R sont la distance de Levenshtein et de Hamming. Le premier est disponible dans le paquet «MiscPsycho» et le dernier dans «e1071». En utilisant ceux-ci, je calculerais simplement une matrice 92 sur 55 de distances par paires, puis procéderais à partir de là (c'est-à-dire que la meilleure correspondance possible pour la chaîne "1" dans la liste 1 est la chaîne "x" de la liste 2 avec la plus petite distance à la chaîne "1 ").
Sinon, il y a une fonction de comparaison () dans RecordLinkage paquet qui semble être conçu pour faire ce que vous voulez et utilise le soi - disant Jaro-Winkler la distance qui semble plus approprié pour la tâche à accomplir, mais je l' ai eu aucune expérience avec elle .
EDIT: Je modifie ma réponse pour inclure le commentaire de Brandon ainsi que le code de Tal, afin de trouver une correspondance avec "Aeropyrum pernix", la première entrée de vec55 :
la source
Pour compléter la réponse utile de Kwak, permettez-moi d'ajouter quelques principes et idées simples. Un bon moyen de déterminer la métrique consiste à déterminer comment les chaînes peuvent différer de la cible. "Modifier la distance" est utile lorsque la variante est une combinaison d'erreurs typographiques telles que la transposition de voisins ou la mauvaise saisie d'une clé unique.
Une autre approche utile (avec une philosophie légèrement différente) consiste à mapper chaque chaîne en un représentant d'une classe de chaînes liées. La méthode " Soundex " fait ceci: le code Soundex pour un mot est une séquence de quatre caractères codant la consonne principale et des groupes de conséquence interne de son similaire. Il est utilisé lorsque des mots sont mal orthographiés ou des variantes phonétiques. Dans l'exemple d'application, vous récupérez tous les mots cibles dont le code Soundex est égal au code Soundex de chaque mot de sonde. (Il pourrait y avoir zéro ou plusieurs cibles récupérées de cette façon.)
la source
Je vous suggère également de consulter N-grammes et la distance Damerau – Levenshtein en plus des autres suggestions de Kwak.
Cet article compare la précision de quelques distances de montage différentes mentionnées ici (et est très cité selon Google scholar).
Comme vous pouvez le constater, il existe de nombreuses manières d’aborder ceci, et vous pouvez même combiner différentes métriques (le document que j’ai lié à des discussions à ce sujet un peu). Je pense que Levenshtein et les métriques associées ont le sens le plus intuitif, en particulier si des erreurs surviennent à cause du typage humain. Les n-grammes sont également simples et ont un sens pour des données autres que des noms ou des mots.
Bien que soundex soit une option, le peu de travail que j'ai vu (ce qui est certes une très petite quantité) soundex ne fonctionne pas aussi bien que Levenshstein ou d'autres distances d'édition pour les noms correspondants. Et le Soundex est limité aux phrases phonétiques probablement entrées par des caractères humains, où Levenshtein et N-grammes ont une portée potentiellement plus large (en particulier N-gram, mais je m'attendrais à ce que la distance de Levenshtein soit également meilleure pour les non-mots).
Je ne peux pas vous aider en ce qui concerne les paquets, mais le concept de N-grammes est assez simple (j’ai créé une macro SPSS pour faire N-grammes récemment, mais pour un si petit projet, j’aimerais simplement utiliser les paquets déjà créés dans R les autres affiches ont suggéré). Voici un exemple de calcul de la distance de Levenshtein en python.
la source
J'ai recherché des paquets et des moyens de résoudre ce problème et je pense que le meilleur candidat est le
fuzzywuzzyR
paquet.J'ai fait la solution simple pour votre problème, mais il y a un petit piège. Vous devez installer python et si vous utilisez winodows, vous devez également installer des outils de construction pour visual studio . Vous devez choisir ceux-ci:
La solution est simple La fonction principale
ExtractOne
renvoie la liste de deux valeurs. Le premier correspond à une correspondance de chaîne et le second correspond au score correspondant (compris entre 0 et 100). LefuzzywuzzyR
paquet fournit également d'autres fonctions qui peuvent être utiles. La documentation principale peut être trouvée ici . J'espère que ce code aide à résoudre le problème.Sortie:
la source
Basé sur la fonction
adist
La fonction
stringdist
d'un package du même nom a plusieurs méthodes (voir?stringdist
):Avec cela, vous pouvez sélectionner une divergence maximale (seuil):
Cette trame de données montre le premier vecteur dans la colonne premier vecteur, la meilleure correspondance du deuxième vecteur dans la correspondance de colonne, sa distance dans la divergence de colonne et toutes les correspondances significatives ordonnées dans les correspondances de colonnes triées comme dans le PO.
la source