Maschinelles Lernen mit Python
Thomas Proisl
2015-09-16
Professur für Korpuslinguistik
Überblick
Ziele dieses Tutorials
• Mini-Einführung in maschinelles Lernen
• Problemstellungen
• Lernverfahren
• Vorgehensweisen
• Machine learning demystified
• Funktionsweise eines einfachen Klassifikationsverfahrens
• Merkmalsextraktion
• Bag-of-words model
• DARIAH NLP-Pipeline
• Maschinelles Lernen mit scikit-learn
• Klassifikation
• Clustering
• Folien und Quellcode und Beispieldaten online verfügbar:
http://www.linguistik.fau.de/~tsproisl/share/Maschinelles_
Lernen_mit_Python.zip
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
3
Maschinelles Lernen – was ist das?
Maschinelles Lernen (ML)
Maschinelle Lernverfahren können überall eingesetzt werden, wo „Wissen“
aus Daten gewonnen werden kann:
• Spielen (Backgammon, Dame)
• Erkennen gesprochener Sprache (Diktiersoftware, Komponenten in
sprachgesteuerter Software)
• Astronomische Strukturen klassifizieren
• Kreditkartenbetrug erkennen
• Zielgruppenspezifische Werbung anzeigen
• Trends an den Finanzmärkten vorhersagen
• Krankheiten diagnostizieren
• Auto fahren (Google Self-Driving Car)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
5
ML für textuelle Daten
• Maschinelle Lernverfahren operieren auf Merkmalen von Texten1 um
Aussagen über die Eigenschaften von unbekannten Texten machen zu
können.
• Dafür werden Texte in der Regel als Vektoren quantifizierbarer Merkmale
betrachtet (→ Merkmalsextraktion).
Grobe Übersicht über typische Problemstellungen:
• Überwachtes Lernen (supervised learning)
• Klassifikation
• Regression
• Unüberwachtes Lernen (unsupervised learning)
• Clustering
• Dimensionsreduktion
1
Text: Alle textuellen Daten, vom ganzen Roman bis hin zu einzelnen Absätzen oder Sätzen
2015-09-16
| Thomas Proisl |
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
6
Überwachtes Lernen
Wir haben annotierte Trainingsdaten und wollen weitere Daten automatisch
annotieren.
Klassifikation: Es handelt sich um kategorische Annotation, d.h. jeder
Trainingstext ist einer Kategorie oder Klasse zugeordnet. Beispiele:
Sprache, Autor, Genre
Regression: Es handelt sich um numerische Annotation, d.h. jedem
Trainingstext ist eine Zahl zugeordnet. Beispiele: Bewertungen,
Noten, Polarität
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
7
Unüberwachtes Lernen
Wir haben unannotierte Daten und wollen Strukturen darin finden.
Clustering: Entdecken von Gruppen ähnlicher Texte, bspw. Texte des
gleichen Autors, inhaltlich ähnliche Texte
Dimensionsreduktion: Hochdimensionale Repräsentation der Texte in einen
niederdimensionalen Raum projizieren, bspw. für Visualisierung,
topic modelling
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
8
Vorgehensweise bei überwachtem Lernen
1. Daten sammeln und annotieren
2. Daten in ein Trainingsset und ein Testset aufteilen
3. Quantifizierbare Merkmale aus Daten extrahieren
4. Abhängig von Art der Annotation, Anzahl der Merkmale und Menge der
Trainingsdaten ein Lernverfahren auswählen
5. Lernverfahren auf Trainingsdaten trainieren (lernen); Ergebnis: Modell
6. Modell auf Testset anwenden und prognostizierte Annotation mit
tatsächlicher Annotation vergleichen (evaluieren)
7. Modell auf unbekannte Daten anwenden
Anstelle von Trainings- und Testset kann auch Kreuzvalidierung verwendet
werden.
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
9
Vorgehensweise bei Clustering
1. Daten sammeln
2. Quantifizierbare Merkmale aus Daten extrahieren
3. Abhängig von Eigenschaften des gewünschten Clusterings, Anzahl der
Merkmale und Menge der Trainingsdaten ein Clusteringverfahren
auswählen
4. Daten clustern; Ergebnis: Clustering und Modell
5. Optional: Modell auf unbekannte Daten anwenden
Evaluation: Clustern von annotierten Daten
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
10
Welche Art von Lernverfahren eignet sich für welches der
folgende Szenarien?
• Wir haben eine Menge von Filmrezensionen, die eine Gesamtbewertung
des Films mit einer Schulnote zwischen 1 und 6 enthalten. Wir möchten
eine Sammlung alter Filmrezensionen automatisch mit einer solchen
Gesamtbewertung versehen.
• Wir möchten automatisch erkennen, ob es sich bei einer E-Mail um Spam
handelt.
• Bei einer Mitarbeiterumfrage wird in einem Freitextfeld nach dem
Kantinenessen gefragt. Wir möchten automatisch die Zufriedenheit der
Mitarbeiter erkennen.
• Wir möchten den wahren Autor eines unter Pseudonym geschriebenen
Romans herausfinden.
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
11
Scikit-learn cheat-sheet
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
12
Naive Bayes: Ein sehr einfacher Klassifikator
Bedingte Wahrscheinlichkeiten und der Satz von Bayes (1)
Spam
• Wir haben 75 Emails
• 30 von 75 Mails sind Spam als markiert
• 50 von 75 Mails enthalten das Wort
„Viagra“
• 20 Mails, die das Wort „Viagra“
enthalten, sind als Spam markiert
Viagra
• Frage: Wie hoch ist die
Wahrscheinlichkeit, dass eine neue
Mail, die das Wort „Viagra“ enthält,
eine Spammail ist?
P (A|B ) =
2015-09-16
| Thomas Proisl |
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
P (A ∩ B )
P (B |A)P (A)
=
P (B )
P (B )
14
Bedingte Wahrscheinlichkeiten und der Satz von Bayes (2)
• Antwort:
P (Viagra|Spam) · P (Spam)
P (Viagra)
20 30
·
30
75
=
50
75
20
=
50
= 0.4
• Wir schätzen die Wahrscheinlichkeiten aus den Daten (relative
Häufigkeiten).
• Simples Beispiel, für das wir den Satz von Bayes eigentlich noch nicht
gebraucht hätten.
P (Spam|Viagra) =
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
15
Bedingte Wahrscheinlichkeiten und der Satz von Bayes (3)
• Je mehr Wörter wir betrachten (= Merkmale), desto komplexere bedingte
Wahrscheinlichkeiten müssen wir abschätzen:
P (Spam|Viagra) =
P (Spam|Viagra, Sex) =
P (Spam|Viagra, Sex, Penis) =
P (Viagra|Spam)P (Spam)
P (Viagra)
P (Sex|Spam, Viagra)P (Viagra|Spam)P (Spam)
P (Sex|Viagra)P (Viagra)
P (Penis|Spam, Viagra, Sex)P (Sex|Spam, Viagra)P (Viagra|Spam)P (Spam)
P (Penis|Viagra, Sex)P (Sex|Viagra)P (Viagra)
• Jedes zusätzliche Wort steigert die Komplexität der Berechnung.
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
16
Naive-Bayes-Annahme
• Vereinfachende Annahme (Naive-Bayes-Annahme): Vorkommen von
Wörtern sind vollkommen unabhängig voneinander.
• Berechnung wird einfacher:
P (Viagra|Spam)P (Sex|Spam)P (Penis|Spam)
P (Spam|Viagra, Sex, Penis) =
P (Viagra)P (Sex)P (Penis)
• Zum Abschätzen der Wahrscheinlichkeiten müssen wir nur
Worthäufigkeiten in Klassen bestimmen.
• Annahme ist zwar offensichtlich falsch, darauf aufbauende Klassifikation
funktioniert aber überraschend gut.
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
17
Naive-Bayes-Klassifikator
• Grundlegende Idee: Wir ordnen einen Text der wahrscheinlichsten
Kategorie zu:
P (Spam|Viagra, Sex, Penis) =
P (Viagra|Spam)P (Sex|Spam)P (Penis|Spam)
P (Viagra)P (Sex)P (Penis)
P (Ham|Viagra, Sex, Penis) =
P (Viagra|Ham)P (Sex|Ham)P (Penis|Ham)
P (Viagra)P (Sex)P (Penis)
• Nenner ist für alle Kategorien gleich und kann weggelassen werden.
• Naive-Bayes-Klassifikator verwendet die Wörter eines Textes.
• Für jede mögliche Kategorie: Multiplikation der relativen Häufigkeiten
dieser Wörter in den Trainingsdaten
• Zuordnung der Kategorie mit dem höchsten Wert
• „Lernen“ ist die Abschätzung der bedingten Wahrscheinlichkeiten aus den
Trainingsdaten
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
18
Merkmalsextraktion
Das Bag-of-words-Modell (1)
• Maschinelle Lernverfahren operieren in der Regel auf Vektoren von
numerischen Merkmalen.
• Wir müssen unsere Texte also durch quantifizierbare Merkmale
repräsentieren.
• Einfachste Methode ist das Bag-of-words-Modell:
• Annahme: Ein Text ist eine ungeordnete Menge von Wörtern, d.h. genaue
Position oder Reihenfolge der Wörter kann vernachlässigt werden.
• Ausschlaggebend ist nur die Häufigkeit der Wörter.
• Text wird auf seine Frequenzliste reduziert.
Beispiel 1
Der Satz „Rose is a rose is a rose is a rose“ wird, unter Vernachlässigung
der Groß-/Kleinschreibung, so dargestellt:
{"a": 3, "is": 3, "rose": 4}
2015-09-16
| Thomas Proisl |
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
20
Das Bag-of-words-Modell (2)
• Die Sätze „Der Hund beißt den Mann“ und „Der Mann beißt den Hund“
sind für das Bag-of-words-Modell identisch.
• Einfache Erweiterung, die ein klein wenig Syntax in das Modell bringt:
Verwendung von N-Grammen.
Beispiel 3
Durch Hinzunahme von Bigrammen können die beiden Sätze unterschieden
werden:
{"beißt": 1,
"der hund":
{"beißt": 1,
"der mann":
2015-09-16
"den": 1, "der":
1, "hund beißt":
"den": 1, "der":
1, "mann beißt":
| Thomas Proisl |
Professur für Korpuslinguistik
|
1,
1,
1,
1,
"hund": 1, "mann": 1,
"beißt den": 1, "den mann": 1}
"hund": 1, "mann": 1,
"beißt den": 1, "den hund": 1}
Maschinelles Lernen mit Python
21
Wie kann der Output der DARIAH NLP-Pipeline integriert
werden?
Annotationsebenen:
• Segmentierung:
• Absätze
• Sätze
• Tokens
• Linguistische Annotation:
•
•
•
•
•
•
Lemmata
Part-of-Speech-Tags und vereinfachte POS-Tags
Morphologie: Kasus, Numerus, Genus, Person, . . .
Dependenzstruktur
Named Entities
Konstituentenstruktur
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
22
Ein paar Ideen
• Lemmata anstatt oder zusätzlich zu Tokens
• Filtern nach POS-Tag (bspw. nur Inhaltswörter)
• Häufigkeiten von POS-Tags
• Häufigkeiten von Named Entities
• Häufigkeiten von bestimmten morphologischen Informationen, bspw. für
Verben Person und Numerus, Tempus
• Kombination von Lemma und vereinfachtem POS-Tag: „der_ART“,
„hund_NN“, „beißen_V“, „der_ART“, „mann_NN“
• Kombination von bestimmten Lemmata mit bestimmten morphologischen
Informationen, bspw. Numerus für alle Substantive: „mann_sg“
• Über Dependenzrelation verbundene Tokens an Stelle von Bigrammen:
„hund der“, „beißt hund“, „beißt mann“, „mann den“
• Optional mit Label: „NK(hund, der)“, „SB(beißt, hund)“, „OA(beißt, mann)“,
„OA(mann, den)“
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
23
Weitere einfach zu extrahierende Merkmale
• Häufigkeiten von bestimmten Interpunktionszeichen (!?)
• Häufigkeit von wörtlicher Rede
• Durchschnittliche Satz- und Absatzlänge
• Type-Token-Verhältnis
• Verhältnis von Interpunktionszeichen zu Wörtern
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
24
Maschinelles Lernen mit scikit-learn
Installation
• Installationsanweisungen unter
http://scikit-learn.org/stable/install.html, bspw.:
pip install -U numpy scipy scikit-learn
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
26
Datenorganisation
• Für unsere Beispiele: Alle Texte einer Klasse in einem Unterverzeichnis;
Verzeichnisname = Klassenname; Dateiname egal
Daten/
|-- Klasse_1
| |-- 01.txt
| |-- 02.txt
| ‘-- 03.txt
|-- Klasse_2
| |-- 04.txt
| |-- 05.txt
| ‘-- 06.txt
|-- Klasse_3
| |-- 07.txt
| |-- 08.txt
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
27
Unser Spielzeugdatenset
• Je acht Romane von sechs verschiedenen Autoren
• Plaintext (8x6)
• Ausgabe der DARIAH NLP-Pipeline (8x6_output)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
28
Laden der Daten
• Datenset laden, dabei Kodierung richtig angeben:
from sklearn.datasets import load_files
corpus = load_files("data/8x6", encoding="utf-8")
• corpus ist ein „Bunch“, eine Menge von Datenfeldern:
•
•
•
•
filenames: Liste der Dateinamen (reproduzierbar gemischt)
data: Liste von Strings mit den Dateiinhalten
target_names: Liste der Namen aller Klassen
target: Liste der den Dateien zugeordneten Klassen
• Liste der Felder:
print(corpus.keys())
• Kann als Dictionary oder als Objekt angesprochen werden:
print(corpus["target_names"])
print(corpus.target)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
29
Aufteilung in Trainings- und Testset
• Reproduzierbare Aufteilung in ein Trainings- und Testset
• n_iter: Anzahl der verschiedenen Aufteilungen; wir wollen nur eine
• test_size: Welcher Anteil der Daten soll zum Testen verwendet werden (50%)
• random_state: Wenn nicht None ist die Aufteilung reproduzierbar
from sklearn.cross_validation import StratifiedShuffleSplit
sss = StratifiedShuffleSplit(corpus.target, n_iter=1, test_size=0.5, random_state=0)
• sss ist ein Iterator, uns interessiert nur die erste mögliche Aufteilung:
train_index, test_index = list(sss)[0]
• data und target aufteilen (corpus.target ist ein numpy Array):
data_train = [corpus.data[_] for _ in train_index]
data_test = [corpus.data[_] for _ in test_index]
target_train = corpus.target[train_index]
target_test = corpus.target[test_index]
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
30
Merkmalsextraktion
• Tokenisierung und Bag-of-words-Modell
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
data_train_counts = count_vect.fit_transform(data_train)
• Relative statt absolute Häufigkeiten (term-frequencies)
• norm="l1": Termfrequenzen summieren sich zu 1
• norm="l2": Dokumentvektor hat die euklidische Länge 1 (Standardwert)
from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer(norm="l2", use_idf=False)
data_train_tfidf = tfidf_transformer.fit_transform(data_train_counts)
• Testdaten transformieren (transform() statt fit_transform()!)
data_test_counts = count_vect.transform(data_test)
data_test_tfidf = tfidf_transformer.transform(data_test_counts)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
31
Tf-Idf
• Abkürzung für term frequency-inverse document frequency
• tf : Häufigkeit eines Wortes in einem Text
• df : In wie vielen Texten kommt ein Wort vor
• idf = Anzahldf Texte
• Intuition: Ein Wort ist wichtig für einen Text, wenn es in diesem Text oft
vorkommt (hohe tf ), und unwichtig, wenn es selten vorkommt (niedrige tf .
Ein Wort ist wichtig (spezifisch), wenn es in wenigen Texten vorkommt
(hohe idf ), und unwichtig wenn es in vielen verschiedenen oder allen
Texten vorkommt (niedrige idf ).
• Multiplikation von tf und idf
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
32
Klassifikator trainieren und evaluieren
• Naive-Bayes-Klassifikator trainieren:
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB()
clf.fit(data_train_tfidf, target_train)
• Testdaten klassifizieren:
predicted = clf.predict(data_test_tfidf)
• Ergebnis evaluieren:
from sklearn import metrics
print(metrics.accuracy_score(target_test, predicted))
print(metrics.classification_report(target_test, predicted,
target_names=corpus.target_names))
print(metrics.confusion_matrix(target_test, predicted))
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
33
Schnittstellen sind immer gleich
• fit(): Modell wird angepasst
• transform(): Modell wird auf Daten angewandt
• fit_transform(): Kombination von fit() und transform()
• predict(): Anstelle von transform() bei Lernern
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
34
Pipelines
Pipelines
• Mit Pipelines können mehrere Verarbeitungsschritte einfach kombiniert
werden.
• Pipeline konfigurieren:
text_clf = Pipeline([(’vect’, CountVectorizer()),
(’tfidf’, TfidfTransformer(norm="l2", use_idf=False)),
(’clf’, MultinomialNB()),
])
• Pipeline trainieren:
text_clf.fit(data_train, target_train)
• Testdaten klassifizieren:
predicted = text_clf.predict(data_test)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
36
Komponenten hinzufügen und austauschen
• Einzelne Komponenten können dank einheitlicher Schnittstellen leicht
hinzugefügt oder ausgetauscht werden.
• Naive Bayes kommt nicht gut mit extrem vielen Merkmalen zurecht,
Beschränkung auf 200 beste Merkmale:
text_clf = Pipeline([(’vect’, CountVectorizer()),
(’tfidf’, TfidfTransformer(norm="l2", use_idf=False)),
(’kbest’, SelectKBest(chi2, k=200)),
(’clf’, MultinomialNB()),
])
• SVMs kommen gut mit sehr vielen Merkmalen zurecht: Verwenden von
Uni- und Bigrammen, lineare Support Vector Machine:
from sklearn.svm import LinearSVC
text_clf = Pipeline([(’vect’, CountVectorizer(ngram_range=(1, 2))),
(’tfidf’, TfidfTransformer(norm="l2", use_idf=False)),
(’clf’, LinearSVC()),
])
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
37
Verwendung der DARIAH NLP-Pipeline
• Das Ausgabeformat muss geparst werden:
class DARIAHAnnotationExtractor(BaseEstimator, TransformerMixin):
"""Convert tab-separated values with header line to dict of columns"""
def fit(self, x, y=None):
return self
def transform(self, texts):
features = collections.defaultdict(list)
for text in texts:
# parse tsv format (list of rows)
table = [[c for c in r.split("\t")] for r in text.splitlines()]
# extract header line
header = table[0]
# convert to list of columns
columns = list(zip(*table[1:]))
# store in dict
for name, column in zip(header, columns):
features[name].append(column)
return features
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
38
Kombination von Merkmalen
• Verwendung von beliebigen Tupeln von Merkmalen (auch 1-Tupel):
class FeatureCombiner(BaseEstimator, TransformerMixin):
"""Convert to dictionary of feature tuples"""
def __init__(self, keys=[]):
self.keys = keys
def fit(self, x, y=None):
return self
def transform(self, data_dict):
# extract desired columns (features)
columns = [data_dict[k] for k in self.keys]
# combine features into tuples
return [collections.Counter(zip(*text)) for text in zip(*columns)]
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
39
Beispielpipelines
• Bag-of-words-Modell mit Tokens:
text_clf = Pipeline([(’extractor’, DARIAHAnnotationExtractor()),
(’combiner’, FeatureCombiner(["Token"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer()),
(’clf’, LinearSVC()),
])
• Hier mit (Lemma, CPOS)-Tupeln (Kombination von Lemma und CPOS in
ein einziges Merkmal):
text_clf = Pipeline([(’extractor’, DARIAHAnnotationExtractor()),
(’combiner’, FeatureCombiner(["Lemma", "CPOS"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer()),
(’clf’, LinearSVC()),
])
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
40
FeatureUnion (1)
• FeatureUnion kombiniert mehrere unabhängige Transformer in einen
• Transformer werden unabhängig voneinander ausgeführt, Ausgabe wird
konkateniert
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
41
FeatureUnion (2)
text_clf = Pipeline([(’extractor’, DARIAHAnnotationExtractor()),
(’union’, FeatureUnion(
transformer_list=[
# Bag-of-words-Modell
(’bow’, Pipeline([
(’combiner’, FeatureCombiner(["Lemma", "CPOS"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer()),
])),
# POS-Tags
(’bopos’, Pipeline([
(’combiner’, FeatureCombiner(["POS"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer(use_idf=False)),
])),
])),
(’normalizer’, Normalizer()),
(’clf’, LinearSVC()),
])
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
42
Verwendung von Dependenzrelationen (1)
• Wir wollen Tripel bestehend aus Dependenzrelation, Governor und
Dependent
• Eigene Transformer-Klasse erstellen:
class DependencyTupleCombiner(BaseEstimator, TransformerMixin):
"""Convert to dictionary of (relation, governor, dependent) tuples"""
def __init__(self, lemma=True):
self.lemma = lemma
def fit(self, x, y=None):
return self
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
43
Verwendung von Dependenzrelationen (2)
• Fortsetzung:
def transform(self, data_dict):
features = []
# use tokens or lemmata
lemma_or_token = "Lemma" if self.lemma else "Token"
# extract necessary columns
columns = [data_dict[k] for k in ["TokenId", lemma_or_token,
"DependencyHead", "DependencyRelation"]]
for text in zip(*columns):
# convert to rows
rows = list(zip(*text))
# do some arithmetic and extract token/lemma for DependencyHead
dependency_tuples = [(r[3], rows[i + (int(r[2]) - int(r[0]))][1], r[1])
for i, r in enumerate(rows) if r[2] != "_"]
features.append(collections.Counter(dependency_tuples))
return features
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
44
Clustering
k-Means (1)
• Daten müssen nur geladen werden, Aufteilung in Trainings- und Testset
nicht zwingend nötig:
corpus = load_files("data/8x6_output", encoding="utf-8")
• Anstelle eines Klassifikators kann ein Clusterverfahren in die Pipeline
eingebunden werden, bspw. k-Means.
• k-Means teilt die Daten in k Gruppen auf, d.h. Anzahl der Cluster muss
vorher bekannt sein (oder durch Probieren gefunden werden).
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
46
k-Means (2)
text_clst = Pipeline([(’extractor’, DARIAHAnnotationExtractor()),
(’union’, FeatureUnion(
transformer_list=[
# Bag-of-words-Modell
(’bow’, Pipeline([
(’combiner’, FeatureCombiner(["Lemma", "CPOS"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer()),
])),
# POS-Tags
(’bopos’, Pipeline([
(’combiner’, FeatureCombiner(["POS"])),
(’vect’, DictVectorizer()),
(’tfidf’, TfidfTransformer(use_idf=False)),
])),
])),
(’normalizer’, Normalizer()),
(’clst’, KMeans(n_clusters=6))
])
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
47
Hierarchisches Clustering
• Anfangs ist jeder Text in einem eigenen Cluster.
• Schrittweise werden die ähnlichsten Cluster verschmolzen.
• Verschiedene Ähnlichkeitsmaße möglich.
• Implementierung in scikit-learn verlangt vorgegebene Anzahl Cluster
(scipy.cluster.hierarchy kann auch explorativ verwendet werden).
• AgglomerativeClustering()
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
48
Delta-Maße
• Auswahl der n häufigsten Wörter, Skalierung ($z$-Werte), optional
Normalisierung, Abstandsmaß
• Burrows’s Delta: Keine Normalisierung, Manhattan-Distanz
• Burrows’s Delta mit Vektornormalisierung: L1-Normalisierung,
Manhattan-Distanz
• Cosine Delta: Keine Normalisierung, Cosinus-Distanz
AgglomerativeClustering(n_clusters=6, affinity="cosine", linkage="complete")
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
49
Visualisierung mit matplotlib (1)
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
50
Visualisierung mit matplotlib (2)
• Zweidimensionale Repräsentation der Daten durch Multidimensional
Scaling (MDS); MDS versucht euklidische Abstände beizubehalten:
from sklearn import manifold
twodim = manifold.MDS().fit_transform(data)
• Daten plotten; Farben markieren Cluster, Beschriftungen tatsächliche
Klassen:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter(twodim[:, 0], twodim[:, 1], c=clusters)
for i, target in enumerate(corpus.target):
ax.annotate(corpus.target_names[target].split(",")[0],
(twodim[:, 0][i], twodim[:, 1][i]), fontsize="small")
plt.savefig("clustering.png")
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
51
Weitere Features von scikit-learn
Features
• Merkmalsextraktion: CountVectorizer kann weitreichend konfiguriert
werden
• Merkmalsauswahl: Varianz, rekursive Merkmalseliminierung,
Merkmalsauswahl mit Hilfe linearer Modelle (bspw. lineare SVM)
• Dimensionsreduktion: Hauptkomponentenanalyse (PCA), Manifold
Learning
• Weitere überwachte Lernverfahren: Generalisierte lineare Modelle,
Diskriminanzanalyse, SVMs mit verschiedenen Kerneln, Nearest
Neighbors, Entscheidungsbäume, . . .
• Ensemble-Methoden um mehrere überwachte Modelle zu kombinieren,
bspw. Random Forests
• Kreuzvalidierung
• Parameter Tuning: Systematisches Durchprobieren von
Parameterkombinationen mit GridSearchCV
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
53
Andere interessante Module
• gensim für Topic Modelling: Latent Semantic Indexing, Latent Dirichlet
Allocation, Hierarchical Dirichlet Processes, Deep Learning (word2vec,
paragraph2vec)
• matplotlib für die Visualisierung
• PyStruct für strukturiertes Lernen
• seqlearn für Sequenzklassifikation
2015-09-16
|
Thomas Proisl
|
Professur für Korpuslinguistik
|
Maschinelles Lernen mit Python
54