100 traitements de langage avec Python

introduction

Knock 100 language processing publié sur la page Web du laboratoire Inui-Okazaki de l'Université de Tohoku pour la formation au traitement du langage naturel et Python. Je vais contester nlp100 /). Je prévois de prendre note du code implémenté et des techniques à supprimer. Le code est également disponible sur GitHub.

Le manuel utilise "Introduction au support de Python 2 & 3 (écrit par Kenji Hosoda et al., Hidekazu System)".

Nous aimerions vous présenter les articles auxquels nous avons fait référence lors du démarrage. Je ne peux pas nier le sentiment que c'est trop utile, alors veuillez me contacter si vous vous sentez mal à l'aise.

Puisque je suis un amateur de Zub, c'est très disgracieux car la notation n'est pas unifiée et les relations Python 2/3 sont mixtes, mais j'apprécierais que vous le précisiez. L'environnement d'exécution lui-même est Python 2.

Chapitre 1: Mouvement préparatoire

00. Ordre inverse des chaînes

Récupère une chaîne dans laquelle les caractères de la chaîne "accentués" sont disposés à l'envers (de la fin au début).

Répondre

00.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 00.py

str = "stressed"
print(str[-1::-1])

commentaire

Exercice de la technique du "slicing" pour les chaînes de caractères. Comme mentionné dans l'article ci-dessus (http://qiita.com/tanaka0325/items/08831b96b684d7ecb2f7), j'étudierai à nouveau le tranchage.

Une tranche est décrite sous la forme de index de chaîne de caractères [index de début: index de fin: nombre d'étapes] pour découper une partie de la chaîne de caractères et l'acquérir. En plus des chaînes de caractères, des listes peuvent être utilisées.

str = "abcdefgh"

#Obtenez un personnage spécifique
str[0]        # 'a', Zéro depuis le début-based
str[-1]       # 'h', Peut être spécifié même avec un nombre négatif (en partant de la fin de la phrase) Cette fois, str[7]Synonyme de

#tranche
str[1:3]      # 'bc', Notez que le caractère de l'index de fin n'est pas inclus. Pas le nombre de caractères
str[0:-3]     # 'abcde', Les nombres négatifs sont OK. Cette fois str[0:5]Synonyme de
str[:4]       # 'abcd', Si l'index de départ est omis, depuis le début
str[4:]       # 'efgh', Jusqu'à la fin si l'index de fin est omis

#Spécifiez le nombre d'étapes
str[0:6:2]    # 'ace', Acquiert les caractères discrets du montant spécifié par le nombre d'étapes (0),2,4ème)
str[::3]      # 'adg', Peut être omis
str[-3::2]    # 'fh', Les nombres négatifs sont également possibles
str[::-3]     # 'hed', Si le nombre de pas est négatif, il revient dans l'ordre inverse

Donc la réponse cette fois était str [:: -1], mais c'était ma première expérience avec le tranchage, alors s'il vous plaît, regardez bien ...

01. «Patatokukashi»

Retirez les 1er, 3e, 5e et 7e caractères de la chaîne de caractères "Patatokukashi" et récupérez la chaîne de caractères concaténée.

Répondre

01.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 01.py

str = u'Patatoku Kashii'
print(str[0::2])

commentaire

Slice exercices ainsi que 00. De même, vous pouvez omettre la position de départ et utiliser str [:: 2]. De plus, les chaînes de caractères japonais (Unicode) peuvent être préfixées avec u, comme ʻu'hogehoge'` (environnement UTF-8).

02. "Patcar" + "Tax" = "Patatokukasie"

Récupérez la chaîne de caractères "Patatokukashi" en reliant alternativement les caractères "Pattocar" + "Tax" depuis le début.

Répondre

02.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 02.py

str1 = u'Voiture Pat'
str2 = u'Taxi'
str3 = u''

for a,b in zip(str1, str2):
    str3 = str3 + a + b

print str3

commentaire

zip () est une fonction qui extrait un élément de chaque argument et crée un taple. Techniques qui peuvent être utilisées lors de la spécification des conditions pour «boucle for». print n'est soudainement plus une fonction, mais c'est la notation Python 2. Je suis désolé pour le mélange.

Et cela est également mentionné dans l'article ci-dessus, mais il semble que la méthode d'ajout à la fin à chaque fois pendant une boucle soit problématique en termes de vitesse d'exécution. chose. Il semble préférable de combiner les chaînes plus tard comme print (''. Join ([a + b pour a, b in zip (str1, str2)])). `` '. Join () joint les éléments dans l'argument après les avoir séparés avec le délimiteur entre ' '. Veuillez noter que le style d'écriture a changé.

03. Taux circonférentiel

Décomposez la phrase "Maintenant, j'ai besoin d'un verre, alcoolique bien sûr, après les lourdes conférences sur la mécanique quantique."

Répondre

03.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 03.py

str = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
str = str.replace('.', "")
str = str.replace(',', "")
str = str.split()

list = []

for word in str:
    list.append(len(word))

print list

commentaire

Après avoir supprimé le point et la virgule avec replace (), séparez chaque mot avec split (), obtenez la longueur avec len () et plongez dans liste. .. Je me suis demandé s'il y avait une meilleure façon de supprimer les points et les virgules, mais j'ai abandonné. Puisque split () peut spécifier un délimiteur comme argument (la valeur par défaut est un espace), j'ai pensé que je les spécifierais tous en même temps, mais je ne pouvais pas.

04. Symbole d'élément

Décomposez la phrase "Salut, il a menti parce que le bore ne pouvait pas oxyder le fluor. Les nouvelles nations pourraient également signer la clause de sécurité de paix. Arthur King Can." En mots 1, 5, 6, 7, 8, 9, 15, 16, Le 19e mot est le premier caractère et les autres mots sont les deux premiers caractères. Créer.

Répondre

04.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 04.py

str = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
str = str.split()

dict = {}
single = [1, 5, 6, 7, 8, 9, 15, 16, 19]

for element in str:
    if str.index(element) + 1 in single:
        dict[element[:1]] = str.index(element) + 1
    else:
        dict[element[:2]] = str.index(element) + 1

#Trier par numéro atomique et imprimer
for k, v in sorted(dict.items(), key=lambda x:x[1]):
    print k, v

commentaire

Comme avec 03, chaque mot est séparé et traité individuellement avec "pour boucle". Puisque seul le début est vu de toute façon, le traitement de la période est omis. Je ne peux pas m'empêcher de penser que le magnésium devient Mi à ce rythme ... Est-ce inévitable? Vous pouvez les spécifier individuellement et les découper (ʻelement [: 3: 2] ). Vous n'êtes pas obligé de le mettre en tant que single, mais str.index (element) + 1` apparaît trois fois, donc je veux bien organiser cette zone. Est-ce une solution si vous l'assignez à une variable appropriée? En outre, le dictionnaire ne garantit pas l'ordre en premier lieu, mais il est trié pour une visualisation facile.

Réparer

Version modifiée


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 04.py

str = "Hi He Lied Because Boron Could Not Oxidize Fluorine.\
 New Nations Might Also Sign Peace Security Clause. Arthur King Can."
words_list = str.split()

dict = {}
single = [0, 4, 5, 6, 7, 8, 14, 15, 18]

for i in range(len(words_list)):
    clen = 1 if i in single else 2
    dict[words_list[i][:clen]] = i + 1

#Trier par numéro atomique et imprimer
# for k, v in sorted(dict.items(), key=lambda x: x[1]):
#     print(k, v)

Les principales améliorations sont les suivantes.

Je pense que la chose la plus importante en ce moment est de tourner «pour» par index. Je voulais essayer la manière d'écrire for, que j'ai apprise pour la première fois dans le code précédent, et par conséquent, j'ai à nouveau obtenu l'index avec ʻindex ()` ...

  1. n-gram

Créez une fonction qui crée un n-gramme à partir d'une séquence donnée (chaîne, liste, etc.). Utilisez cette fonction pour obtenir le mot bi-gramme et la lettre bi-gramme à partir de la phrase "Je suis un PNL".

Répondre

05.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 05.py

original = "I am an NLPer"

def ngram(input, n):
    #Caractère n-gram (Argument str)
    l = len(input)
    if type(input) == str:
        input = "$" * (n - 1) + input + "$" * (n - 1)
        for i in xrange(l + 1):
            print input[i:i+n]
    #Mot n-gram (Liste d'arguments)
    elif type(input) == list:
        input = ["$"] * (n - 1) + input + ["$"] * (n - 1)
        for i in xrange(l + 1):
            print input[i:i+n]

ngram(original, 2)              #Caractère n-gram
original = original.split()
ngram(original, 2)              #Mot n-gram

commentaire

C'était plus dur que ce à quoi je m'attendais. De nombreux réglages fins tels que ± 1 en raison de la longueur du nombre de caractères ... J'ai inséré «$» avant le début et après la fin de la chaîne de caractères. Je voulais implémenter une fonction comme la surcharge Java, mais il semble que la surcharge ne soit pas implémentée par défaut en Python, donc je l'ai implémentée avec type ().

Commentaires et mise en œuvre

Commentaires et implémentation de knok.

Implémentation de la fonction ngram par knok


def ngram(input, n):
    last = len(input) - n + 1
    ret = []
    for i in range(0, last):
        ret.append(input[i:i+n])
    return ret

En n'insérant pas «$» au début et à la fin, vous pouvez implémenter intelligemment à la fois. Dans la chaîne de caractères et dans la liste, vous pouvez spécifier l'élément par index et le découper, vous n'avez donc pas besoin de connaître le type.

Hmm magnifique. Regarder à nouveau mon code me donne le vertige. Merci beaucoup.

06. Réunion

Trouvez l'ensemble des caractères bi-grammes contenus dans «paraparaparadise» et «paragraphe» comme X et Y, respectivement, et trouvez les ensembles somme, produit et différence de X et Y, respectivement. En outre, découvrez si le bi-gram'se'est inclus dans X et Y.

Répondre

06.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 06.py

str1 = "paraparaparadise"
str2 = "paragraph"

def ngram(input, n):
    l = len(input)
    list = []
    input = "$" * (n - 1) + input + "$" * (n - 1)
    for i in xrange(l + 1):
        list.append(input[i:i+n])
    return list

#ngram liste à définir;Peut éliminer la duplication et effectuer des opérations d'ensemble
X = set(ngram(str1, 2))
Y = set(ngram(str2, 2))

print X.union(Y)            #Ensemble de somme
print X.intersection(Y)     #Ensemble de produits
print X.difference(Y)       #Ensemble de différences

print "se" in X		# in:Vers X"se"Vrai si,Faux sinon
print "se" in Y		#Presque le même (X-> Y)

commentaire

Voir le code pour une utilisation spécifique. Je suis heureux de pouvoir écrire de telles opérations de manière intuitive.

Réparer

Version modifiée


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 06.py

from mymodule import ngram

str1 = "paraparaparadise"
str2 = "paragraph"

X = set(ngram(str1, 2))
Y = set(ngram(str2, 2))

#Omission

En référence à cet article, je l'ai paramétré pour que la fonction créée en 05 puisse être réutilisée.

07. Génération de déclaration par modèle

Implémentez une fonction qui prend les arguments x, y, z et renvoie la chaîne "y at x is z". De plus, définissez x = 12, y = "température", z = 22,4 et vérifiez le résultat de l'exécution.

Répondre

07.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 07.py

x = 12
y = u'Température'
z = 22.4

def function(x, y, z):
    return unicode(x) + u'de temps' + unicode(y) + u'Est' + unicode(z)

print function(x, y, z)

commentaire

Puisque x et y sont respectivement ʻint et float, ils doivent être convertis lors de la concaténation avec ʻUnicode. La conversion du code de caractère semble être assez profonde si vous creusez plus profondément, mais cette fois cela a fonctionné, donc surtout. Existe-t-il un moyen d'utiliser ~~ zip ()? ~~ Ça ne ressemble pas à ça.

08. Cryptographie

Implémentez la fonction de chiffrement qui convertit chaque caractère de la chaîne de caractères donnée avec les spécifications suivantes.

  • Remplacer par (219 --character code) caractères si minuscules

  • Afficher les autres caractères tels quels

Utilisez cette fonction pour crypter / décrypter les messages en anglais.

Répondre

08.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 08.py

#La source:Wikipédia version anglaise"Atbash"Que
str = "Atbash is a simple substitution cipher for the Hebrew alphabet."

def cipher(input):
    ret = ""
    for char in input:
        ret += chr(219-ord(char)) if char.islower() else char
    return ret

str = cipher(str)
print str
str = cipher(str)
print str

commentaire

Puisqu'il s'agit d'un soi-disant «code Atbash», il peut être chiffré et déchiffré avec la même fonction. chr () est une fonction qui convertit le code ASCII en caractères concrets (chr (97) -> 'a'). ʻOrd () ʻest l'opposé, mais Unicode renvoie des points de code Unicode. La version Unicode de chr () est ʻunichr () `.

Avant la conversion Après la conversion Fonction à utiliser
Code ASCII Caractères ASCII chr()
Point de code Unicode Caractères Unicode unichr()
Caractères ASCII Code ASCII ord()
Caractères Unicode Point de code Unicode ord()

Voir également Document officiel.

Nous avons rassemblé des branches «si» en utilisant l'opérateur ternaire.

Opérateur triangulaire


#Valeur 1 lorsque l'expression conditionnelle est vraie, valeur 2 lorsque l'expression conditionnelle est fausse
Valeur 1 si expression conditionnelle sinon valeur 2
  1. Typoglycemia

Créez un programme qui réorganise de manière aléatoire l'ordre des autres caractères, en laissant le premier et le dernier caractère de chaque mot pour la chaîne de mots séparés par des espaces. Cependant, les mots d'une longueur de 4 ou moins ne sont pas réorganisés. Donnez une phrase en anglais appropriée (par exemple, "Je ne pouvais pas croire que je pouvais réellement comprendre ce que je lisais: le pouvoir phénoménal de l'esprit humain.") Et vérifiez le résultat de l'exécution.

Répondre

09.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 09.py
import random

str = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."
words = str.split()
shuffled_list = []

for word in words:
    if len(word) < 4:
        pass
    else:
        char_list = list(word)
        mid_list = char_list[1:-1]
        random.shuffle(mid_list)
        word = word[0] + "".join(mid_list) + word[-1]
    shuffled_list.append(word)

shuffled_str = " ".join(shuffled_list)
print shuffled_str

commentaire

Remplacez aléatoirement les chaînes de caractères par random.shuffle ()! Très pratique. Cela semble assez ennuyeux à implémenter en C, mais ... Je suis reconnaissant que Python dispose d'une bibliothèque aussi riche. Comme il est complètement aléatoire, la même chaîne de caractères que la chaîne de caractères d'origine peut être renvoyée. S'il en est de même après avoir comparé les chaînes de caractères, vous pouvez réessayer ou l'implémenter.

Supplément

(Chaîne de caractères) Il y a == et ʻisdans la comparaison. Alors que== compare uniquement le contenu, ʻis compare s'il s'agit du même objet. Cette fois, il est plus correct d'utiliser == lors de l'implémentation de la comparaison de chaînes.

(Citation) En Python, les deux «» «et» «sont OK lors de la clôture d'une chaîne. Cependant, lorsque vous utilisez '' en possession ou en abréviation en anglais, si vous placez toute la chaîne de caractères entre '', les quotas ne correspondront pas et une erreur se produira. Pour contourner ce problème, vous pouvez soit l'enfermer dans «» soit l'échapper avec une barre oblique inverse telle que «\» ».

Réparer

Version modifiée


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 09.py

import random


def word_typoglycemia(word):
    if len(word) <= 4:
        return word

    mid_list = list(word[1:-1])
    while mid_list == list(word[1:-1]):
        random.shuffle(mid_list)
    return word[0] + "".join(mid_list) + word[-1]


def str_typoglycemia(str):
    shuffled_list = []
    for word in str.split():
        shuffled_list.append(word_typoglycemia(word))
    return " ".join(shuffled_list)


str = "I couldn't believe that I could actually understand \
 what I was reading : the phenomenal power of the human mind ."

print(str_typoglycemia(str))

Les principales améliorations sont les suivantes.

Le grand changement est l'élimination des coïncidences, mais il est un peu regrettable qu'il n'y ait aucune garantie que «tant que» se terminera. C'est très peu probable ... (même les 5 caractères les plus dangereux, si vous bouclez n fois, la probabilité est $ \ frac {1} {6 ^ {n}} $)

en conclusion

Suite au Chapitre 2, Partie 1.

Recommended Posts

100 traitements de langage avec Python
100 traitements de langage avec Python (chapitre 3)
100 traitements de langage avec Python (chapitre 2, partie 2)
100 traitements de langage avec Python (chapitre 2, partie 1)
100 coups de traitement du langage avec Python 2015
100 Language Processing Knock Chapitre 1 (Python)
100 Language Processing Knock Chapitre 2 (Python)
100 Language Processing Knock Chapitre 1 en Python
100 Language Processing Knock Chapitre 1 par Python
100 Language Processing Knock 2020 Chapitre 1
100 Traitement du langage Knock Chapitre 1
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
J'ai fait 100 traitements linguistiques Knock 2020 avec GiNZA v3.1 Chapitre 4
100 Language Processing Knock 2020 Chapitre 2: Commandes UNIX
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Language Processing Knock 2020 Chapitre 9: RNN, CNN
100 coups de traitement linguistique (2020): 28
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
[Chapitre 5] Introduction à Python avec 100 coups de traitement du langage
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
100 Language Processing Knock 2020 Chapitre 10: Traduction automatique (90-98)
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
[Chapitre 3] Introduction à Python avec 100 coups de traitement du langage
100 Traitement du langage Knock 2020 Chapitre 7: Vecteur de mots
100 Language Processing Knock 2020 Chapitre 8: Neural Net
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (05 ~ 09)
100 coups de traitement linguistique (2020): 38
[Chapitre 2] Introduction à Python avec 100 coups de traitement du langage
Réhabilitation des compétences Python et PNL à partir de "100 Language Processing Knock 2015" (Chapitre 1)
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 1
100 traitement de la langue frapper 00 ~ 02
100 Language Processing Knock 2020 Chapitre 1: Mouvement préparatoire
100 Language Processing Knock 2020 Chapitre 3: Expressions régulières
100 Language Processing Knock 2015 Chapitre 4 Analyse morphologique (30-39)
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 2
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 4
[Chapitre 4] Introduction à Python avec 100 coups de traitement du langage
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (00 ~ 04)
3. Traitement du langage naturel par Python 2-1. Réseau de co-occurrence
Traitement d'image par Python 100 knock # 12 motion filter
3. Traitement du langage naturel par Python 1-1. Word N-gram
[Programmeur nouveau venu "100 language processing knock 2020"] Résoudre le chapitre 1
Traitement du langage 100 knocks-88: 10 mots à haute similitude
100 traitements linguistiques Knock 2020 [00 ~ 39 réponse]
100 langues de traitement knock 2020 [00-79 réponse]
100 traitements linguistiques Knock 2020 [00 ~ 69 réponse]
Réhabilitation des compétences Python et PNL à partir de "100 Language Processing Knock 2015" (Chapitre 2 premier semestre)
100 coups de traitement du langage amateur: 17
100 traitements linguistiques Knock 2020 [00 ~ 49 réponse]
100 Traitement du langage Knock-52: Stemming
100 coups de traitement du langage ~ Chapitre 1
100 coups de langue amateur: 07
Le traitement de 100 langues frappe le chapitre 2 (10 ~ 19)
Traitement d'image avec Python
100 coups de traitement du langage amateur: 09
100 coups en traitement du langage amateur: 47
Traitement 100 langues knock-53: Tokenisation