[PYTHON] 3.6 Normalisation de texte

3.6 Normalisation de la normalisation du texte

Dans les exemples de programmes précédents, il était courant de convertir du texte en minuscules avant de faire quoi que ce soit avec un mot.

 set(w.lower()for w for text)
lower()

J'ai utilisé la commande ci-dessus pour rendre le texte plus bas *** normalisé *** afin que Le et le soient considérés comme identiques. Dans de nombreux cas, allez au-delà et supprimez le suffixe, une tâche connue sous le nom de suffixe. Une étape supplémentaire consiste à s'assurer que la forme résultante est un mot connu dans le dictionnaire. Il s'agit d'une tâche appelée *** Headwordization ***. Ceux-ci seront expliqués dans l'ordre. Tout d'abord, vous devez définir les données utilisées dans cette section.

>>> raw = """DENNIS: Listen, strange women lying in ponds distributing swords
... is no basis for a system of government.  Supreme executive power derives from
... a mandate from the masses, not from some farcical aquatic ceremony."""
>>> tokens = word_tokenize(raw)

Tiges

NLTK contient plusieurs égouts du commerce.

Stemmers est un traitement de racine de mot << Les moteurs de recherche reconnaissent le mot issu du terme de recherche et de la recherche, y compris la forme d'utilisation et la forme dérivée >>

Si vous avez besoin d'un stemmer, utilisez l'un d'eux pour avoir la priorité sur votre propre création à l'aide d'expressions régulières. Porter Stemmer et Lancaster Stemmer suivent leurs propres règles pour supprimer les verbes.

• La tige de Porter est une méthode d'élimination des terminaisons morphologiques et flexionnelles courantes des mots anglais. C'est la méthode la plus couramment utilisée et la plus simple. -Lancaster est le calcul le plus rapide, mais il peut avoir des problèmes avec les résultats.

Le Porter Stemmer gère correctement le mauvais mot, mais pas le Lancaster Stemmer.

>>> porter = nltk.PorterStemmer()
>>> lancaster = nltk.LancasterStemmer()
>>> [porter.stem(t) for t in tokens]
['denni', ':', 'listen', ',', 'strang', 'women', 'lie', 'in', 'pond',
'distribut', 'sword', 'is', 'no', 'basi', 'for', 'a', 'system', 'of', 'govern',
'.', 'suprem', 'execut', 'power', 'deriv', 'from', 'a', 'mandat', 'from',
'the', 'mass', ',', 'not', 'from', 'some', 'farcic', 'aquat', 'ceremoni', '.']
>>> [lancaster.stem(t) for t in tokens]
['den', ':', 'list', ',', 'strange', 'wom', 'lying', 'in', 'pond', 'distribut',
'sword', 'is', 'no', 'bas', 'for', 'a', 'system', 'of', 'govern', '.', 'suprem',
'execut', 'pow', 'der', 'from', 'a', 'mand', 'from', 'the', 'mass', ',', 'not',
'from', 'som', 'farc', 'aqu', 'ceremony', '.']

La tige n'est pas un processus bien défini et sélectionne généralement la meilleure tige pour l'application à laquelle vous pensez. Porter stemmer convient lorsque vous souhaitez indexer du texte et prendre en charge les recherches utilisant des formes alternatives de mots.

class IndexedText(object):

    def __init__(self, stemmer, text):
        self._text = text
        self._stemmer = stemmer
        self._index = nltk.Index((self._stem(word), i)
                                 for (i, word) in enumerate(text))

    def concordance(self, word, width=40):
        key = self._stem(word)
        wc = int(width/4)                # words of context
        for i in self._index[key]:
            lcontext = ' '.join(self._text[i-wc:i])
            rcontext = ' '.join(self._text[i:i+wc])
            ldisplay = '{:>{width}}'.format(lcontext[-width:], width=width)
            rdisplay = '{:{width}}'.format(rcontext[:width], width=width)
            print(ldisplay, rdisplay)

    def _stem(self, word):
        return self._stemmer.stem(word).lower()
>>> porter = nltk.PorterStemmer()
>>> grail = nltk.corpus.webtext.words('grail.txt')
>>> text = IndexedText(porter, grail)
>>> text.concordance('lie')
r king ! DENNIS : Listen , strange women lying in ponds distributing swords is no
 beat a very brave retreat . ROBIN : All lies ! MINSTREL : [ singing ] Bravest of
       Nay . Nay . Come . Come . You may lie here . Oh , but you are wounded !
doctors immediately ! No , no , please ! Lie down . [ clap clap ] PIGLET : Well
ere is much danger , for beyond the cave lies the Gorge of Eternal Peril , which
   you . Oh ... TIM : To the north there lies a cave -- the cave of Caerbannog --
h it and lived ! Bones of full fifty men lie strewn about its lair . So , brave k
not stop our fight ' til each one of you lies dead , and the Holy Grail returns t

Figure 3.6: Indexation de texte à l'aide de souches

Lemmatisation

Le lemmatiseur WordNet supprime le suffixe uniquement si le mot résultant est dans le dictionnaire.

WordNet est un dictionnaire de concepts anglais (dictionnaire sémantique) lemmatizer est de convertir en un mot-clé. Exemple rencontre, réunion) J'assisterai à la réunion. Après la conversion - réunion Je l'ai rencontré hier soir. Après la conversion, rendez-vous

Ce processus de vérification supplémentaire rend le lemmatiseur plus lent que les souches ci-dessus. Ne mentez pas, mais changez wom * e * n en wom * a * n.

>>> wnl = nltk.WordNetLemmatizer()
>>> [wnl.lemmatize(t) for t in tokens]
['DENNIS', ':', 'Listen', ',', 'strange', 'woman', 'lying', 'in', 'pond',
'distributing', 'sword', 'is', 'no', 'basis', 'for', 'a', 'system', 'of',
'government', '.', 'Supreme', 'executive', 'power', 'derives', 'from', 'a',
'mandate', 'from', 'the', 'mass', ',', 'not', 'from', 'some', 'farcical',
'aquatic', 'ceremony', '.']

Le lemmatiseur WordNet convient lorsque vous souhaitez modifier le vocabulaire de certains textes et avez besoin d'une liste de lemmes valides.

Un lemme est un mot sous la forme d'une entrée ou d'un dictionnaire.

3.7 Expressions régulières pour tokeniser du texte

** La tokenisation ** consiste à couper une chaîne en unités linguistiques identifiables qui constituent une partie des données linguistiques. C'est une tâche basique, mais elle pourrait être retardée jusqu'à présent car de nombreux corpus sont déjà ** tokenisés ** et NLTK inclut une certaine tokenisation. .. Étant familier avec les expressions canoniques, vous pouvez apprendre à les utiliser pour ** tokenize ** du texte et obtenir plus de contrôle sur le processus.

Un jeton est un caractère ou une chaîne de caractères qui est traité comme la plus petite unité d'une phrase lors de l'analyse d'un langage naturel.

Une approche simple de la tokenisation

Le moyen le plus simple de ** tokenize ** du texte est de le diviser avec des espaces. Considérez le texte suivant des aventures d'Alice au pays des merveilles.

>>> raw = """'When I'M a Duchess,' she said to herself, (not in a very hopeful tone
... though), 'I won't have any pepper in my kitchen AT ALL. Soup does very
... well without--Maybe it's always pepper that makes people hot-tempered,'..."""

Vous pouvez utiliser raw.split () pour diviser ce texte brut en blancs. Faire correspondre le caractère espace dans la chaîne ** [1] ** n'est pas suffisant pour faire la même chose en utilisant des expressions régulières. En effet, il générera un jeton contenant le caractère de saut de ligne \ n. Au lieu de cela, vous devez faire correspondre n'importe quel nombre d'espaces, de tabulations ou de sauts de ligne ** [2] **:

>>> re.split(r' ', raw) [1]
["'When", "I'M", 'a', "Duchess,'", 'she', 'said', 'to', 'herself,', '(not', 'in',
'a', 'very', 'hopeful', 'tone\nthough),', "'I", "won't", 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'AT', 'ALL.', 'Soup', 'does', 'very\nwell', 'without--Maybe',
"it's", 'always', 'pepper', 'that', 'makes', 'people', "hot-tempered,'..."]
>>> re.split(r'[ \t\n]+', raw) [2]
["'When", "I'M", 'a', "Duchess,'", 'she', 'said', 'to', 'herself,', '(not', 'in',
'a', 'very', 'hopeful', 'tone', 'though),', "'I", "won't", 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'AT', 'ALL.', 'Soup', 'does', 'very', 'well', 'without--Maybe',
"it's", 'always', 'pepper', 'that', 'makes', 'people', "hot-tempered,'..."]

L'expression régulière «[\ t \ n] +» correspond à un ou plusieurs espaces, tabulations (\ t) ou sauts de ligne (\ n). D'autres caractères vides tels que les retours chariot et les sauts de page doivent en fait être inclus.

Le retour chariot est un caractère de contrôle qui indique que le curseur est renvoyé au début d'une phrase dans le système de codes de caractères.

Au lieu de cela, utilisez l'abréviation intégrée \ s. Cela signifie tout caractère vide. L'instruction ci-dessus peut être réécrite comme re.split (r '\ s +', raw).

Important: n'oubliez pas de faire précéder l'expression régulière de la lettre r. Cela indique à l'interpréteur Python de traiter la chaîne comme un littéral au lieu de gérer le caractère de barre oblique inverse inclus.

La séparation avec des blancs donne des jetons tels que «(pas», «elle-même», etc.) Au lieu de cela, Python fournit une classe de caractères \ w pour les caractères de mot équivalente à [a-zA-Z0-9_]. Vous pouvez également utiliser des faits. Vous pouvez également utiliser \ W comme complément à cette classe \ W, c'est-à-dire définir tous les caractères à l'exception des lettres, des chiffres ou des traits de soulignement. Utilisez \ W dans une expression régulière simple pour utiliser le mot caractère. Vous pouvez diviser des entrées autres que.

Le soulignement signifie "_". Identique à la barre inférieure.

>>> re.split(r'\W+', raw)
['', 'When', 'I', 'M', 'a', 'Duchess', 'she', 'said', 'to', 'herself', 'not', 'in',
'a', 'very', 'hopeful', 'tone', 'though', 'I', 'won', 't', 'have', 'any', 'pepper',
'in', 'my', 'kitchen', 'AT', 'ALL', 'Soup', 'does', 'very', 'well', 'without',
'Maybe', 'it', 's', 'always', 'pepper', 'that', 'makes', 'people', 'hot', 'tempered',
'']

Notez que cela vous donnera une chaîne vide au début et à la fin. Obtenez le même jeton, mais utilisez re.findall (r '\ w +', raw), utilisez un modèle qui correspond au mot au lieu d'un espace et n'utilisez pas de chaîne vide. Maintenant que nous avons fait correspondre les mots, nous sommes en mesure d'étendre l'expression canonique pour couvrir un plus large éventail de cas. L'expression régulière «\ w + | \ S \ w *» essaie d'abord de faire correspondre une séquence de lettres de mots.

Une séquence est une série de données et de procédures organisées dans l'ordre, et une méthode de traitement qui traite les données et les procédures dans l'ordre dans lequel elles sont organisées.

Si aucune correspondance n'est trouvée, il tente de faire correspondre n'importe quel caractère non vide (\ S est le complément de \ s) suivi d'un autre caractère de mot. Autrement dit, la ponctuation est groupée par les caractères suivants (par exemple), mais les séquences de deux caractères de ponctuation ou plus sont séparées.

>>> re.findall(r'\w+|\S\w*', raw)
["'When", 'I', "'M", 'a', 'Duchess', ',', "'", 'she', 'said', 'to', 'herself', ',',
'(not', 'in', 'a', 'very', 'hopeful', 'tone', 'though', ')', ',', "'I", 'won', "'t",
'have', 'any', 'pepper', 'in', 'my', 'kitchen', 'AT', 'ALL', '.', 'Soup', 'does',
'very', 'well', 'without', '-', '-Maybe', 'it', "'s", 'always', 'pepper', 'that',
'makes', 'people', 'hot', '-tempered', ',', "'", '.', '.', '.']

Généraliser \ w + dans la formule ci-dessus pour autoriser les tirets et les apostolophies à l'intérieur des mots: «\ w + ([- '] \ w +) *». Cette expression signifie que \ w + est suivi de zéro ou plusieurs instances de [- '] \ w +. Cela correspond au tempérament chaud. Ajoutez également un modèle qui correspond au caractère entre guillemets afin qu'il reste séparé du texte que le caractère entre guillemets englobe.

>>> print(re.findall(r"\w+(?:[-']\w+)*|'|[-.(]+|\S\w*", raw))
["'", 'When', "I'M", 'a', 'Duchess', ',', "'", 'she', 'said', 'to', 'herself', ',',
'(', 'not', 'in', 'a', 'very', 'hopeful', 'tone', 'though', ')', ',', "'", 'I',
"won't", 'have', 'any', 'pepper', 'in', 'my', 'kitchen', 'AT', 'ALL', '.', 'Soup',
'does', 'very', 'well', 'without', '--', 'Maybe', "it's", 'always', 'pepper',
'that', 'makes', 'people', 'hot-tempered', ',', "'", '...']

La formule ci-dessus est «[-. (] + »Est également inclus pour marquer séparément les doubles tirets, les ellipses et les crochets ouverts. Répertorie les symboles de classe de caractères canoniques vus dans cette section de 3.4 et d'autres symboles utiles. Ça a été.

Tableau 3.4: Symboles d'expressions régulières

Symbol Function
\b Limite de mot (largeur zéro)
\d Tout nombre décimal ([0-9]Équivalent à)
\D Caractères autres que des nombres ([^ 0-9]Équivalent à)
\s Caractère vide ([\ t \ n \ r \ f \ v]Équivalent à)
\S Caractères non vides ([^ \ t \ n \ r \ f \ v]Équivalent à)
\w Tout alphanumérique ([a-zA-Z0-9_]Équivalent à)
\W Tout non alphanumérique ([^ a-zA-Z0-9_]Équivalent à)
\t Caractère de tabulation
\n Caractère de rupture

Tokenizer d'expression régulière NLTK

La fonction nltk.regexp_tokenize () est similaire à re.findall () (car elle est utilisée pour la tokenisation). Cependant, nltk.regexp_tokenize () est plus efficace pour cette tâche et évite le besoin d'une gestion spéciale des parenthèses. Pour plus de lisibilité, divisez l'expression régulière en plusieurs lignes et ajoutez un commentaire pour chaque ligne. Un "indicateur détaillé" spécial indique à Python de supprimer les espaces et les commentaires incorporés.

>>> text = 'That U.S.A. poster-print costs $12.40...'
>>> pattern = r'''(?x)     # set flag to allow verbose regexps
...     (?:[A-Z]\.)+       # abbreviations, e.g. U.S.A.
...   | \w+(?:-\w+)*       # words with optional internal hyphens
...   | \$?\d+(?:\.\d+)?%? # currency and percentages, e.g. $12.40, 82%
...   | \.\.\.             # ellipsis
...   | [][.,;"'?():-_`]   # these are separate tokens; includes ], [
... '''
>>> nltk.regexp_tokenize(text, pattern)
['That', 'U.S.A.', 'poster-print', 'costs', '$12.40', '...']

Lorsque vous utilisez l'indicateur de détail, vous ne pouvez plus utiliser "" pour faire correspondre le caractère d'espace. Utilisez plutôt \ s. La fonction regexp_tokenize () a un paramètre de lacunes optionnel. Lorsqu'elle est définie sur True, l'expression régulière spécifie l'écart entre les jetons, similaire à re.split ().

Autres problèmes de tokenisation

La tokenisation s'est avérée être une tâche beaucoup plus difficile que prévu. Il n'y a pas de solution unique qui fonctionne parfaitement bien, donc en fonction de votre domaine d'application, vous devez décider de ce que vous comptez comme des jetons.

Lors du développement d'un tokenizer, il est utile d'avoir accès au texte brut tokenisé manuellement pour comparer la sortie du tokenizer avec des tokens de haute qualité (ou "gold standard"). La collection NLTK Corpus contient des échantillons de données de Penn Treebank, y compris du texte brut du Wall Street Journal (nltk.corpus.treebank_raw.raw ()) et des versions tokenisées (nltk.corpus.treebank.words ()). Je vais.

Le dernier problème de la tokenisation est la présence de contractions. Si vous analysez la signification d'une déclaration, il est probablement plus pratique de normaliser ce formulaire en deux formes distinctes: fait et non (ou non). Vous pouvez le faire avec une table de recherche.

Une table de recherche est constituée de données telles qu'un tableau ou un tableau associatif qui fait du processus de calcul un processus de référence de tableau. Par exemple, si vous sélectionnez un élément dans une base de données et que vous souhaitez récupérer les données correspondant à cet élément, enregistrez au préalable les données correspondant à l'élément en tant que table de recherche, puis reportez-vous à la valeur correspondant à l'élément dans la table de recherche. En conséquence, les données correspondant à l'article peuvent être demandées. Puisqu'il n'est pas nécessaire d'effectuer le calcul à chaque fois qu'une demande est faite, la charge de calcul sur l'ordinateur peut être réduite et le traitement peut être effectué efficacement.

Recommended Posts

3.6 Normalisation de texte
Par langue: expressions régulières pour les mots de passe
[Python] Expressions régulières Expressions régulières
Pandas Python: recherchez DataFrame à l'aide d'expressions régulières
Appelez la bibliothèque Python pour la normalisation de texte depuis MATLAB
Text mining (pour mémo)
Utiliser des expressions régulières en C
Extraire des nombres avec des expressions régulières
À propos de Python et des expressions régulières