Knock 100-Sprachverarbeitung, veröffentlicht auf der Webseite des Inui-Okazaki-Labors der Tohoku-Universität zum Training der Verarbeitung natürlicher Sprache und von Python. Ich werde nlp100 /) herausfordern. Ich habe vor, den darin implementierten Code und die Techniken, die unterdrückt werden sollten, zu notieren. Der Code wird auch auf GitHub veröffentlicht.
Dank des Überspringens für eine Weile schrieb ich einen Artikel, während ich den Code las, den ich zuvor geschrieben hatte. Ein Stil, "Ich bin vor drei Tagen eine andere Person" auf den Boden zu bringen. Während dieser Zeit änderte sich mein Kenntnisstand erheblich und ich schaute auf meinen Code, während ich miteinander sprach. Es gibt eine Lücke zwischen den Updates, aber ich hoffe, Sie können es als Stein von einem anderen Berg verwenden.
Es gibt eine Datei jawiki-country.json.gz, die Wikipedia-Artikel im folgenden Format exportiert.
Eine Artikelinformation pro Zeile wird im JSON-Format gespeichert In jeder Zeile wird der Artikelname im Schlüssel "title" und der Artikelkörper im Wörterbuchobjekt mit dem Schlüssel "text" gespeichert, und dieses Objekt wird im JSON-Format ausgeschrieben. Die gesamte Datei wird komprimiert Erstellen Sie ein Programm, das die folgende Verarbeitung ausführt.
Lesen Sie die JSON-Datei des Wikipedia-Artikels und zeigen Sie den Artikeltext zu "UK" an. Führen Sie in den Problemen 21-29 den hier extrahierten Artikeltext aus.
20.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 20.py
import json
with open("jawiki-country.json") as f:
article_json = f.readline()
while article_json:
article_dict = json.loads(article_json)
if article_dict["title"] == u"England":
print(article_dict["text"])
article_json = f.readline()
Die diesmal verwendete jawiki-country.json.gz ist 9,9 MB groß, was ziemlich schwer ist. Daher lese ich Zeile für Zeile mit "readline ()" und nur der Artikel "UK" ist "print" (andere Artikel sind durch). Ich habe das Gefühl, dass der Vorgang für eine Weile angehalten wird, wenn ich "readlines ()" mache, und wenn es einen breiteren Anwendungsbereich gibt, werde ich nur für Artikel in "UK" arbeiten, also habe ich ihn so implementiert.
In diesen Textdaten wird jede Zeile der Datei im JSON-Format beschrieben. Das Lesen von (json.load ()
) funktioniert jedoch nicht gut und der Vorteil von JSON kann nicht genutzt werden. Deshalb habe ich json.loads ()
verwendet, um es in das JSON-Format zu konvertieren (diesmal ist es ein echtes Wörterbuch). Ich werde.
Von hier aus wird die Arbeit, nur die Artikel von "UK" zu extrahieren, noch eine Weile fortgesetzt, daher habe ich sie wie folgt modularisiert.
extract_from_json.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# extract_from_json.py
import json
def extract_from_json(title):
with open("jawiki-country.json") as f:
json_data = f.readline()
while json_data:
article_dict = json.loads(json_data)
if article_dict["title"] == title:
return article_dict["text"]
else:
json_data = f.readline()
return ""
Im Gegensatz zu 20.py
gibt diese Funktion die Zeichenfolge des Artikels zurück, wenn der Titel als Argument übergeben wird (leere Zeichenfolge, falls nicht vorhanden).
Extrahieren Sie die Zeile, in der der Kategoriename im Artikel angegeben ist.
21.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 21.py
from mymodule import extract_from_json
lines = extract_from_json(u"England").split("\n")
for line in lines:
if "Category" in line:
print(line)
#Mit Python3 kann dies weiterhin angezeigt werden (obwohl es sich um eine Liste handelt).
# print([line for line in lines if "Category" in line])
Obwohl es sich um ein Kapitel über reguläre Ausdrücke handelt, werden keine regulären Ausdrücke verwendet. Nun, dieser ist leichter zu verstehen ... Daher ist nur die Zeile mit der Zeichenfolge "Kategorie" "Drucken".
Wenn Sie es in die Einschlussnotation schreiben, passt es gut, aber in Python2 wird es maskiert, wenn Sie nur eine Liste mit Unicode-Zeichenfolgen "drucken". Daher wird es nicht in einer Form angezeigt, die als Japanisch gelesen werden kann. Dieser Code kann in Python3 ausgeführt werden. Wenn Sie ihn also in Python3 ausführen, wird er gut verarbeitet.
Extrahieren Sie die Namen der Artikelkategorien (nach Namen, nicht zeilenweise).
22.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 22.py
import re
from mymodule import extract_from_json
lines = extract_from_json(u"England").split("\n")
for line in lines:
category_line = re.search("^\[\[Category:(.*?)(|\|.*)\]\]$", line)
if category_line is not None:
print(category_line.group(1))
Extrahieren Sie zuerst die Kategoriezeile auf die gleiche Weise wie in 21. und extrahieren Sie nur den Namen mit re.search ()
daraus.
re.search ()
gibt eineMatchObject
-Instanz zurück, wenn ein Teil der durch das zweite Argument angegebenen Zeichenfolge mit dem regulären Ausdrucksmuster des ersten Arguments übereinstimmt.
Abgesehen davon, wie "MatchObject" aussieht, können Sie ".group ()" verwenden, um die übereinstimmende Zeichenfolge abzurufen.
In diesem Fall in "category_line.group (0)" die gesamte übereinstimmende Zeichenfolge (z. B. "[[Kategorie: Vereinigtes Königreich | *]]"), in "category_line.group (1)" jedoch der erste übereinstimmende Teil Sie erhalten eine Zeichenfolge (z. B. "UK").
Und obwohl es sich um einen wesentlichen regulären Ausdruck handelt, werden die Details in das offizielle Dokument übernommen, und auf dieser Seite werden spezifische Anpassungsbeispiele befolgt. Ich werde es gerne versuchen. Klicken Sie hier, um die Kategoriezeile anzuzeigen, die dieses Mal verarbeitet werden soll (Ausführungsergebnis von 21.py).
22.Ausführungsergebnis von py
$ python 22.py
[[Category:England|*]]
[[Category:Königreich des Vereinigten Königreichs|*]]
[[Category:G8-Mitgliedsländer]]
[[Category:Mitgliedsländer der Europäischen Union]]
[[Category:Marine Nation]]
[[Category:Souveränes Land]]
[[Category:Inselstaat|Kureito Furiten]]
[[Category:Staat / Region gegründet 1801]]
Grundsätzlich ist es "[[Kategorie: Kategoriename]]", aber es gibt einige, die das Lesen durch Trennen mit "|" spezifizieren. Also als Politik,
[[Kategorie:
|
getrenntes Lesepseudonym.]]
Es wird in Form von sein. Dies in einem regulären Ausdruck auszudrücken (ich bin nicht sicher, ob es optimal ist) ist "^ \ [\ [Kategorie: (. *?) (\ |. *) * ] ] $" ".
Absicht | Tatsächlicher regulärer Ausdruck | Kommentar |
---|---|---|
Zuerst[[Category: Beginnt mit |
^\[\[Category: |
^Geben Sie den Anfang mit an |
Es kommt eine Art Zeichenkette (Kategoriename) | (.*?) |
Kürzeste Übereinstimmung mit einer Saite |
In manchen Fällen| Das Lesepseudonym getrennt durch |
(\|.*)* |
(\|.*)*? Kann angemessener sein |
Schließlich]] Mit festziehen |
\]\]$ |
Zeigt das Ende an$ Möglicherweise nicht erforderlich |
Zeigen Sie den im Artikel enthaltenen Abschnittsnamen und seine Ebene an (z. B. 1, wenn "== Abschnittsname ==").
23.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 23.py
import re
from mymodule import extract_from_json
lines = extract_from_json(u"England").split("\n")
for line in lines:
section_line = re.search("^(=+)\s*(.*?)\s*(=+)$", line)
if section_line is not None:
print(section_line.group(2), len(section_line.group(1)) - 1)
Die Grundstruktur ist dieselbe wie 22., aber diesmal ist der Abschnittsname (z. B. == Abschnitt ==) das Ziel, also werden wir ihn aufgreifen.
Da die Notation leicht schwankte (== section ==, == section ==), wird zwischen sie ein Leerzeichen \ s
eingefügt, damit es absorbiert werden kann.
Da die Schnittebene der Länge von ==
(== 1 ==, === 2 ===, ...) entspricht, wird sie durch Erfassen der Länge und -1 berechnet. Es ist.
Extrahieren Sie alle Mediendateien, auf die aus dem Artikel verwiesen wird.
24.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 24.py
import re
from mymodule import extract_from_json
lines = extract_from_json(u"England").split("\n")
for line in lines:
file_line = re.search(u"(File|Datei):(.*?)\|", line)
if file_line is not None:
print(file_line.group(2))
Anfangs wurden nur diejenigen extrahiert, die mit "File:" beginnen ... dumm.
Es ist "Unicode", weil Japanisch im Muster für reguläre Ausdrücke enthalten ist, aber es scheint, dass es im Python-Muster für reguläre Ausdrücke zulässig ist.
Ich sehe Beispiele für rohe Saiten oft als "r" hogehoge ", aber zumindest fühlt es sich nicht wie ein Muss an, da es verhindert, dass der Fluchtprozess dupliziert und schwer zu lesen ist?
Wenn Sie das Muster für reguläre Ausdrücke wiederholt wiederverwenden möchten, scheint es außerdem effizienter zu sein, mit re.compile ()
zu kompilieren. Das zuletzt verwendete Muster für reguläre Ausdrücke wird jedoch zwischengespeichert, sodass Sie sich diesmal keine Sorgen machen müssen.
Extrahieren Sie die Feldnamen und Werte der im Artikel enthaltenen Vorlage "Basisinformationen" und speichern Sie sie als Wörterbuchobjekt.
25.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 25.py
import re
from mymodule import extract_from_json
temp_dict = {}
lines = re.split(r"\n[\|}]", extract_from_json(u"England"))
for line in lines:
temp_line = re.search("^(.*?)\s=\s(.*)", line, re.S)
if temp_line is not None:
temp_dict[temp_line.group(1)] = temp_line.group(2)
for k, v in sorted(temp_dict.items(), key=lambda x: x[1]):
print(k, v)
Die Vorlage ~~ ist in der Form "| Vorlagenname = Vorlageninhalt" enthalten, daher handelt es sich um einen regulären Ausdruck, der mit dieser Vorlage übereinstimmt. Wie oben erwähnt, ist beim Schreiben von "^ \ | (. *?) \ S = \ s (. *)" Die erste Klammer der Vorlagenname und die zweite Klammer der Vorlageninhalt. Fügen Sie sie daher in das Wörterbuch ein. Es wird gespeichert. ~~
Grundsätzlich wird die Vorlage ** in jeder Zeile ** in Form von "| Vorlagenname = Vorlageninhalt" gespeichert, aber der offizielle Ländername war etwas problematisch.
Offizieller Ländername
|Offizieller Ländername= {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>Offizieller Ländername außer Englisch:<br/>
*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[schottisch Gälisch]])<br/>
*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[Wales]])<br/>
*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[irisch]])<br/>
*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[Cornwall]])<br/>
*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[schottisch]])<br/>
**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(Ulster Scottish)</ref>
Wie oben erwähnt, umfasst es mehrere Zeilen einschließlich Zeilenumbrüchen (Zeichen = \ n
), daher ist es notwendig, diesen Bereich gut zu behandeln.
Nach alldem
split ()
}
ist beteiligt, weil |
nicht ganz am Ende erscheint.Es wurde durch verschiedene Versuche und Irrtümer gemacht.
Ich habe for loop
to print
verwendet, um den Inhalt zu überprüfen, aber Python3 wird auch empfohlen. Python3 ist aus irgendeinem Grund nützlich ...
Entfernen Sie bei der Verarbeitung von> 25 das MediaWiki-Hervorhebungs-Markup (alle schwachen Hervorhebungen, Hervorhebungen und starken Hervorhebungen) aus dem Vorlagenwert und konvertieren Sie es in Text (Referenz: [Markup-Kurzreferenz](https: // ja. wikipedia.org/wiki/Help: Kurzreferenztabelle)).
26.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 26.py
import re
from mymodule import extract_from_json
temp_dict = {}
lines = re.split(r"\n[\|}]", extract_from_json(u"England"))
for line in lines:
temp_line = re.search("^(.*?)\s=\s(.*)", line, re.S)
if temp_line is not None:
temp_dict[temp_line.group(1)] = re.sub(r"'{2,5}", r"", temp_line.group(2))
# 25.Siehe Python3 sowie py
for k, v in sorted(temp_dict.items(), key=lambda x: x[1]):
print(k, v)
"re" ist eine Funktion, die den Teil ersetzt, der dem regulären Ausdruck entspricht. Dieses Mal schreibe ich, um 2 oder mehr und 5 oder weniger `'s zu löschen. Wenn Sie "{n, m}" schreiben, können Sie das vorherige Zeichen in einem regulären Ausdruck als n oder mehr und m oder weniger ausdrücken. ~~ Nun, ich habe das Gefühl, ich hätte dieses Mal alle "" entfernen sollen ... ~~
Entfernen Sie zusätzlich zur Verarbeitung 26 das interne Link-Markup von MediaWiki aus dem Vorlagenwert und konvertieren Sie es in Text (Referenz: [Markup-Kurzreferenz](https://ja.wikipedia.org/wiki/Help :)). Vereinfachtes Diagramm)).
27.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 27.py
import re
from mymodule import extract_from_json
def remove_markup(str):
str = re.sub(r"'{2,5}", r"", str)
str = re.sub(r"\[{2}([^|\]]+?\|)*(.+?)\]{2}", r"\2", str)
return str
temp_dict = {}
lines = extract_from_json(u"England").split("\n")
for line in lines:
category_line = re.search("^\|(.*?)\s=\s(.*)", line)
if category_line is not None:
temp_dict[category_line.group(1)] = remove_markup(category_line.group(2))
for k, v in sorted(temp_dict.items(), key=lambda x: x[0]):
print(k, v)
Ich habe eine Funktion "remove_markup ()" erstellt, die Markups entfernt.
Zeilennummer | Ziel entfernt werden |
---|---|
Die erste Zeile | Schwerpunkt (ähnlich wie 26) |
2. Zeile | Interner Link |
Wie schreibe ich interne Links
Es gibt drei Typen, aber alle entsprechen der Regel, dass "der Artikelname mit" [["beginnt und mit einem Symbol ("]] "," | "," # ") endet". Ich habe einen regulären Ausdruck geschrieben.
Entfernen Sie zusätzlich zur Verarbeitung von> 27 das MediaWiki-Markup so weit wie möglich aus dem Vorlagenwert und formatieren Sie die Basisinformationen des Landes.
28.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 28.py
import re
from mymodule import extract_from_json
def remove_markup(str):
str = re.sub(r"'{2,5}", r"", str)
str = re.sub(r"\[{2}([^|\]]+?\|)*(.+?)\]{2}", r"\2", str)
str = re.sub(r"\{{2}.+?\|.+?\|(.+?)\}{2}", r"\1 ", str)
str = re.sub(r"<.*?>", r"", str)
str = re.sub(r"\[.*?\]", r"", str)
return str
temp_dict = {}
lines = extract_from_json(u"England").split("\n")
for line in lines:
temp_line = re.search("^\|(.*?)\s=\s(.*)", line)
if temp_line is not None:
temp_dict[temp_line.group(1)] = remove_markup(temp_line.group(2))
for k, v in sorted(temp_dict.items(), key=lambda x: x[0]):
print(k, v)
Neben 27
Zeilennummer | Ziel entfernt werden |
---|---|
Die erste Zeile | Schwerpunkt (ähnlich wie 26) |
2. Zeile | Interner Link (wie 27) |
3. Zeile | Notation mit angegebener Sprache (jedoch nicht in der Markup-Tabelle) |
4. Zeile | Kommentar |
5. Zeile | Externer Link |
Schrieb remove_markup ()
um, um es zu entfernen.
Verwenden Sie den Inhalt der Vorlage, um die URL des Flaggenbilds abzurufen. (Hinweis: Rufen Sie imageinfo in der MediaWiki-API auf, um Dateiverweise in URLs zu konvertieren.)
29.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 29.py
import re
import requests
from mymodule import extract_from_json
def json_search(json_data):
ret_dict = {}
for k, v in json_data.items():
if isinstance(v, list):
for e in v:
ret_dict.update(json_search(e))
elif isinstance(v, dict):
ret_dict.update(json_search(v))
else:
ret_dict[k] = v
return ret_dict
def remove_markup(str):
str = re.sub(r"'{2,5}", r"", str)
str = re.sub(r"\[{2}([^|\]]+?\|)*(.+?)\]{2}", r"\2", str)
str = re.sub(r"\{{2}.+?\|.+?\|(.+?)\}{2}", r"\1 ", str)
str = re.sub(r"<.*?>", r"", str)
str = re.sub(r"\[.*?\]", r"", str)
return str
temp_dict = {}
lines = extract_from_json(u"England").split("\n")
for line in lines:
temp_line = re.search("^\|(.*?)\s=\s(.*)", line)
if temp_line is not None:
temp_dict[temp_line.group(1)] = remove_markup(temp_line.group(2))
url = "https://en.wikipedia.org/w/api.php"
payload = {"action": "query",
"titles": "File:{}".format(temp_dict[u"Flaggenbild"]),
"prop": "imageinfo",
"format": "json",
"iiprop": "url"}
json_data = requests.get(url, params=payload).json()
print(json_search(json_data)["url"])
Wie kann ich die API in Python aufrufen? Als ich es nachgeschlagen habe, war das ziemlich kompliziert ...
urllib
wurde traditionell verwendeturllib2
ermöglicht komplexe EinstellungenAnfragen
wurde entwickelt, weil es schwierig zu bedienen istAnfragen
steht urllib3
... Nun, aus der Schlussfolgerung scheint es, dass "Anfragen" empfohlen werden. Offizielle Dokumentation für Python 3
Für eine übergeordnete http-Client-Schnittstelle wird das Requests-Paket empfohlen.
Oder Offizielle Dokumente für Anfragen
Anfragen: HTTP für Menschen (Weggelassen) Das Standard-Modul urllib2 von Python verfügt über die meisten erforderlichen HTTP-Funktionen, die API funktioniert jedoch nicht ordnungsgemäß.
"Anfragen" wird für starken Text empfohlen.
Einzelheiten zur Verwendung finden Sie im offiziellen Dokument. Diesmal habe ich jedoch das Ergebnis erhalten, dass ich die API in JSON aufgerufen und verarbeitet habe. Die Struktur des zurückgegebenen JSON war kompliziert, daher habe ich überall gesucht und den Teil überprüft, in dem die URL geschrieben wurde.
Fahren Sie mit Kapitel 4 fort.
Recommended Posts