So bereiten Sie Nachrichtenartikel für die Textzusammenfassung vor
Bei der Textzusammenfassung geht es darum, eine kurze, genaue und flüssige Zusammenfassung eines Artikels zu erstellen.
Ein beliebter und kostenloser Datensatz zur Verwendung in Textzusammenfassungsexperimenten mit Deep-Learning-Methoden ist der Story-Datensatz von CNN News.
In diesem Tutorial erfahren Sie, wie Sie den CNN News-Datensatz für die Textzusammenfassung vorbereiten.
Nach Abschluss dieses Tutorials wissen Sie:
- Informationen zum CNN News-Datensatz und zum Herunterladen der Story-Daten auf Ihre Workstation.
- So laden Sie den Datensatz und teilen jeden Artikel in Story-Text und Highlights auf.
- So bereinigen Sie den Datensatz für die Modellierung und speichern die bereinigten Daten zur späteren Verwendung in einer Datei.
Starten Sie Ihr Projekt mit meinem neuen Buch „Deep Learning for Natural Language Processing“, einschließlich Schritt-für-Schritt-Anleitungen und den Python-Quellcode-Dateien für alle Beispiele.
Fangen wir an.
Tutorial-Übersicht
Dieses Tutorial ist in 5 Teile unterteilt; sie sind:
- CNN News Story-Datensatz
- Untersuchen Sie den Datensatz
- Daten laden
- Datenbereinigung
- Speichern Sie saubere Daten
CNN News Story-Datensatz
Der DeepMind Q&A-Datensatz ist eine große Sammlung von Nachrichtenartikeln von CNN und der Daily Mail mit zugehörigen Fragen.
Der Datensatz wurde als Frage-Antwort-Aufgabe für Deep Learning entwickelt und 2015 in der Arbeit „Teaching Machines to Read and Comprehend“ vorgestellt.
Dieser Datensatz wurde bei der Textzusammenfassung verwendet, bei der Sätze aus den Nachrichtenartikeln zusammengefasst werden. Bemerkenswerte Beispiele sind die Papiere:
- Abstrakte Textzusammenfassung mithilfe von Sequenz-zu-Sequenz-RNNs und darüber hinaus, 2016.
- Auf den Punkt kommen: Zusammenfassung mit Pointer-Generator-Netzwerken, 2017.
Kyunghyun Cho ist Akademiker an der New York University und hat den Datensatz zum Download bereitgestellt:
- DeepMind Q&A-Datensatz
In diesem Tutorial arbeiten wir mit dem CNN-Datensatz, insbesondere dem Download des ASCII-Textes der hier verfügbaren Nachrichten:
- cnn_stories.tgz (151 Megabyte)
Dieser Datensatz enthält mehr als 93.000 Nachrichtenartikel, wobei jeder Artikel in einer einzigen „.story“-Datei gespeichert ist.
Laden Sie diesen Datensatz auf Ihre Workstation herunter und entpacken Sie ihn. Nach dem Herunterladen können Sie das Archiv wie folgt über Ihre Befehlszeile entpacken:
tar xvf cnn_stories.tgz
Dadurch wird ein Verzeichnis cnn/stories/ erstellt, das mit Dateien .story gefüllt ist.
Beispielsweise können wir die Anzahl der Story-Dateien auf der Befehlszeile wie folgt zählen:
ls -ltr | wc -l
Das zeigt uns, dass wir insgesamt 92.580 Filialen haben.
92580
Untersuchen Sie den Datensatz
Überprüfen Sie mit einem Texteditor einige der Geschichten und notieren Sie einige Ideen für die Aufbereitung dieser Daten.
Unten sehen Sie beispielsweise ein Beispiel für eine Geschichte, wobei der Text der Kürze halber abgeschnitten ist.
(CNN) -- If you travel by plane and arriving on time makes a difference, try to book on Hawaiian Airlines. In 2012, passengers got where they needed to go without delay on the carrier more than nine times out of 10, according to a study released on Monday.
In fact, Hawaiian got even better from 2011, when it had a 92.8% on-time performance. Last year, it improved to 93.4%.
[...]
@highlight
Hawaiian Airlines again lands at No. 1 in on-time performance
@highlight
The Airline Quality Rankings Report looks at the 14 largest U.S. airlines
@highlight
ExpressJet and American Airlines had the worst on-time performance
@highlight
Virgin America had the best baggage handling; Southwest had lowest complaint rate
Ich stelle fest, dass die allgemeine Struktur des Datensatzes darin besteht, dass auf den Text der Geschichte eine Reihe von „Hervorhebungspunkten“ folgt.
Wenn ich mir Artikel auf der CNN-Website ansehe, kann ich erkennen, dass dieses Muster immer noch weit verbreitet ist.
Der ASCII-Text enthält nicht die Artikeltitel, aber wir können diese von Menschen geschriebenen „Highlights“ als mehrere Referenzzusammenfassungen für jeden Nachrichtenartikel verwenden.
Ich kann auch sehen, dass viele Artikel mit Quellenangaben beginnen, vermutlich dem CNN-Büro, das die Geschichte produziert hat; Zum Beispiel:
(CNN) --
Gaza City (CNN) --
Los Angeles (CNN) --
Diese können vollständig entfernt werden.
Die Datenbereinigung ist ein anspruchsvolles Problem und muss auf die spezifische Anwendung des Systems zugeschnitten werden.
Wenn wir allgemein daran interessiert sind, ein System zur Zusammenfassung von Nachrichtenartikeln zu entwickeln, können wir den Text bereinigen, um das Lernproblem zu vereinfachen, indem wir die Größe des Vokabulars reduzieren.
Einige Ideen zur Datenbereinigung für diese Daten umfassen:
- Normalisieren Sie die Groß- und Kleinschreibung in Kleinbuchstaben (z. B. „Ein Italiener“).
- Entfernen Sie Satzzeichen (z. B. „pünktlich“).
Wir könnten das Vokabular auch weiter reduzieren, um das Testen von Modellen zu beschleunigen, wie zum Beispiel:
- Entfernen Sie Zahlen (z. B. „93,4 %“).
- Entfernen Sie Wörter mit geringer Häufigkeit wie Namen (z. B. „Tom Watkins“).
- Geschichten auf die ersten 5 oder 10 Sätze kürzen.
Daten laden
Der erste Schritt besteht darin, die Daten zu laden.
Wir können damit beginnen, eine Funktion zu schreiben, um ein einzelnes Dokument mit einem Dateinamen zu laden. Die Daten enthalten einige Unicode-Zeichen, daher laden wir den Datensatz, indem wir die Kodierung auf UTF-8 erzwingen.
Die unten stehende Funktion mit dem Namen load_doc() lädt ein einzelnes Dokument als Text mit einem Dateinamen.
# load doc into memory
def load_doc(filename):
# open the file as read only
file = open(filename, encoding='utf-8')
# read all text
text = file.read()
# close the file
file.close()
return text
Als nächstes müssen wir jeden Dateinamen im Stories-Verzeichnis durchgehen und sie laden.
Wir können die Funktion listdir() verwenden, um alle Dateinamen im Verzeichnis zu laden und dann jeden einzelnen nacheinander zu laden. Die unten stehende Funktion mit dem Namen load_stories() implementiert dieses Verhalten und bietet einen Ausgangspunkt für die Vorbereitung der geladenen Dokumente.
# load all stories in a directory
def load_stories(directory):
for name in listdir(directory):
filename = directory + '/' + name
# load document
doc = load_doc(filename)
Jedes Dokument kann in den Nachrichtentext und den Highlights- oder Zusammenfassungstext unterteilt werden.
Die Aufteilung für diese beiden Punkte ist das erste Vorkommen des Tokens „@highlight“. Nach der Aufteilung können wir die Highlights in einer Liste organisieren.
Die unten stehende Funktion mit dem Namen split_story() implementiert dieses Verhalten und teilt einen bestimmten geladenen Dokumenttext in eine Story und eine Liste mit Highlights auf.
# split a document into news story and highlights
def split_story(doc):
# find first highlight
index = doc.find('@highlight')
# split into story and highlights
story, highlights = doc[:index], doc[index:].split('@highlight')
# strip extra white space around each highlight
highlights = [h.strip() for h in highlights if len(h) > 0]
return story, highlights
Wir können jetzt die Funktion load_stories() aktualisieren, um die Funktion split_story() für jedes geladene Dokument aufzurufen und die Ergebnisse dann in einer Liste zu speichern.
# load all stories in a directory
def load_stories(directory):
all_stories = list()
for name in listdir(directory):
filename = directory + '/' + name
# load document
doc = load_doc(filename)
# split into story and highlights
story, highlights = split_story(doc)
# store
all_stories.append({'story':story, 'highlights':highlights})
return all_stories
Zusammenfassend ist unten das vollständige Beispiel für das Laden des gesamten Datensatzes aufgeführt.
from os import listdir
# load doc into memory
def load_doc(filename):
# open the file as read only
file = open(filename, encoding='utf-8')
# read all text
text = file.read()
# close the file
file.close()
return text
# split a document into news story and highlights
def split_story(doc):
# find first highlight
index = doc.find('@highlight')
# split into story and highlights
story, highlights = doc[:index], doc[index:].split('@highlight')
# strip extra white space around each highlight
highlights = [h.strip() for h in highlights if len(h) > 0]
return story, highlights
# load all stories in a directory
def load_stories(directory):
stories = list()
for name in listdir(directory):
filename = directory + '/' + name
# load document
doc = load_doc(filename)
# split into story and highlights
story, highlights = split_story(doc)
# store
stories.append({'story':story, 'highlights':highlights})
return stories
# load stories
directory = 'cnn/stories/'
stories = load_stories(directory)
print('Loaded Stories %d' % len(stories))
Wenn Sie das Beispiel ausführen, wird die Anzahl der geladenen Storys gedruckt.
Loaded Stories 92,579
Wir können nun auf die geladene Story zugreifen und Daten hervorheben, zum Beispiel:
print(stories[4]['story'])
print(stories[4]['highlights'])
Datenbereinigung
Nachdem wir nun die Story-Daten laden können, können wir den Text vorbearbeiten, indem wir ihn bereinigen.
Wir können die Storys Zeile für Zeile verarbeiten und für jede Hervorhebungszeile dieselben Reinigungsvorgänge verwenden.
Für eine bestimmte Zeile führen wir die folgenden Operationen aus:
Entfernen Sie die CNN-Büroinformationen.
# strip source cnn office if it exists
index = line.find('(CNN) -- ')
if index > -1:
line = line[index+len('(CNN)'):]
Teilen Sie die Zeile mit Leerzeichen auf:
# tokenize on white space
line = line.split()
Normalisieren Sie die Groß- und Kleinschreibung.
# convert to lower case
line = [word.lower() for word in line]
Entfernen Sie alle Satzzeichen von jedem Token (Python 3-spezifisch).
# prepare a translation table to remove punctuation
table = str.maketrans('', '', string.punctuation)
# remove punctuation from each token
line = [w.translate(table) for w in line]
Entfernen Sie alle Wörter, die nicht alphabetische Zeichen enthalten.
# remove tokens with numbers in them
line = [word for word in line if word.isalpha()]
Zusammenfassend sehen Sie unten eine neue Funktion namens clean_lines(), die eine Liste mit Textzeilen entgegennimmt und eine Liste mit sauberen Textzeilen zurückgibt.
# clean a list of lines
def clean_lines(lines):
cleaned = list()
# prepare a translation table to remove punctuation
table = str.maketrans('', '', string.punctuation)
for line in lines:
# strip source cnn office if it exists
index = line.find('(CNN) -- ')
if index > -1:
line = line[index+len('(CNN)'):]
# tokenize on white space
line = line.split()
# convert to lower case
line = [word.lower() for word in line]
# remove punctuation from each token
line = [w.translate(table) for w in line]
# remove tokens with numbers in them
line = [word for word in line if word.isalpha()]
# store as string
cleaned.append(' '.join(line))
# remove empty strings
cleaned = [c for c in cleaned if len(c) > 0]
return cleaned
Wir können dies als eine Geschichte bezeichnen, indem wir sie zunächst in eine Textzeile umwandeln. Die Funktion kann direkt auf der Liste der Highlights aufgerufen werden.
example['story'] = clean_lines(example['story'].split('\n'))
example['highlights'] = clean_lines(example['highlights'])
Das vollständige Beispiel für das Laden und Bereinigen des Datensatzes ist unten aufgeführt.
from os import listdir
import string
# load doc into memory
def load_doc(filename):
# open the file as read only
file = open(filename, encoding='utf-8')
# read all text
text = file.read()
# close the file
file.close()
return text
# split a document into news story and highlights
def split_story(doc):
# find first highlight
index = doc.find('@highlight')
# split into story and highlights
story, highlights = doc[:index], doc[index:].split('@highlight')
# strip extra white space around each highlight
highlights = [h.strip() for h in highlights if len(h) > 0]
return story, highlights
# load all stories in a directory
def load_stories(directory):
stories = list()
for name in listdir(directory):
filename = directory + '/' + name
# load document
doc = load_doc(filename)
# split into story and highlights
story, highlights = split_story(doc)
# store
stories.append({'story':story, 'highlights':highlights})
return stories
# clean a list of lines
def clean_lines(lines):
cleaned = list()
# prepare a translation table to remove punctuation
table = str.maketrans('', '', string.punctuation)
for line in lines:
# strip source cnn office if it exists
index = line.find('(CNN) -- ')
if index > -1:
line = line[index+len('(CNN)'):]
# tokenize on white space
line = line.split()
# convert to lower case
line = [word.lower() for word in line]
# remove punctuation from each token
line = [w.translate(table) for w in line]
# remove tokens with numbers in them
line = [word for word in line if word.isalpha()]
# store as string
cleaned.append(' '.join(line))
# remove empty strings
cleaned = [c for c in cleaned if len(c) > 0]
return cleaned
# load stories
directory = 'cnn/stories/'
stories = load_stories(directory)
print('Loaded Stories %d' % len(stories))
# clean stories
for example in stories:
example['story'] = clean_lines(example['story'].split('\n'))
example['highlights'] = clean_lines(example['highlights'])
Beachten Sie, dass die Geschichte jetzt als Liste klarer Zeilen gespeichert ist, die nominell durch Sätze getrennt sind.
Speichern Sie saubere Daten
Nachdem die Daten nun bereinigt wurden, können wir sie schließlich in einer Datei speichern.
Eine einfache Möglichkeit, die bereinigten Daten zu speichern, besteht darin, die Liste der Geschichten und Highlights auszuwählen.
Zum Beispiel:
# save to file
from pickle import dump
dump(stories, open('cnn_dataset.pkl', 'wb'))
Dadurch wird eine neue Datei namens cnn_dataset.pkl mit allen bereinigten Daten erstellt. Diese Datei wird etwa 374 Megabyte groß sein.
Wir können es dann später laden und wie folgt mit einem Textzusammenfassungsmodell verwenden:
# load from file
stories = load(open('cnn_dataset.pkl', 'rb'))
print('Loaded Stories %d' % len(stories))
Weiterführende Literatur
In diesem Abschnitt finden Sie weitere Ressourcen zum Thema, wenn Sie tiefer gehen möchten.
- DeepMind Q&A-Datensatz
- Maschinen das Lesen und Verstehen beibringen, 2015.
- Abstrakte Textzusammenfassung mithilfe von Sequenz-zu-Sequenz-RNNs und darüber hinaus, 2016.
- Auf den Punkt kommen: Zusammenfassung mit Pointer-Generator-Netzwerken, 2017.
Zusammenfassung
In diesem Tutorial haben Sie erfahren, wie Sie den CNN News-Datensatz für die Textzusammenfassung vorbereiten.
Konkret haben Sie gelernt:
- Informationen zum CNN News-Datensatz und zum Herunterladen der Story-Daten auf Ihre Workstation.
- So laden Sie den Datensatz und teilen jeden Artikel in Story-Text und Highlights auf.
- So bereinigen Sie den Datensatz für die Modellierung und speichern die bereinigten Daten zur späteren Verwendung in einer Datei.
Haben Sie Fragen?
Stellen Sie Ihre Fragen in den Kommentaren unten und ich werde mein Bestes tun, um sie zu beantworten.