Machine Learning: Theorie

Themen

  • Ãœberblick über Methoden
  • Libraries
  • Ãœberblick über Verfahren im Machine Learning
  • Algorithmen für Ãœberwachtes Lernen
  • Vorbereiten von Daten
  • Trainieren eines Modells
  • Validieren eines Modells

Überblick über Methoden

Überblick über Methoden

  • Supervised learning (überwachtes Lernen)
    • Regression
    • Klassifizierung
  • Unsupervised learning
    • Clustering
    • Dimensionsreduktion / Komprimierung
  • Reinforcement learning
    • Optimierung

Regression

Zuweisung von numerischen Werten zu numerischen Eingabedaten

Beispiele:

  • Schätzung der Entfernung einer Galaxie basierend auf der Rotverschiebung
  • Schätzung der Kursentwicklung einer Aktie

Klassifizierung

Zuweisung von Klassen zu numerischen Eingabedaten

Beispiele:

  • Spam-Filterung basierend auf einer Anzahl an Wörtern / Phrasen
  • Erkennen von Objekten / Personen / Zeichen auf Bildern
  • Diagnose von Krankheiten basierend auf Symptomen / Messwerten

Clustering

Erkennen von Gruppierungen / Clustern bei numerischen Eingabedaten

Beispiele:

  • Erkennen wiederkehrender Elemente in Bildern

Dimensionality Reduction

Vereinfachung von Daten mit einer großen Anzahl an Merkmalen zu Daten mit weniger, aber aussagekräftigeren Merkmalen

Reinforcement Learning

Optimieren von Strategien in einer Simulation

Beispiele:

  • Simulieren des Verlaufs einer Krankheit, Finden der besten Behandlungsstrategie

Beispiele für Datensätze und Aufgaben

Beispiele für Datensätze und Aufgaben

Mögliche Aufgaben

  • Bilddaten: z.B. Objekterkennung, Gesichtserkennung, Handschrifterkennung
  • Textdaten: z.B. Sentimentanalyse
  • Sprachdaten: z.B. Spracherkennung

Oft verwendete Datensätze

Libraries

Libraries

Python Libraries für Machine Learning:

  • scikit-learn
  • keras
  • pytorch

Libraries

scikit-learn:

  • unterstützt viele verschiedene Algorithmenklassen (auch sehr einfache neuronale Netzwerke)
  • basiert auf NumPy

keras:

  • unterstützt neuronale Netzwerke
  • basiert auf der TensorFlow-Bibliothek
  • kann auch auf der GPU oder TPU (Tensor Processing Unit) laufen

pytorch:

  • unterstützt neuronale Netzwerke
  • low-level

Ãœberwachtes Lernen

Ãœberwachtes Lernen: Verfahren

Schritte:

  • Sammeln und Vorbereiten von Trainingsdaten (Eingangsdaten und zugehörigen Ausgangsdaten)
  • Trainieren eines Algorithmus basierend auf den Eingangs- und Ausgangsdaten
  • Validieren der Richtigkeit / Qualität der Vorhersagen des Algorithmus
  • Verwenden des Algorithmus, um Outputs für neue Daten zu erzeugen

Ãœberwachtes Lernen: Verfahren

in scikit-learn:

  • Erstelle eine Eingangsmatrix (oft x oder X) und eines Zielvektors / einer Zielmatrix (oft y oder Y)
  • Instanziiere eine Algorithmenklasse, z.B. KNeighborsClassifier, MLPClassifier, LinearRegression, ...
  • "Lerne" mittels model.fit(x, y)
  • Validiere mittels model.score(x_val, y_val) oder metrics.accuracy_score(x_val, y_val), ...
  • Sage weitere Ergebnisse voraus mittels model.predict(...) oder model.predict_proba(...)

Ãœberwachtes Lernen: Verfahren

in keras:

  • Erstelle ein Eingangs-Array (x) und ein Ziel-Array (y)
  • Erstelle ein Modell aus verschiedenen Layern (z.B. Preprocessing-Layer, Neuronen-Layer, ...)
  • Kompiliere via model.compile() und "Lernen" via model.fit(x, y)
  • Validiere via model.evaluate(x_val, y_val)
  • Sage weitere Werte vorher via model.predict(...)

Iris Datensatz

Iris Datensatz

Iris Datensatz: einfacher Beispieldatensatz für Machine Learning / Data Science

Beinhaltet Abmessungen von 150 Iris-Pflanzen (Schwertlilien): 3 verschiedene Spezies mit je 50 Einträgen

Iris Datensatz

Eigenschaften im Datensatz:

  • sepal length
  • sepal width
  • petal length
  • petal width
  • species name

Iris Datensatz

Beispiel CSV-Daten von http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data:

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
...
7.0,3.2,4.7,1.4,Iris-versicolor
...
6.3,3.3,6.0,2.5,Iris-virginica
...

Beispiel: Iris-Klassifikation

Beispiel: Iris-Klassifikation

Aufgabe: trainiere einen Algorithmus, um Iris-Pflanzen basierend auf ihren Abmessungen zu klassifizieren

Daten laden

# load data via pandas
iris = pd.read_csv(
    "http://archive.ics.uci.edu/ml/" +
    "machine-learning-databases/iris/iris.data",
    header=None,
    names=["sepal_length", "sepal_width", "petal_length",
           "petal_width", "species"]
)

Daten vorbereiten

iris_shuffled = iris.sample(frac=1.0)

# convert to numerical numpy arrays
measurements = iris_shuffled[[
    "sepal_length",
    "sepal_width",
    "petal_length",
    "petal_width",
]].to_numpy()
species = (
    iris_shuffled["species"]
    .replace({
        "Iris-setosa": 0,
        "Iris-versicolor": 1,
        "Iris-virginica": 2,
    })
    .to_numpy()
)

Erstellen eines Modells in scikit-learn

from sklearn.neighbors import KNeighborsClassifier

model = KNeighborsClassifier()

Erstellen eines Modells in keras

from tensorflow import keras

model = keras.Sequential([
    keras.layers.Dense(8),
    keras.layers.Activation("relu"),
    keras.layers.Dense(3),
    keras.layers.Activation("softmax")
])
model.compile(
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]
)

Erstellen eines Modells via NumPy

class NearestNeighborClassifier():
    def fit(self, x, y):
        # In a "real" machine learning algorithm,
        #   a lot of processing could happen here.
        # In this case we're just storing the training data.
        self.x = x
        self.y = y

    def predict_single(self, x):
        vectors = self.x - x
        distances = np.linalg.norm(vectors, axis=1)
        min_index = np.argmin(distances)
        return self.y[min_index]

model = NearestNeighborClassifier()

Trainieren des Modells

Trainieren basierend auf den ersten 130 Einträgen:

in scikit-learn:

model.fit(measurements[:130], species[:130])

in keras:

model.fit(
    measurements[:130],
    species[:130],
    epochs=300,
    validation_split=0.1
)

Verwenden des Modells

Anwenden der Klassifikation auf neue Daten (in scikit-learn):

demo_measurements = np.array([
    [5.3, 3.4, 1.9, 0.6],
    [6.0, 3.0, 4.7, 1.5],
    [6.5, 3.1, 5.0, 1.7]
])

model.predict(demo_measurements)
# e.g. [0, 1, 1] in scikit-learn

model.predict_proba(demo_measurements)
# [[0.9 0.1 0. ]
#  [0.  0.8 0.2]
#  [0.  0.7 0.3]]

Evaluieren des Modells

measurements_val = measurements[130:]
species_val = species[130:]

in scikit-learn (accuracy):

print(model.score(measurements_val, species_val))

in keras (categorical crossentropy, accuracy):

print(model.evaluate(measurements_val, species_val))

Algorithmen für überwachtes Lernen

Algorithmen für überwachtes Lernen

Regression:

  • neuronale Netzwerke
  • lineare Regression, polynomiale Regression, ...

Klassifizierung:

  • neuronale Netzwerke
  • k-nearest-neighbors
  • Entscheidungsbäume (decision trees)
  • logistische Regression
  • naive Bayes
  • Support Vector Machines

Lineare Regression

Regression

Lineare Regression: Festlegen einer linearen Funktion, die die Datenpunkte bestmöglich approximiert (kleinste Quadratsumme)

Lineare Regression

Beispiel: Wir betrachten verschiedene Einkäufe bei verschiedenen Supermärkten:

  • 1 l Milch, 1 kg Brot: 5.00€
  • 2 l Milch, 3 kg Brot: 13.50€
  • 3 l Milch, 2 kg Brot: 10.90€
  • (0 l Milch, 0 kg Brot: 0€)

Aufgabe: Schätzung der Preise von:

  • 1 l Milch
  • 1 kg Brot
  • 1 l Milch und 2 kg Brot

Diese Aufgabe kann mit Hilfe von Regression beantwortet werden.

Lineare Regression

Eingangsdaten:

1, 1 → 5.00
2, 3 → 13.50
3, 2 → 10.90
0, 0 → 0.00

Ergebnis einer linearen Regression:

price = 0.05 + 1.13*x + 3.73*y

Neuronale Netzwerke

Neuronale Netzwerke

Machine Learning Verfahren, das in etwa die Interaktion von Neuronen im Gehirn nachahmt

Neuronale Netzwerke

image/svg+xml
Diagrammm eines neuronalen Netzwerks mit zwei Inputs, fünf Neuronen in der Zwischenschicht und einem Output (Quelle: Dake, Mysid via Wikimedia Commons / CC BY)

Neuronen

Modell eines einzelnen Neurons mit mehreren Inputs und einem Output

Aktivierungsfunktionen

  • ReLU (Rectified Linear Unit)
  • Softmax - oft im letzen Layer für Klassifikation verwendet
  • Sigmoid - oft im letzen Layer für "Tagging" verwendet (Tags können sich überlappen)

Demo

Ressource

Klassifizierungsalgorithmen

Klassifizierungsalgorithmen

  • neuronale Netzwerke
  • k-nearest-neighbors
  • Entscheidungsbäume (decision trees)
  • logistische Regression
  • naive Bayes
  • Support Vector Machines

K-Nearest-Neighbors

Um einen Datenpunkt zu klassifizieren, werden ähnliche bekannte Datenpunkte betrachtet, für die schon eine Klassifizierung bekannt ist

Entscheidungsbäume (Decision Trees)

Beispiel für die Iris-Klassifizierung:

  • Ist die petal length kleiner oder gleich 2.4?
    • ja: setosa
    • nein: Ist die petal width kleiner oder gleich 1.7?
      • ja: Ist die petal length kleiner oder gleich 5.0?
        • ja: versicolor
        • nein: virginica
      • nein: virginica

Logistische Regression

An einer Grenze zwischen zwei Klassen wird mit Hilfe einer logistischen Funktion angegeben, wie groß die Wahrscheinlichkeit ist, dass der Datenpunkt zu der einen bzw zu der anderen Klasse gehört.

Die logistische Funktion selbst wird intern mittels Regression bestimmt (daher der Name).

Naive Bayes

Für die bekannten Klassen werden Wahrscheinlichkeitsverteilungen angenommen (z.B. Normalverteilung, Multinomialverteilung). Diese Verteilungen werden aus den Trainingsdaten hergeleitet.

Für einen neuen Datenpunkt wird dann errechnet, unter welcher der Verteilungen er am ehesten auftreten würde.

Zwei wichtige Verteilungen:

  • Normalverteilung oder Gauß'sche Verteilung (für kontinuierliche Werte)
  • Multinomialverteilung (für diskrete Werte / Ganzzahlen)

Support Vector Machines

Einfachster Fall: Trennung von Klassen durch Geraden / Ebenen / Hyperebenen - diese Trenner sollen von den getrennten Punkten maximalen Abstand haben.

Durch Kernelfunktionen können die Grenzen auch andere Formen annehmen, z.B. die von Kegelschnitten für polynomiale Kernel vom Grad 2 oder anderen Kurven.

Klassifizierungsalgorithmen

Überblick über Klassifizierungsalgorithmen in scikit-learn

Beispiel: Iris-Klassifizierung mit verschiedenen Algorithmen

Beispiel: Iris-Klassifizierung mit verschiedenen Algorithmen

Aufgabe: verwende andere Klassifizierungsalgorithmen in scikit-learn, z.B.:

  • sklearn.tree.DecisionTreeClassifier
  • sklearn.svm.SVC
  • sklearn.naive_bayes.GaussianNB
  • sklearn.neural_network.MLPClassifier

Daten vorbereiten

Daten vorbereiten

erwünschtes Datenformat für Machine Learning Algorithmen:

  • x oder X: zweidimensionales Array mit numerischen Eingangsdaten
  • y oder Y: ein- oder zweidimensionales Array mit numerischen Resultaten

Daten vorbereiten

Aufgaben:

  • "Flattening" von verschachtelten Daten
  • Skalieren von Werten
  • Fehlende Daten ergänzen
  • Kategoriedaten in numerische Daten umwandeln
  • Textdaten in numerische Daten umwandeln

Skalieren von Werten

Welcher dieser beiden Sterne ist der Sonne am ähnlichsten?

# data: radius (km), mass (kg), temparature (K)
sun =    [7.0e7, 2.0e30, 5.8e3]

star_a = [6.5e7, 2.2e30, 5.2e3]
star_b = [7.0e8, 2.1e30, 8.1e3]

manche Machine Learning Algorithmen wie z.B. k-Nearest-Neighbor betrachten Absolutwerte.

Hier würde vom Algorithmus im wesentlichen nur die Masse herangezogen werden, da alle anderen Werte im Vergleich verschwindend gering sind.

Skalieren von Werten

Lösung: Bevor ein Algorithmus angewendet wird, werden die Werte zentriert und skaliert (z.B. so, dass ihr Mittelwert 0 und ihre Standardabweichung 1 sind)

Fehlende Daten

Fehlende Daten werden häufig in der Form von NaNs auftreten.

Mögliche Behandlungen:

  • Löschen aller Zeilen, die an irgendeiner Stelle undefinierte Werte enthalten
  • Interpolieren der fehlenden Werte durch andere Daten

Kategorien als Daten

Manchmals: Kategorien als Eingangs- oder Ausgangsdaten - z.B. Land, Berufsgruppe, Messverfahren, ...

Beispiel für Eingangsdaten:

[["fr", "chrome"], ["uk", "chrome"], ["us", "firefox"]]

oftmals als Strings angegeben, Kodierung als Zahlen gewünscht

Kategorien als Daten

Eingangsdaten:

[["fr", "chrome"], ["uk", "chrome"], ["us", "firefox"]]

Kodierung als Ordinale (nicht für alle Algorithmen geeignet, da implizit geordnet (fr=0, uk=1, us=2)):

[[0., 0.], [1., 0.], [2., 1.]]

Kategorien als Daten

Eingangsdaten:

[["fr", "chrome"],
 ["uk", "chrome"],
 ["us", "firefox"]]

One-Hot-Kodierung:

# fr?, uk?, us?, chrome?, firefox?
[[1., 0., 0., 1., 0.],
 [0., 1., 0., 1., 0.],
 [0., 0., 1., 0., 1.]]

Textdaten

Beispiel für Preprocessing für Textklassifikation: Zählen von Wörtern

Beispiel: Laden und Vorbereiten von Daten

Laden von Daten

iris = pd.read_csv(
    "http://archive.ics.uci.edu/ml/" +
    "machine-learning-databases/iris/iris.data",
    header=None)
iris_measures = iris.iloc[:, :4].to_numpy()
iris_species = iris.iloc[:, 4].to_numpy()

Vorbereiten von Daten

encoder = LabelBinarizer()
encoder.fit(iris_species)
iris_species_one_hot = encoder.transform(iris_species)
scaler = StandardScaler()
scaler.fit(iris_measures)
iris_measures_scaled = scaler.transform(iris_measures)
x = iris_measures_scaled
y = iris_species_one_hot

Modellvalidierung und -auswahl

Trainingsdaten und Validierungsdaten

Um zu validieren, ob ein Verfahren ein passendes Ergebnis liefert:

Die Daten werden in Trainingsdaten und Validierungsdaten unterteilt

Trainingsdaten und Validierungsdaten

für iterative Algorithmen (z.B. Neuronale Netzwerke in keras):

  • Trainingsdaten
  • Testdaten (während iterativem Training verwendet)
  • Validierungsdaten (zur Validierung des fertigen Modells)

für andere Algorithmen (z.B. sklearn):

  • Trainingsdaten
  • Validierungsdaten oder Testdaten (zur Validierung des Modells)

Modellvalidierung und -auswahl

Um das bestmögliche Modell zu bestimmen:

  • Testen mehrerer Algorithmen
  • Testen mehrerer Parameter für den Algorithmus
  • Testen, ob mehr Lerndaten zu besseren Ergebnissen führen

siehe Python Data Science Handbook → Hyperparameters and Model Validation → Selecting the Best Model

Grundlegende Validierungsmetriken

Grundlegende Validierungsmetriken

Klassifizierungsmetriken:

  • accuracy (Anteil an richtig klassifizierten Elementen)
  • confusion matrix

Regressionsmetriken:

  • mittlere quadratische Abweichung
  • Bestimmtheitsmaß (R²)

Validierungsmetriken für Klassifizierung

Beispiel:

Ein Korb von Früchten enthält 10 Äpfel, 10 Orangen und 10 Pfirsiche

Ein Klassifizierungsalgorithmus liefert diese Ergebnisse:

  • Klassifizierung von Äpfeln: 8 als Äpfel, 0 als Orangen, 2 als Pfirsiche
  • Klassifizierung von Orangen: 10 als Orangen
  • Klassifizierung von Pfirsichen: 1 als Apfel, 0 als Orangen, 9 als Pfirsiche

Klassifizierungsmetriken

accuracy: relativer Anteil korrekter Klassifizierungen (im Beispiel: 27/30=0.9)

confusion matrix: Tabelle mit Klassifizierungen für jede Kategorie

applesorangespeaches
apples802
oranges0100
peaches109

Regressionsmetriken

mittlere quadratische Abweichung

Bestimmtheitsmaß (R²):

vergleicht die mittlere quadratische Abweichung der Regression mit der Varianz der Eingangsdaten

  • R²=1 - perfekte Interpolation
  • R²=0 - Interpolation ist nicht besser als das Verwenden des Durchschnitts
  • R²<0 - schlechter als das Verwenden des Durchschnitts

Klassifizierungsmetriken

Klassifizierungsmetriken

  • accuracy metrics
    • accuracy
    • confusion matrix
  • Metriken, die auf true/false positives/negatives basieren
    • precision
    • recall
    • f-score
    • ROC und AUC
  • probabilistische Metriken
    • Kreuzentropie

Metriken, die auf true/false positives/negatives basieren

Binäre Klassifizierung: Spam-Erkennung

  • true positive: eine Spam-Nachricht wird als Spam klassifiziert
  • true negative: eine normale Nachricht wird als kein Spam klassifiziert
  • false positive: eine normale Nachricht wird als Spam klassifiziert (Fehler erster Art)
  • false negative: eine Spam-Nachricht wird als kein Spam klassifiziert (Fehler zweiter Art)

Metriken, die auf true/false positives/negatives basieren

Beispiele:

60 normale Nachrichten, 40 Spam-Nachrichten

1 normale Nachricht wird als Spam klassifiziert

5 Spam-Nachrichten werden als normal klassifiziert

precision (Genauigkeit) = 36/36=0.97 (35 von 36 Nachrichten, die als Spam Klassifiziert wuerden, sind tatsächlich Spam)

recall (Trefferquote) = 35/40 = 0.88 (35 von 40 Spam-Nachrichten wurden als solche erkannt)

siehe auch: Precision and recall auf der englischsprachigen Wikipedia

Metriken, die auf true/false positives/negatives basieren

precision und recall haben unterschiedliche Relevanz in verschiedenen Szenarien

Beispiel: Beim Klassifizieren von E-mails als Spam ist precision besonders wichtig (vermeiden, eine E-mail fälschlicherweise als Spam zu klassifizieren)

Metriken, die auf true/false positives/negatives basieren

f-score = harmonisches Mittel zwischen precision und recall

Metriken, die auf true/false positives/negatives basieren

ROC (Receiver Operating Characteristic)

= Metrik, die true positives und false positives wiederspiegelt

Ein Klassifizierungsalgorithmus könnte bezüglich seiner true positives-Quote und false positives-Quote fein eingestellt werden:

  • Option 1: 60% true positives-Quote, 0% false positives-Quote
  • Option 2: 70% true positives-Quote, 5% false positives-Quote
  • Option 3: 80% true positives-Quote, 25% false positives-Quote
  • Option 4: 90% true positives-Quote, 55% false positives-Quote
  • Option 5: 95% true positives-Quote, 90% false positives-Quote

Metriken, die auf true/false positives/negatives basieren

Die ROC kann als Kurve dargestellt werden; je größer die Fläche unter der Kurve (area under the curve, AUC), desto besser die Klassifikation

Probabilistische Metriken

Kreuzentropie (log loss): Misst, wie gut ein Modell einer Wahrscheinlichkeitsverteilung die tatsächliche Wahrscheinlichkeitsverteilung annähert

relevant bei neuronalen Netzwerken und logistischer Regression

Overfitting

Overfitting

Mögliches Problem beim Lernen: Der Algorithmus ist zu flexibel und erkennt scheinbare Muster in den Eingangsdaten, hinter denen aber keine Systematik steckt

Algorithmen, die anfällig für Overfitting sind:

  • Neuronale Netze
  • Polynomiale Regression
  • Entscheidungsbäume

Overfitting

visualization of an algorithm overfitting 2D data
Visualisierung von Overfitting bei der Kategorisierung von 2D-Daten (Quelle: Chabacano via Wikimedia Commons / CC BY)

Overfitting - Lösungsmöglichkeiten

  • größere Menge an Daten zum Lernen
  • Einschränkung der Flexibilität (z.B. Grad des Polynoms, Tiefe des Entscheidungsbaums)
  • zufälliges Deaktivieren einiger Neuronen während des Lernens (Dropout)
  • Kombination mehrerer Entscheidungsbäume (Random Forest)
  • "Bestrafung" großer Koeffizienten bei der polynomialen Regression (L2- und L1-Regularisierung)

Zur polynomialen Regression siehe: Data Science Handbook - Regularization

Beispiel: Iris-Validierung in scikit-learn

Beispiel: Iris-Validierung in scikit-learn

Manueller train-test Split:

rng = np.random.default_rng(seed=1)

random_indexes = rng.permutation(x.shape[0])
# e.g. [65, 44, 22, 133, 47, ...]

x_train = x[random_indexes[:120]]
y_train = y[random_indexes[:120]]

x_test = x[random_indexes[120:]]
y_test = y[random_indexes[120:]]

Beispiel: Iris-Validierung in scikit-learn

Automatische Unterteilung vis scikit-learn:

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y)

Beispiel: Iris-Validierung in scikit-learn

Validierung basierend auf den Testdaten:

from sklearn import metrics

y_prediction = model.predict(x_test)
score = metrics.accuracy_score(y_prediction, y_test)
print("accuracy:", score)

Iris-Klassifikation in scikit-learn - komplett

Iris-Klassifikation - komplett

import pandas as pd
from sklearn.preprocessing import (
    LabelBinarizer,
    StandardScaler,
)
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics

# loading data

iris = pd.read_csv(
    "http://archive.ics.uci.edu/ml/" +
    "machine-learning-databases/iris/iris.data",
    header=None)
iris_measures = iris.iloc[:, :4].to_numpy()
iris_species = iris.iloc[:, 4].to_numpy()

# preparing data

encoder = LabelBinarizer()
encoder.fit(iris_species)
iris_species_one_hot = encoder.transform(iris_species)

scaler = StandardScaler()
scaler.fit(iris_measures)
iris_measures_scaled = scaler.transform(iris_measures)

X = iris_measures_scaled
Y = iris_species_one_hot

# train-test-split

X_train, X_test, Y_train, Y_test = train_test_split(X, Y)

# training

model = KNeighborsClassifier()
model.fit(X_train, Y_train)

# validation

Y_prediction = model.predict(X_test)
score = metrics.accuracy_score(Y_prediction, Y_test)
print("accuracy: ", score)

# predicting further species

new_iris_data = [
    [5.3, 3.4, 1.9, 0.6],
    [6.0, 3.0, 4.7, 1.5],
    [6.5, 3.1, 5.0, 1.7]
]
new_iris_predictions = model.predict(
    scaler.transform(new_iris_data)
)
print("prediction data:")
print(new_iris_predictions)
predicted_labels = encoder.inverse_transform(
    new_iris_predictions
)
print("predicted labels:")
print(predicted_labels)