Dieser Artikel richtet sich an diejenigen, die mit der Verarbeitung natürlicher Sprache mit Python beginnen möchten, mit ein wenig Verständnis von C, aber wenig Wissen über Python. Wir streben den kürzesten Weg zur Lösung von Kapitel 1 von 100 Language Processing Knock 2015 an, das als Einführung in die Verarbeitung natürlicher Sprache bekannt ist. .. (4/8 Nachschrift: Kapitel 1 ist das gleiche für die Version 2020)
Es gibt bereits viele Artikel zu diesem Qiita-Antwortbeispiel für 100 Schläge, aber die Erklärung ist nicht so vollständig und ich dachte, es wäre schwierig für Python-Anfänger, also habe ich diesen Artikel geschrieben.
Die offizielle Dokumentation für Python ist ziemlich nett, und ich denke, Sie können selbst lernen, indem Sie das Tutorial lesen, aber in diesem Artikel Ich möchte nur die Dinge ansprechen, die notwendig sind, um 100 Schläge zu lösen.
geben wir unser Bestes. $ Brew install python3
für MacOS, $ sudo apt install python3.7 python3.7-dev
für Ubuntu
In einfachem Windows scheint es einfach zu sein, auf Python-Installation (Win10) zu verweisen.
(Möglicherweise handelt es sich um Google Colaboratory.)
Es ist in Ordnung, wenn Python3 durch Eingabe eines Befehls wie "$ python3" oder "$ python3.7" in der Befehlszeile gestartet werden kann. Python kann jetzt im interaktiven Modus ausgeführt werden. Wenn Sie in diesem Modus einen Ausdruck eingeben und die Eingabetaste drücken, wird das Bewertungsergebnis des Ausdrucks zurückgegeben.
>>> 1+2
3
Eine der Funktionen von Python ist "Dynamic Typing". Im Gegensatz zu C müssen Sie den Typ der Variablen nicht deklarieren, und der Integer-Typ (int) wird zum Gleitkomma-Typ (float).
>>> a = 1
>>> a = 5/2
>>> a
2.5
Lassen Sie uns zunächst sehen, welche Typen (integrierte Typen) im Python-Standard verwendet werden können. Numerische Typen wie int und float, die im obigen Beispiel erwähnt wurden, sind einer davon. 100 Schläge In Kapitel 1 können Sie es lösen, wenn Sie nur die folgenden Typen kennen.
Da wir die Sprache verarbeiten, beginnen wir mit dem Zeichenkettentyp. Um eine Zeichenfolge in Python zu schreiben, schließen Sie sie einfach in '
oder "
ein! Japanisch ist perfekt. Sie können Zeichenfolgen einfach kombinieren.
>>> "Herzlich willkommen"
'Herzlich willkommen'
>>> 'hoge' + 'fuga'
'hogefuga'
>>> word = 'Python'
>>> word[0]
'P'
>>> word[-1]
'n'
>>> word[1:4]
'yth'
>>> word[2:-1]
'tho'
>>> word[:2]
'Py'
>>> word[2:]
'thon'
word [i: j: k]
können Sie die Elemente vom i
th zum weniger als dem j
th by k
bekommen.>>> word[1:5:2]
'yh'
>>> word[::2]
'Pto'
>>> word[::-2]
'nhy'
Lassen Sie uns die Scheiben voll ausnutzen.
Holen Sie sich eine Zeichenfolge, in der die Zeichen der Zeichenfolge "betont" umgekehrt angeordnet sind (vom Ende bis zum Anfang).
Unten finden Sie ein Beispiel für die Antwort.
nlp00.py
word = 'stressed'
word[::-1]
'desserts'
Nehmen Sie das 1., 3., 5. und 7. Zeichen der Zeichenkette "Patatokukashi" heraus und erhalten Sie die verkettete Zeichenkette.
Unten finden Sie ein Beispiel für die Antwort.
nlp01.py
word = 'Patatoku Cassie'
word[::2]
'Streifenwagen'
Wenn Sie sich den Listentyp als eine Einschaltversion des in C erlernten Arrays vorstellen, ist dies in Ordnung. Schreiben Sie wie folgt.
squares = [1, 4, 9, 16, 25]
Schreiben Sie eine leere Liste wie folgt:
empty = []
Der Listentyp kann auf dieselbe Weise wie der Zeichenfolgentyp tiefgestellt und in Scheiben geschnitten werden. Diese integrierten Typen werden gemeinsam als ** Sequenztypen ** bezeichnet.
>>> squares[:3]
[1, 4, 9]
In Python gibt es Funktionen für jeden Datentyp, die als ** Methoden ** bezeichnet werden.
Beispielsweise fügt die Methode "Anhängen" des Listentyps der Liste ein Element hinzu. Um es aufzurufen, schreiben Sie list.append ()
wie folgt.
>>> squares.append(36)
>>> squares
[1, 4, 9, 16, 25, 36]
Ich werde auch einige Methoden vom Typ String vorstellen.
--x.split (sep)
: Erstellen Sie eine Liste, indem Sie die Zeichenfolge x
durch sep
trennen.
--sep.join (list)
: Erstellt eine Zeichenfolge, die die Elemente von list
mit sep
kombiniert
--x.strip (chars)
: Gibt den String zurück, wobei chars
von beiden Enden des Strings entfernt wurde
--x.rstrip (chars)
: Gibt den String zurück, wobei chars
am rechten Rand des Strings entfernt ist
** * Wenn die Argumente von "split ()", "strip ()" und "rstrip ()" weggelassen werden, bedeutet dies "beliebiges Leerzeichen" **
>>> 'I have a pen.'.split(' ')
['I', 'have', 'a', 'pen.']
>>> ' '.join(['I', 'have', 'a', 'pen.'])
'I have a pen.'
Es kann etwas schwierig sein, sich daran zu erinnern, dass join ()
eher eine String-Typ-Methode als eine Listentyp-Methode ist. Zusammenfassend lässt sich sagen, dass jedes Element der Liste keine Zeichenfolge ist Weil es nicht anwendbar ist.
>>> 'ehoge'.strip('e')
'hog'
>>> 'ehoge'.rstrip('e')
'ehog'
>>> 'ehoge'.rstrip('eg') #Bedeutet, e oder g so weit wie möglich vom rechten Rand zu entfernen
'eho'
Nachdem Sie die Liste verstanden haben, wollen wir uns mit der for-Anweisung befassen, mit der etwas wiederholt wird. Bei der Berechnung der Summe der Elemente eines Arrays in C habe ich beispielsweise Folgendes geschrieben.
int i;
int squares[6] = {1, 4, 6, 16, 25, 36};
int total = 0;
for(i = 0; i < 6; i++) {
total += squares[i];
}
Die Python for-Anweisung sieht folgendermaßen aus.
total = 0
for square in squares:
total += square
Jede Schleife nimmt ein Element von "Quadraten" und weist es "Quadrat" zu. Mit anderen Worten, "Quadrat = 1", "Quadrat = 4", und so weiter. Die Formalisierung der for-Anweisung sieht folgendermaßen aus.
Variablen in der Liste, die das for-Element darstellen: TAB-Verarbeitungsinhalt
Unmittelbar nach "in" wird als "Liste" getäuscht, aber es ist in Ordnung, auch wenn es sich um einen Zeichenkettentyp handelt (da jedes Zeichen als Element einer Zeichenkette betrachtet werden kann). Der generische Name für Dinge, die unmittelbar nach dem "in" in der for-Anweisung platziert werden können, ist ** iterierbar.
Einrückung war in C optional, in Python jedoch obligatorisch!
print()
Lassen Sie uns den Wert der Variablen in der for-Schleife sehen. Im interaktiven Modus wird die Funktion print ()
verwendet, da die Variablen im for-Block nicht ausgewertet und der Wert angezeigt werden. Argumente werden standardmäßig ausgegeben, auch wenn sie kein Zeichenfolgentyp sind. Sie können es verwenden, ohne etwas wie "# include" in C zu tun. Solche Funktionen werden als ** eingebaute Funktionen ** bezeichnet.
for square in squares:
print(square)
1
4
9
16
25
36
Wie Sie sehen können, bricht Pythons Funktion "print ()" automatisch Zeilen (standardmäßig). Geben Sie das optionale Argument "end" wie folgt an, um Zeilenumbrüche zu vermeiden.
for square in squares:
print(square, end=' ')
1 4 9 16 25 36
len()
Ich werde nützliche integrierte Funktionen vorstellen. len ()
gibt die Länge einer Liste, eines Strings usw. zurück.
>>> len(squares)
6
>>> len('AIUEO')
5
range()
range ()
wird im Allgemeinen verwendet, wenn Sie die for-Anweisung n-mal drehen möchten.
for i in range(3):
print(i)
0
1
2
range ()
wird als Bereichstyp bezeichnet, bei dem es sich um einen Sequenztyp handelt. Die Verwendung entspricht jedoch der Konvertierung in einen for-Anweisungs- oder Listentyp.>>> range(3)
range(0, 3)
>>> list(range(4))
[0, 1, 2, 3]
Versuchen wir auch, den Quellcode in einer Datei zu speichern und auszuführen. Wenn Sie beispielsweise eine Datei mit nur "print (" Hello World ")" als "hello.py" speichern und "$ python3 hello.py" in die Befehlszeile eingeben, sollte "Hallo Welt" ausgegeben werden. .. Fahren wir mit 100 Schlägen fort.
Erhalten Sie die Zeichenkette "Patatokukashi", indem Sie die Zeichen "Pattocar" + "Tax" von Anfang an abwechselnd verbinden.
Lassen Sie uns so viel tun, wie wir bisher gelernt haben. Unten finden Sie ein Beispiel für die Antwort.
nlp02.py
str_a = 'Pat Auto'
str_b = 'Taxi'
for i in range(len(str_a)):
print(str_a[i]+str_b[i], end='')
Patatoku Kashii
In einem solchen Fall können Sie es einfacher schreiben, indem Sie die integrierte Funktion zip ()
verwenden. Diese Funktion koppelt das i-te Element aus dem iterierbaren Argumentobjekt.
>>> list(zip(str_a, str_b))
[('Pa', 'Ta'), ('To', 'Ku'), ('Ka', 'Shi'), ('ー', 'ー')]
Der obige Code kann also wie folgt umgeschrieben werden: Dies ist eine sehr häufig verwendete Funktion.
for a, b in zip(str_a, str_b):
print(a+b, end='')
Patatoku Kashii
Übrigens scheint es zu bedeuten, den Reißverschluss unabhängig vom Dateiformat "ZIP" zu straffen.
Wenn Sie nicht gedacht haben, was ist dieses Komma? Nachdem Sie die obige Erklärung gelesen haben, überspringen Sie diesen Abschnitt und lösen Sie Frage 03.
Das Objekt, das dieses "zip ()" in jeder Schleife abruft, ist wie eine Liste mit "str_a [i]" und "str_b [i]" als Elementen. Um richtig zu sein, es ist ein Taple, eine unveränderliche Version der Liste.
Da tapple eine Art Sequenz ist, können Sie auf Indizes zugreifen, aber Sie können keine Elemente mit append ()
usw. hinzufügen. In Python wird das, was geändert werden kann, als veränderlich und das, was nicht geändert werden kann, als unveränderlich bezeichnet. Ich habe bisher durchgemacht, aber Listen sind veränderlich und Strings und Taples sind unveränderlich.
>>> a = 'abc'
>>> a[1] = 'a'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-ae17b2fd35d6> in <module>
1 a = 'abc'
----> 2 a[1] = 'a'
TypeError: 'str' object does not support item assignment
>>> a = [0, 9, 2]
>>> a[1] = 1
>>> a
[0, 1, 2]
Das Taple wird beschrieben, indem es in "()" eingeschlossen wird, aber normalerweise ist das äußere "()" nicht erforderlich (es kann nicht in dem "()" weggelassen werden, in dem das Funktionsargument geschrieben ist).
>>> 1, 2, 3
(1, 2, 3)
Unter Verwendung der Spezifikation, die durch Weglassen des "()" des Taples beschrieben werden kann, wird das Zuweisen mehrerer durch "," getrennter Werte zu einer Variablen als Taple-Pack bezeichnet. Im Gegensatz dazu wird das Zuweisen einer Sequenz zu mehreren Variablen gleichzeitig als Sequenzentpacken bezeichnet.
>>> a = 'a'
>>> b = 'b'
>>> t = a, b
>>> t
('a', 'b')
>>> x, y = t
>>> print(x)
>>> print(y)
a
b
Die Seitenstraße ist lang geworden, aber jetzt weiß ich, was "für a, b in zip (str_a, str_b)" ist. Die von der Zip-Funktion in jeder Schleife zurückgegebenen Taples werden in die Variablen a und b entpackt.
Machen wir das.
Brechen Sie den Satz "Jetzt brauche ich nach den schweren Vorlesungen über Quantenmechanik einen Alkoholiker." In Wörter auf und erstellen Sie eine Liste der Anzahl der (alphabetischen) Zeichen in jedem Wort in der Reihenfolge ihres Auftretens.
Dieses Problem, Punkte und Kommas sind nicht alphabetisch und müssen entfernt werden, um ein Umfangsverhältnis zu erhalten.
Unten finden Sie ein Beispiel für die Antwort.
nlp03.py
sent = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
words = sent.split()
ans = []
for word in words:
ans.append(len(word.rstrip('.,')))
print(ans)
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
Es gibt tatsächlich eine bessere Möglichkeit, es zu schreiben (Aufnahme in die Liste), aber es ist in Ordnung, wenn Sie es zu diesem Zeitpunkt noch nicht gesehen haben.
ans = [len(word.rstrip('.,')) for word in words]
In Zeichenfolgen und Listen haben wir Indizes verwendet, dh eine Reihe von Ganzzahlen, um auf Elemente zuzugreifen. Auf Wörterbuchtypen kann jedoch mit einem von uns definierten "Schlüssel" zugegriffen werden. Da Sie beispielsweise die Anzahl der Vorkommen eines bestimmten Wortes speichern möchten, können Sie ein Wörterbuch mit dem Schlüssel als Wort und dem Wert als Anzahl der Vorkommen erstellen. Das Wörterbuchobjekt ist wie folgt definiert und der Wert wird abgerufen. Sie können Ihrem Wörterbuch auch problemlos Schlüssel / Wert-Paare hinzufügen.
>>> dic = {'I':141, 'you':112}
>>> dic
{'I': 141, 'you': 112}
>>> dic['I']
141
>>> dic['have'] = 256
>>> dic
{'I': 141, 'you': 112, 'have': 256}
Richtig oder falsch wird zurückgegeben, wenn eine Gleichung oder Ungleichung ausgewertet wird.
>>> 1 == 1
True
>>> 1 == 2
False
>>> 1 < 2 <= 3
True
Sie können den Bool-Wert mit not
invertieren.
In
ohne for bestimmt die Zugehörigkeit.
>>> 1 in [1, 2, 3]
True
Diejenigen mit definierten In-Operationen werden als ** Containertypen ** bezeichnet. Zeichenketten, Listen, Tapples und Wörterbücher sind Containertypen.
Beachten Sie, dass die if-Anweisung in Python C ähnelt, jedoch "elif" anstelle von "else if" ist.
if 1==2:
print('hoge')
elif 1==3:
print('fuga')
else:
print('bar')
bar
Lassen Sie uns das bisher Gelernte voll ausnutzen.
Brechen Sie den Satz "Hi He Lied, weil Bor Fluor nicht oxidieren konnte. Neue Nationen könnten auch die Friedenssicherheitsklausel unterzeichnen. Arthur King Can." In die Wörter 1, 5, 6, 7, 8, 9, 15, 16 auf. Das 19. Wort ist das erste Zeichen, und die anderen Wörter sind die ersten beiden Zeichen und das assoziative Array (Wörterbuchtyp oder Kartentyp) von der extrahierten Zeichenfolge bis zur Position des Wortes (welche Anzahl von Wörtern von Anfang an) Erstellen.
Unten finden Sie ein Beispiel für die Antwort.
nlp04.py
sent = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
positions = [1, 5, 6, 7, 8, 9, 15, 16, 19]
words = sent.split()
i = 1
ans = {}
for word in words:
if i in positions:
key = word[0]
else:
key = word[:2]
ans[key] = i
i += 1
print(ans)
{'H': 1, 'He': 2, 'Li': 3, 'Be': 4, 'B': 5, 'C': 6, 'N': 7, 'O': 8, 'F': 9, 'Ne': 10, 'Na': 11, 'Mi': 12, 'Al': 13, 'Si': 14, 'P': 15, 'S': 16, 'Cl': 17, 'Ar': 18, 'K': 19, 'Ca': 20}
(Was, Mi hat kein Elementsymbol? Erstens ist die englische Version meines Schiffes wie ein Dämonentor ...)
Die eingebaute Funktion "enumerate ()" addiert die Anzahl der Schleifen und erleichtert so das Schreiben. Da es bei normaler Verwendung bei 0 beginnt, wird das Optionsargument start = 1
angegeben.
ans = {}
for i, word in enumerate(words, start=1):
if i in where:
key = word[0]
else:
key = word[:2]
ans[key] = i
Enumerate ()
ist sehr praktisch und wird oft so verwendet. Tatsächlich gibt es eine Möglichkeit, die Elemente von "Wörtern" mit "enumerate ()" zu ändern, selbst in [03](# 100 knock 03) (Sie können sich die Mühe sparen, eine neue Liste "ans" zu erstellen). ..
Als nächstes versuchen wir 100 klopfen 05.
Erstellen Sie eine Funktion, die aus einer bestimmten Sequenz (Zeichenfolge, Liste usw.) ein n-Gramm erstellt. Verwenden Sie diese Funktion, um das Wort Bi-Gramm und den Buchstaben Bi-Gramm aus dem Satz "Ich bin ein NLPer" zu erhalten.
Wenn Sie Ihre eigene Funktion in Python definieren möchten, können Sie wie folgt schreiben.
def function_name(argument): TAB-Verarbeitung
Das Ausgabeformat ist nicht angegeben, aber schreiben wir einen Code, der beispielsweise wie folgt ausgibt.
[['i', 'am'], ['am', 'an], ['an', 'nlper']]
Es scheint in Ordnung zu sein, wenn Sie eine Funktion erstellen, die eine Sequenz und n als Argumente verwendet.
Unten finden Sie ein Beispiel für die Antwort.
def ngram(seq, n):
lis = []
for i in range(len(seq) - n + 1):
lis.append(seq[i:i+n])
return lis
Wenn Sie dies bisher getan haben, speichern Sie es in einer Datei mit dem Namen "nlp05.py" und führen Sie "$ python3 nlp05.py" in der Befehlszeile aus.
nlp05.py
def ngram(seq, n):
lis = []
for i in range(len(seq) - n + 1):
lis.append(seq[i:i+n])
return lis
if __name__ == '__main__':
sent = 'I am an NLPer'
words = sent.split(' ')
lis = ngram(words, 2)
print(lis)
lis = ngram(sent, 2)
print(lis)
Der Teil if __name__ == '__ main __':
ist erforderlich, da er im nächsten Problem importiert wird. Diejenigen, die sich fragen, sollten diese Zeile nicht einmal schreiben.
Die ngram-Funktion hat auch die folgende alternative Lösung, die schneller ist, aber die Erklärung ist etwas lang, daher werde ich sie weglassen.
def ngram(seq, n):
return list(zip(*(seq[i:] for i in range(n))))
Als nächstes kommt 100 Klopfen 06.
Suchen Sie den in "paraparaparadise" und "Absatz" enthaltenen Satz von Zeichen-Bi-Gramm als X bzw. Y und ermitteln Sie die Summen-, Produkt- und Differenzsätze von X bzw. Y. Finden Sie außerdem heraus, ob das Bi-Gramm in X und Y enthalten ist.
Lassen Sie uns zunächst den folgenden Code ausführen.
from nlp05 import ngram
x = set(ngram('paraparaparadise', 2))
print(x)
{'is', 'se', 'di', 'ap', 'ad', 'ar', 'pa', 'ra'}
Die zuvor im Teil from nlp05 import ngram
erstellte ngram-Funktion ist" importiert ".
Der Mengen-Typ kann manuell als "x = {" pa "," ar "}" definiert werden, er kann aber auch mit "set ()" aus anderen iterierbaren Objekten erstellt werden.
Die Summe kann mit |
berechnet werden, das Produkt mit &
und die Differenz mit -
.
Unten finden Sie ein Beispiel für die Antwort.
nlp06.py
from nlp05 import ngram
x = set(ngram('paraparaparadise', 2))
y = set(ngram('paragraph', 2))
print(x | y)
print(x & y)
print(x - y)
print(y - x)
print('se' in x)
print('se' in y)
{'is', 'se', 'di', 'ph', 'ap', 'ag', 'ad', 'ar', 'pa', 'gr', 'ra'}
{'ra', 'ap', 'pa', 'ar'}
{'is', 'se', 'ad', 'di'}
{'ag', 'gr', 'ph'}
True
False
Wenn Sie dies im Betrieb auf eine Liste wie Problem 04 anwenden, wird O (n) benötigt. Verwenden Sie es daher nach Möglichkeit als festgelegten Typ.
Löse 100 Schläge 07.
Implementieren Sie eine Funktion, die die Argumente x, y, z verwendet und die Zeichenfolge "y bei x ist z" zurückgibt. Setzen Sie außerdem x = 12, y = "Temperatur", z = 22,4 und überprüfen Sie das Ausführungsergebnis.
Es ist schwierig, dies zu tun, indem Zeichenketten mit +
kombiniert werden. In Python gibt es drei Möglichkeiten.
>>> x = 12
>>> y = 'Temperatur'
>>> '%Um d Uhr%s' % (x, y)
'12 Uhr Temperatur '
>>> '{}von Zeit{}'.format(x, y)
'12 Uhr Temperatur '
>>> f'{x}von Zeit{y}'
'12 Uhr Temperatur '
Grundsätzlich ist F-String am einfachsten. Backslashes können jedoch nicht in {}
verwendet werden. Wenn Sie die Anzahl der Ziffern angeben, scheint das printf-Format schneller zu sein (Referenz).
Damit können Sie 07 ohne zu zögern tun.
08 kann mit den integrierten Funktionen "ord ()" und "chr ()" ausgeführt werden, die zwischen Zeichen und Codepunkten konvertieren. Sie können Codepunkte verwenden, um den Fall zu bestimmen, oder Sie können str.islower ()
verwenden. Ein Codepunkt ist wie ein Index von Zeichen auf einem Computer. Das Konvertieren einer Bytezeichenfolge in einen Codepunkt wird als Decodierung bezeichnet, und umgekehrt wird als Codierung bezeichnet, und die Entsprechung zwischen ihnen wird als Zeichencode bezeichnet. Es kann gut sein, eine solche Geschichte zu kennen.
09 kann mit dem Shuffle () oder Sample () des Moduls random durchgeführt werden. Beachten Sie, dass shuffle () eine Methode ist, die die Originaldaten zerstört und keinen Rückgabewert hat. Vergessen Sie natürlich nicht zu importieren.
Sie sollten nun in der Lage sein, die Grundlagen von Python zu erlernen. Eigentlich wollte ich den Inhalt der Einschlussnotation, des Iterators, des Generators, des Lambda-Ausdrucks, des Auspackens der Argumentliste und von "map ()" behandeln, aber ich habe ihn weggelassen, weil ich den Darm abschneiden wollte. Wenn Sie interessiert sind, überprüfen Sie es bitte.
(4/25 Nachschrift) [Kapitel 2] Einführung in Python mit 100 Klopfen Sprachverarbeitung wurde veröffentlicht! Anhand der Probleme in Kapitel 2 werde ich einige der Inhalte erläutern, die ich oben behandeln wollte, zusätzlich zu den Eingaben / Ausgaben für Dateien und Unix-Befehlen.
Recommended Posts