100 Language Processing Knock-25: Extraction de modèles

Traitement du langage 100 coups 2015 ["Chapitre 3: Expressions régulières"](http: //www.cl.ecei.tohoku) Il s'agit de l'enregistrement du 25e «modèle d'extraction» de .ac.jp / nlp100 / # ch3). Cette fois, nous aborderons le contenu légèrement déroutant de la ** perspective affirmative **. Ce n'est rien si vous le comprenez, mais est-il difficile de comprendre les mots? Vous apprendrez également ** DOTALL et les dictionnaires ordonnés **. Ce contenu est important car il entraînera des coups après le chapitre 3.

Lien de référence

Lien Remarques
025.Extraction de modèle.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:25 Copiez et collez la source de nombreuses pièces source
Apprenez les bases et les astuces des expressions canoniques Python à partir de zéro J'ai organisé ce que j'ai appris dans ce coup
Expression régulière HOWTO Expression régulière officielle Python Comment faire
re ---Opération d'expression régulière Description officielle du paquet Python re
Help:Graphique simplifié Wikipediaの代表的なマークアップのGraphique simplifié
Template:Informations de base Pays Modèle de pays Wikipedia

environnement

type version Contenu
OS Ubuntu18.04.01 LTS Il fonctionne virtuellement
pyenv 1.2.15 J'utilise pyenv car j'utilise parfois plusieurs environnements Python
Python 3.6.9 python3 sur pyenv.6.J'utilise 9
3.7 ou 3.Il n'y a aucune raison profonde de ne pas utiliser la série 8
Les packages sont gérés à l'aide de venv

Dans l'environnement ci-dessus, j'utilise les packages Python supplémentaires suivants. Installez simplement avec pip ordinaire.

type version
pandas 0.25.3

Chapitre 3: Expressions régulières

contenu de l'étude

En appliquant des expressions régulières à la description du balisage sur la page Wikipédia, diverses informations et connaissances peuvent être extraites.

Expressions régulières, JSON, Wikipedia, InfoBox, services web

Contenu frappé

Un fichier jawiki-country.json.gz qui exporte les articles Wikipédia au format suivant Il y a.

  • Une information d'article par ligne est stockée au format JSON --Dans chaque ligne, le nom de l'article est stocké dans la clé "title" et le corps de l'article est stocké dans l'objet dictionnaire avec la clé "text", et cet objet est écrit au format JSON. --Le fichier est entièrement compressé

Créez un programme qui effectue le traitement suivant.

25. Extraction du modèle

Extraire les noms de champs et les valeurs du modèle "informations de base" inclus dans l'article et les stocker sous forme d'objet dictionnaire.

Supplément problème (à propos des "informations de base")

[Modèle: pays d'information de base](https://ja.wikipedia.org/wiki/Template:%E5%9F%BA%E7%A4%8E%E6%83%85%E5%A0%B1_%E5%9B Il existe un modèle «d'informations de base» dans% BD), auquel j'ai fait référence. Les noms de champ et les valeurs de ces informations de base sont extraits avec des expressions régulières.

Extrait de la partie "informations de base" du dossier


{{Informations de base Pays\n
|Nom abrégé=Angleterre\n
|Nom du pays japonais=Royaume-Uni de Grande-Bretagne et d'Irlande du Nord\n

Omission

|Numéro de téléphone international= 44\n
|Remarque= <references />\n
}}\n

Répondre

Programme de réponse [025. Template extraction.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/03.%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7 % 8F% BE / 025.% E3% 83% 86% E3% 83% B3% E3% 83% 97% E3% 83% AC% E3% 83% BC% E3% 83% 88% E3% 81% AE% E6% 8A% BD% E5% 87% BA.ipynb)

from collections import OrderedDict
from pprint import pprint
import re

import pandas as pd

def extract_by_title(title):
    df_wiki = pd.read_json('jawiki-country.json', lines=True)
    return df_wiki[(df_wiki['title'] == title)]['text'].values[0]

wiki_body = extract_by_title('Angleterre')

basic = re.search(r'''
                    ^\{\{Informations de base.*?\n  #Terme de recherche(\Est un traitement d'échappement), Non capturé, non gourmand
                    (.*?)              #Chaîne de caractères arbitraire
                    \}\}               #Terme de recherche(\Est un traitement d'échappement)
                    $                  #Fin de chaîne
                    ''', wiki_body, re.MULTILINE+re.VERBOSE+re.DOTALL)
pprint(basic.group(1))

#Ignorer la séquence d'échappement dans la chaîne brute lorsque r est au début
#Ignorer les pauses au milieu avec des guillemets triples
# re.Ignorer les espaces et les commentaires à l'aide de l'option VERBOSE
templates = OrderedDict(re.findall(r'''
                          ^\|         # \Est-ce un traitement d'échappement, non-capture
                          (.+?)       #Cible de capture(key), Non gourmand
                          \s*         #0 ou plusieurs caractères vides
                          =           #Termes de recherche, non-capture
                          \s*         #0 ou plusieurs caractères vides
                          (.+?)       #Cible de capture(Value), Non gourmand
                          (?:         #Démarrer un groupe qui n'est pas capturé
                            (?=\n\|)  #nouvelle ligne(\n)+'|'Devant de(Une vision positive affirmative)
                          | (?=\n$)   #Ou un saut de ligne(\n)+Avant la fin(Une vision positive affirmative)
                          )           #Fin du groupe non ciblé pour la capture
                         ''', basic[0], re.MULTILINE+re.VERBOSE+re.DOTALL))
pprint(templates)

Répondre au commentaire

Extraction des "informations de base"

La première est la partie extraction des «informations de base». Je ne pouvais pas l'amener au type dictionnaire avec une seule expression régulière, donc je l'ai fait en deux étapes. ^ \ {\ {Informations de base commence par" {{Informations de base "au début de la ligne et se termine par un saut de ligne. Récupère la chaîne de caractères après le saut de ligne jusqu'à «}}». J'utilise re.DOTALL pour inclure des sauts de ligne dans le caractère générique .. Jusqu'à présent, les expressions régulières utilisaient la fonction findall, mais comme une seule place est requise, la fonction 'search' //qiita.com/FukuharaYohei/items/459f27f0d7bbba551af7#match%E3%81%A8search) est utilisé.

python


basic = re.search(r'''
                    ^\{\{Informations de base.*?\n  #Terme de recherche(\Est un traitement d'échappement), Non capturé, non gourmand
                    (.*?)              #Chaîne de caractères arbitraire
                    \}\}               #Terme de recherche(\Est un traitement d'échappement)
                    $                  #Fin de chaîne
                    ''', wiki_body, re.MULTILINE+re.VERBOSE+re.DOTALL)
pprint(basic.group(1))

La partie «informations de base» est extraite sous la forme suivante.

Résultat de l'extraction "Informations de base"


('|Nom abrégé=Angleterre\n'
 '|Nom du pays japonais=Royaume-Uni de Grande-Bretagne et d'Irlande du Nord\n'
 '|Nom officiel du pays= {{lang|en|United Kingdom of Great Britain and Northern '
 'Ireland}}<ref>Nom officiel du pays autre que l'anglais:<br/>\n'

Omission

 '|ccTLD = [[.uk]] / [[.gb]]<ref>L'utilisation est.Un nombre extrêmement faible par rapport au Royaume-Uni.</ref>\n'
 '|Numéro de téléphone international= 44\n'
 '|Remarque= <references />\n')

Nom de champ et extraction de valeur

Les noms et valeurs des champs sont extraits ici. Les résultats sont transformés en un type de dictionnaire ordonné en utilisant collections.OrderDIct (car il est difficile de lire en sortie sans ordre).

python


templates = OrderedDict(re.findall(r'''
                          ^\|         # \Est-ce un traitement d'échappement, non-capture
                          (.+?)       #Cible de capture(key), Non gourmand
                          \s*         #0 ou plusieurs caractères vides
                          =           #Termes de recherche, non-capture
                          \s*         #0 ou plusieurs caractères vides
                          (.+?)       #Cible de capture(Value), Non gourmand
                          (?:         #Démarrer un groupe qui n'est pas capturé
                            (?=\n\|)  #nouvelle ligne(\n)+'|'Devant de(Une vision positive affirmative)
                          | (?=\n$)   #Ou un saut de ligne(\n)+Avant la fin(Une vision positive affirmative)
                          )           #Fin du groupe non ciblé pour la capture
                         ''', basic.group(1), re.MULTILINE+re.VERBOSE+re.DOTALL))

[Regard affirmatif sur l'avenir](https://qiita.com/FukuharaYohei/items/459f27f0d7bbba551af7#%E5%85%88%E8%AA%AD%E3%81%BF%E5%BE%8C%E8%AA%AD % E3% 81% BF% E3% 82% A2% E3% 82% B5% E3% 83% BC% E3% 82% B7% E3% 83% A7% E3% 83% B3)

La recherche positive affirmative est une technique dans laquelle si la chaîne de caractères suivante est lue en premier et que la condition est remplie, cette partie est également mise en correspondance. Je sais que c'est difficile à comprendre parce que je l'écris. En premier lieu, cette série a les quatre suivants.

La forme suivante est utilisée comme matrice.

positif le déni
Regard vers l’avenir (?=...)
...Match si la partie continue ensuite
(?!...)
...Match si la pièce ne suit pas
Regard vers l’avenir (?<=...)
...Correspondance si la pièce est avant la position actuelle et qu'il y a correspondance
(?<!...)
...Correspondance si la pièce est avant la position actuelle et qu'il n'y a pas de correspondance

Un exemple concret est plus facile à comprendre qu'une explication détaillée.

>>> string = 'A01234 B91235 C01234'

#Affirmation affirmative d'anticipation(Positive Lookahead Assertions)
# '123'À côté de'5'Chaîne de caractères suivie de('(?=5)'Une partie est la suivante'.'Ne t'en passe pas)
>>> print(re.findall(r'..123(?=5).', string))
['B91235']

#Affirmation d'anticipation négative(Negative Lookahead Assertions)
# '123'À côté de'5'Chaîne de caractères qui ne suit pas('(?!5)'Une partie est la suivante'.'Ne t'en passe pas)
>>> print(re.findall(r'..123(?!5).', string))
['A01234', 'C01234']

#Affirmation affirmative d'anticipation(Positive Lookbehind Assertions)
# '0'Mais'123'Chaîne correspondante avant('(?<=0)'La partie de est le début'.'Maisなければ取得しない)
>>> print(re.findall(r'..(?<=0)123', string))
['A0123', 'C0123']

#Affirmation d'anticipation négative(Negative Lookbehind Assertions)
# '0'Mais'123'Chaîne sans correspondance avant('(?<!0)'La partie de est le début'.'Maisなければ取得しない)
>>> print(re.findall(r'..(?<!0)123', string))
['B9123']

Résultat de sortie (résultat de l'exécution)

Lorsque le programme est exécuté, le résultat suivant est sorti à la fin.

Résultat de sortie


OrderedDict([('Nom abrégé', 'Angleterre'),
             ('Nom du pays japonais', 'Royaume-Uni de Grande-Bretagne et d'Irlande du Nord'),
             ('Nom officiel du pays',
              '{{lang|en|United Kingdom of Great Britain and Northern '
              'Ireland}}<ref>Nom officiel du pays autre que l'anglais:<br/>\n'
              '*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn '
              'mu Thuath}}([[Gaélique écossais]])<br/>\n'
              '*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd '
              'Iwerddon}}([[Pays de Galles]])<br/>\n'
              '*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart '
              'na hÉireann}}([[irlandais]])<br/>\n'
              '*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon '
              'Glédh}}([[Cornouailles]])<br/>\n'
              '*{{lang|sco|Unitit Kinrick o Great Breetain an Northren '
              'Ireland}}([[Écossais]])<br/>\n'
              '**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin '
              'Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin '
              'Airlann}}(Ulster écossais)</ref>'),
             ('Image du drapeau', 'Flag of the United Kingdom.svg'),
             ('Image de l'emblème national',
              '[[Fichier:Royal Coat of Arms of the United '
              'Kingdom.svg|85px|Emblème national britannique]]'),
             ('Lien de l'emblème national', '([[Emblème national britannique|emblème national]])'),
             ('Slogan', '{{lang|fr|Dieu et mon droit}}<br/>([[français]]:Dieu et mes droits)'),
             ('Hymne national', '[[Sa Majesté la Reine|Protégez Sa Majesté la Reine, Dieu]]'),
             ('Image de position', 'Location_UK_EU_Europe_001.svg'),
             ('Terminologie officielle', '[[Anglais]](Enréalité)'),
             ('Capitale', '[[Londres]]'),
             ('Ville la plus grande', 'Londres'),
             ('Ancien titre de la tête', '[[Prince britannique|Reine]]'),
             ('Prénom', '[[Elizabeth II]]'),
             ('Titre de premier ministre', '[[Premier ministre britannique|premier ministre]]'),
             ('Nom du premier ministre', '[[David Cameron]]'),
             ('Classement de la zone', '76'),
             ('Taille de la zone', '1 E11'),
             ('Valeur de la zone', '244,820'),
             ('Rapport de surface d'eau', '1.3%'),
             ('Année de recensement', '2011'),
             ('Classement de la population', '22'),
             ('Taille de la population', '1 E7'),
             ('Valeur de la population',
              '63,181,775<ref>[http://esa.un.org/unpd/wpp/Excel-Data/population.htm '
              'United Nations Department of Economic and Social '
              'Affairs>Population Division>Data>Population>Total '
              'Population]</ref>'),
             ('Valeur de densité de population', '246'),
             ('Statistiques du PIB année yuan', '2012'),
             ('Source de valeur du PIB',
              '1,5478 billion<ref '
              'name="imf-statistics-gdp">[http://www.imf.org/external/pubs/ft/weo/2012/02/weodata/weorept.aspx?pr.x=70&pr.y=13&sy=2010&ey=2012&scsm=1&ssd=1&sort=country&ds=.&br=1&c=112&s=NGDP%2CNGDPD%2CPPPGDP%2CPPPPC&grp=0&a= '
              'IMF>Data and Statistics>World Economic Outlook Databases>By '
              'Countrise>United Kingdom]</ref>'),
             ('Statistiques du PIB Année MER', '2012'),
             ('Classement du PIB MER', '5'),
             ('Valeur du PIB RFG', '2433,7 milliards<ref name="imf-statistics-gdp" />'),
             ('Année statistique du PIB', '2012'),
             ('Classement du PIB', '6'),
             ('Valeur du PIB', '2316,2 milliards<ref name="imf-statistics-gdp" />'),
             ('GDP/Homme', '36,727<ref name="imf-statistics-gdp" />'),
             ('Forme fondatrice', 'Fondation du pays'),
             ('Forme établie 1',
              '[[Royaume d'Angleterre]]/[[Royaume d'Ecosse]]<br />(Les deux pays[[Droit de l'Union'
              '(1707)|1707連合法]]Jusqu'à ce que)'),
             ('Date de création 1', '[[927]]/[[843]]'),
             ('Forme établie 2', '[[Royaume de Grande-Bretagne]]Fondation du pays<br />([[Droit de l'Union(1707)|1707連合法]])'),
             ('Date d'établissement 2', '[[1707]]'),
             ('Forme établie 3',
              '[[Royaume-Uni de Grande-Bretagne et d'Irlande]]Fondation du pays<br />([[Droit de l'Union(1800)|1800連合法]])'),
             ('Date d'établissement 3', '[[1801]]'),
             ('Forme établie 4', "Nom du pays actuel "'''Royaume-Uni de Grande-Bretagne et d'Irlande du Nord'''"changer en"),
             ('Date d'établissement 4', '[[1927]]'),
             ('devise', '[[Étang Sterling|Livre britannique]](&pound;)'),
             ('Code de devise', 'GBP'),
             ('Fuseau horaire', '±0'),
             ('Heure d'été', '+1'),
             ('ISO 3166-1', 'GB / GBR'),
             ('ccTLD', '[[.uk]] / [[.gb]]<ref>L'utilisation est.Un nombre extrêmement faible par rapport au Royaume-Uni.</ref>'),
             ('Numéro de téléphone international', '44'),
             ('Remarque', '<references />')])

Recommended Posts

100 Language Processing Knock-25: Extraction de modèles
100 Language Processing Knock-58: Extraction de Taple
100 coups de traitement linguistique (2020): 28
100 coups de traitement linguistique (2020): 38
100 traitement de la langue frapper 00 ~ 02
100 Language Processing Knock-55: extraction d'expressions uniques
100 Language Processing Knock-82 (mot de contexte): Extraction de contexte
100 traitements linguistiques Knock 2020 [00 ~ 69 réponse]
100 Language Processing Knock 2020 Chapitre 1
100 traitements linguistiques Knock 2020 [00 ~ 49 réponse]
100 Traitement du langage Knock-52: Stemming
100 Traitement du langage Knock Chapitre 1
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
100 coups de traitement du langage amateur: 09
100 coups en traitement du langage amateur: 47
Traitement 100 langues knock-53: Tokenisation
100 coups de traitement du langage amateur: 97
100 traitements linguistiques Knock 2020 [00 ~ 59 réponse]
100 coups de traitement du langage amateur: 67
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
100 traitement du langage knock-72 (en utilisant Stanford NLP): Extraction d'identité
100 coups de traitement du langage avec Python 2015
100 traitement du langage Knock-51: découpage de mots
100 traitement linguistique knock-50: coupure de phrase
100 Language Processing Knock Chapitre 1 (Python)
Traitement du langage 100 Knock-87: similitude des mots
J'ai essayé 100 traitements linguistiques Knock 2020
100 Language Processing Knock-56: analyse de co-référence
Résolution de 100 traitements linguistiques Knock 2020 (01. "Patatokukashi")
100 coups de traitement du langage amateur: Résumé
Traitement du langage 100 knocks-49: Extraction de chemins de dépendances entre nomenclature
100 Language Processing Knock 2020 Chapitre 2: Commandes UNIX
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 traitements de langage avec Python
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Language Processing Knock 2020 Chapitre 9: RNN, CNN
100 traitement du langage knock-76 (en utilisant scicit-learn): étiquetage
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
100 traitements de langage avec Python (chapitre 3)
100 Language Processing Knock: Chapitre 1 Mouvement préparatoire
100 Language Processing Knock 2020 Chapitre 6: Apprentissage automatique
100 Traitement du langage Knock Chapitre 4: Analyse morphologique
Traitement du langage 100 knock-86: affichage vectoriel Word
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
100 Language Processing Knock-28: Suppression du balisage MediaWiki
100 Traitement du langage Knock 2020 Chapitre 7: Vecteur de mots
100 Language Processing Knock 2020 Chapitre 8: Neural Net
100 traitement du langage knock-59: analyse de la formule S
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (05 ~ 09)
100 traitement du langage knock-31 (en utilisant des pandas): verbe
100 langues de traitement frappent 2020 "pour Google Colaboratory"
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 1
100 Language Processing Knock 2020 Chapitre 1: Mouvement préparatoire
100 traitement du langage knock-73 (en utilisant scikit-learn): apprentissage
100 Language Processing Knock Chapitre 1 par Python
100 Language Processing Knock 2020 Chapitre 3: Expressions régulières
100 langage traitement knock-24: Extraire la référence du fichier
100 Language Processing Knock 2015 Chapitre 4 Analyse morphologique (30-39)
100 traitement du langage knock-74 (en utilisant scicit-learn): prédiction
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 2