Weiter zum Inhalt

Machine-Learning-Modelle in Python in APIs verwandeln

Lerne, wie du mit Flask in Python eine einfache API für ein Machine-Learning-Modell erstellst.
Aktualisiert 18. Sept. 2026  · 15 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Stell dir folgende Situation vor:

Du hast ein starkes Machine-Learning-Modell gebaut, das vorhersagt, ob eine Transaktion betrügerisch ist oder nicht. Eine Freundin entwickelt gerade eine Android-App für Banking und möchte dein Modell wegen seiner Treffgenauigkeit integrieren.

Allerdings stellt sie fest: Du hast dein Modell in Python entwickelt, während ihre App in Java entsteht. Heißt das, ihr könnt das Modell nicht einbinden?

Zum Glück gibt es APIs. Und genau in solchen Fällen ist es entscheidend, Machine-Learning-Modelle als APIs bereitzustellen. Viele Unternehmen suchen Data Scientists, die das können. Ein Modell in eine API zu packen, ist gar nicht so schwer – und genau das machst du in diesem Tutorial: Mach aus deinem Machine-Learning-Modell eine API.

Optionen zur Implementierung von Machine-Learning-Modellen

In der Praxis steckt der Nutzen deines Modells oft im Herzen eines intelligenten Produkts – sei es als Baustein eines Empfehlungssystems oder eines Chatbots. Genau dann wirken die Hürden oft hoch.

Die meisten ML-Praktiker arbeiten für ihre Experimente mit R/Python. Nutzer dieser Modelle sind aber oft Softwareentwickler mit völlig anderem Tech-Stack. Es gibt zwei Lösungswege:

  • Den kompletten Code in der Sprache der Softwareentwickler neu schreiben. Klingt gut, ist aber häufig zeit- und energieaufwendig, gerade bei komplexen Modellen. Viele Sprachen wie JavaScript haben zudem keine ausgereiften ML-Bibliotheken. Davon sollte man Abstand nehmen.
  • API-first-Ansatz – Web-APIs ermöglichen saubere Zusammenarbeit über Sprachgrenzen hinweg. Benötigt ein Frontend-Entwickler dein ML-Modell, braucht er nur die URL des Endpunkts, unter dem die API läuft.

Bevor wir weitermachen: Was genau ist eigentlich eine API?

Was sind APIs?

"Einfach gesagt ist eine API ein (hypothetischer) Vertrag zwischen zwei Softwares: Liefert die Nutzer-Software Eingaben in einem vorgegebenen Format, erweitert die andere ihre Funktionalität und gibt das Ergebnis zurück." - Analytics Vidhya

Diese Artikel helfen dir zu verstehen, warum APIs bei Entwicklerinnen und Entwicklern so beliebt sind:

Im Kern ähneln APIs Webanwendungen – nur liefern sie statt hübsch gestyltem HTML Daten in standardisierten Austauschformaten wie JSON oder XML. Sobald Entwickler das gewünschte Ergebnis erhalten, können sie es beliebig weiterverarbeiten. Es gibt auch viele etablierte ML-APIs, etwa die ML-API von IBM Watson mit folgenden Fähigkeiten:

  • Maschinelle Übersetzung – Übersetzt Text zwischen verschiedenen Sprachpaaren.
  • Message Resonance – Ermittelt, wie gut Phrasen oder Wörter bei einer Zielgruppe ankommen.
  • Question and Answers – Liefert direkte Antworten auf Fragen anhand primärer Dokumentenquellen.
  • User Modeling – Sagt soziale Merkmale einer Person anhand eines Texts voraus.

Die Google Vision API ist ein weiteres starkes Beispiel mit Services für Computer Vision. Hier entlang, um zu sehen, was sich damit umsetzen lässt.

Viele Cloud-Provider und spezialisierte ML-Unternehmen bieten sofort einsetzbare APIs. Sie bedienen Entwicklerinnen, Entwickler und Unternehmen ohne tiefes ML-Know-how, die ML in Prozesse oder Produkte integrieren möchten.

Für Webentwicklung sind z. B. DialogFlow, Microsoft's Cognitive Toolkit, TensorFlow.js beliebt.

Jetzt, wo du ein gutes Bild von APIs hast, schauen wir uns an, wie du ein in Python entwickeltes Machine-Learning-Modell als API in Python bereitstellst.

Meistere deine Datenkenntnisse mit DataCamp

Mehr als 10 Millionen Menschen lernen Python, R, SQL und andere technische Fertigkeiten in unseren praxisorientierten Kursen, die von Branchenexperten entwickelt wurden.

Lernen Beginnen
learner-on-couch@2x.jpg

Flask – Ein Framework für Webservices in Python

Was ist ein Webservice? Im Grunde eine API, die auf einem Server gehostet und konsumiert werden kann. Web-API, Webservice – die Begriffe werden oft synonym verwendet.

Flask ist ein Framework für die Entwicklung von Webservices in Python. Es ist nicht das einzige – auch Django, Falcon, Hug und andere sind verbreitet. In diesem Tutorial verwenden wir Flask. Eine Einführung findest du hier.

Wenn du die Anaconda-Distribution installiert hast, ist Flask bereits dabei. Andernfalls installierst du es so:

pip install flask

Flask ist sehr schlank. Viele Python-Entwickler mögen es, weil es mit einem leichtgewichtigen integrierten Webserver kommt, der minimal konfiguriert werden muss und sich aus dem Python-Code steuern lässt. Das macht es so beliebt.

Der folgende Code zeigt die Minimalität elegant. Er erstellt eine einfache Web-API, die bei Aufruf einer bestimmten URL eine feste Antwort liefert.

from flask import Flask

app = Flask(__name__)


@app.route("")
def hello():
    return "Welcome to machine learning model APIs!"


if __name__ == '__main__':
    app.run(debug=True)

Nach dem Start rufst du im Browser die Adresse auf, die im Terminal angezeigt wird, und siehst das Ergebnis.

terminal

Wichtige Hinweise:

  • Jupyter Notebooks sind super für Markdown, R und Python-Analysen. Für das Starten eines Webservers zeigen sie aber teils unvorhersehbares Verhalten. Schreib Flask-Code daher besser in einem Editor wie Sublime und führe ihn im Terminal aus.

  • Benenne die Datei nicht flask.py.

  • Flask nutzt standardmäßig Port 5000. Manchmal startet der Server zwar auf diesem Port, aber der Aufruf der URL im Browser oder per Postman liefert nichts zurück. Beispiel:

output 1

  • Flask meldet: Server läuft auf Port 5000 – aber der Browser zeigt nichts. Das kann ein Portkonflikt sein. Ändere dann den Standardport, z. B. so:

    app.run(debug=True,port=12345)

  • Dann sieht die Serverausgabe etwa so aus:

output 2

Schauen wir uns den Code Schritt für Schritt an:

  • Du erzeugst eine Instanz der Klasse Flask und übergibst die Variable "name" (von Python gesetzt). Läuft die Datei direkt als Skript, ist ihr Wert "main". Wird sie importiert, entspricht "name" dem Modulnamen. Beispiel: Du importierst test.py in run.py, dann ist in test.py app = Flask(test).

  • Über der Definition von hello() steht @app.route(""). route() ist ein Decorator, der Flask mitteilt, welche URL die Funktion hello() auslösen soll.

  • hello() liefert die Ausgabe (Welcome to machine learning model APIs!), sobald der Endpunkt korrekt aufgerufen wird. In diesem Fall erzeugt localhost:5000/ im Browser die Ausgabe (sofern der Server auf Port 5000 läuft).

Als Nächstes betrachten wir Punkte, die beim Bereitstellen von scikit-learn-Modellen per Flask wichtig sind.

Scikit-learn-Modelle mit Flask

Mit scikit-learn war es noch nie so einfach, von sehr einfachen bis sehr komplexen ML-Modellen in Python zu kommen. Beachte dabei:

  • Scikit-learn ist eine Python-Bibliothek mit effizienten Tools für Data Mining und Datenanalyse. Zentrale Module sind:
    • Clustering
    • Regression
    • Klassifikation
    • Dimensionalitätsreduktion
    • Modellauswahl
    • Preprocessing

(Sieh dir unbedingt DataCamps Kurs Supervised Learning with scikit-learn an – unterrichtet vom Core-Entwickler von scikit-learn, Andreas Müller.)

  • Scikit-learn unterstützt die Serialisierung und Deserialisierung trainierter Modelle. So musst du nicht jedes Mal neu trainieren. Mit dem serialisierten Modell kannst du eine Flask-API schreiben.

  • Scikit-learn erwartet numerische Eingaben. Enthält dein Datensatz kategoriale, nicht-numerische Merkmale, musst du sie umwandeln. Dafür gibt es LabelEncoder, OneHotEncoder etc. im Modul sklearn.preprocessing.

  • Scikit-learn kann fehlende Werte nicht implizit verarbeiten. Kümmere dich selbst darum und füttere erst dann dein Modell. Auch hierfür bietet sklearn.preprocessing viele Utilities.

Label-Encoding und der Umgang mit fehlenden Werten sind zentrale Preprocessing-Schritte für gute Modelle. Mehr dazu im DataCamp-Kurs:

Für dieses Tutorial nutzen wir den Titanic-Datensatz – beliebt, weil er unterschiedliche Variablentypen sowie fehlende Werte enthält. Eine starke Analyse findest du in diesem DataCamp-Tutorial, den Datensatz gibt es hier.

Die Aufgabe ist eine Klassifikation: Vorhersagen, ob ein Passagier überlebt hat oder nicht – basierend auf einigen Merkmalen.

Hinweis: „Variablen“ und „Features“ werden hier synonym verwendet.

Zur Vereinfachung nutzen wir nur vier Variablen: age, sex, embarked und survived, wobei survived das Label ist.

# Import dependencies
import pandas as pd
import numpy as np
# Load the dataset in a dataframe object and include only four features as mentioned
url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/train.csv"
df = pd.read_csv(url)
include = ['Age', 'Sex', 'Embarked', 'Survived'] # Only four features
df_ = df[include]

„Sex“ und „Embarked“ sind kategorial und damit nicht-numerisch – sie brauchen also eine numerische Kodierung. „Age“ enthält fehlende Werte. Diese kannst du mit einer Kennzahl wie Median oder Mittelwert imputieren. Fehlende Werte können in realen Anwendungen aussagekräftig sein und sollten untersucht werden.

Scikit-learn behandelt leere Zellen als NaN. Hier ersetzen wir NaN schlicht durch 0 und schreiben dafür eine kleine Hilfe.

categoricals = []
for col, col_type in df_.dtypes.iteritems():
     if col_type == 'O':
          categoricals.append(col)
     else:
          df_[col].fillna(0, inplace=True)

Der Code macht Folgendes:

  • Er iteriert über alle Spalten von df und sammelt die nicht-numerischen in der Liste categorical.
  • Sind Spalten numerisch (hier nur Age), prüft er auf fehlende Werte und füllt sie mit 0.

    NaN pauschal mit einem Wert zu füllen, kann unerwünschte Effekte haben – insbesondere, wenn dieser Wert im beobachteten Wertebereich liegt. Da „0“ kein legitimes Alter ist, führst du hier keinen Bias ein – im Gegensatz zu z. B. 36! - Source

Jetzt wandelst du die nicht-numerischen Spalten in numerische um – per One-Hot-Encoding. In pandas geht das bequem mit get_dummies().

df_ohe = pd.get_dummies(df_, columns=categoricals, dummy_na=True)

Beim OHE entsteht für jede Kombination aus Spalte/Wert eine neue Spalte im Format spalte_wert. Für „Embarked“ etwa „Embarked_C“, „Embarked_Q“, „Embarked_S“ und „Embarked_nan“.

Nach dem Preprocessing kannst du das Modell trainieren – hier mit einem Logistic-Regression-Klassifikator.

from sklearn.linear_model import LogisticRegression
dependent_variable = 'Survived'
x = df_ohe[df_ohe.columns.difference([dependent_variable])]
y = df_ohe[dependent_variable]
lr = LogisticRegression()
lr.fit(x, y)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False)

Das Modell steht. Jetzt speicherst du es – sprich: du serialisierst es. In Python nennt man das Pickling.

Modell speichern: Serialisierung und Deserialisierung

Dafür nutzen wir joblib aus sklearn.

from sklearn.externals import joblib
joblib.dump(lr, 'model.pkl')
['model.pkl']

Die Logistic Regression ist jetzt persistiert. Du kannst sie mit einer Codezeile laden. Dieses Zurückladen nennt sich Deserialisierung.

lr = joblib.load('model.pkl')

Jetzt bist du bereit, Flask zu nutzen, um das persistierte Modell bereitzustellen. Du hast gesehen, wie minimal der Start ist.

Eine API aus einem Machine-Learning-Modell mit Flask erstellen

Um dein Modell mit Flask zu serven, tust du zwei Dinge:

  • Lade das persistierte Modell beim Start der Anwendung in den Speicher.
  • Erstelle einen API-Endpunkt, der Eingaben entgegennimmt, korrekt transformiert und Vorhersagen zurückgibt.

Ein Beispiel-Input an die API sieht so aus:

[
    {"Age": 85, "Sex": "male", "Embarked": "S"},
    {"Age": 24, "Sex": '"female"', "Embarked": "C"},
    {"Age": 3, "Sex": "male", "Embarked": "C"},
    {"Age": 21, "Sex": "male", "Embarked": "S"}
]

(eine JSON-list von Eingaben)

Und die API antwortet so:

{"prediction": [0, 1, 1, 0]}

Die Werte kennzeichnen den Überlebensstatus: 0 = Nein, 1 = Ja.

JSON (JavaScript Object Notation) ist eines der meistgenutzten Austauschformate. Falls du eine kurze Einführung brauchst: Hier entlang.

Schreiben wir die Funktion predict(), die Folgendes macht:

  • Lädt das persistierte Modell beim Start der Anwendung.
  • Bietet einen Endpunkt, der Eingaben entgegennimmt, korrekt transformiert und Vorhersagen liefert.

Wie man ein Modell lädt, hast du gesehen. Jetzt geht es darum, es zur Vorhersage zu nutzen.

from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
     json_ = request.json
     query_df = pd.DataFrame(json_)
     query = pd.get_dummies(query_df)
     prediction = lr.predict(query)
     return jsonify({'prediction': list(prediction)})

Super! Ein kleines Problem gibt es aber.

Die Funktion funktioniert nur, wenn die eingehende Anfrage alle möglichen Ausprägungen der kategorialen Variablen enthält – was in der Praxis selten perfekt passt. Enthält die Anfrage nicht alle möglichen Werte, erzeugt get_dummies() ein DataFrame mit weniger Spalten als der Klassifikator erwartet – Laufzeitfehler.

Die Lösung: Persistiere zusätzlich die Spaltenliste aus dem Training. Beliebige Python-Objekte kannst du als .pkl sichern – wieder mit joblib.

(Denk daran: Servercode schreibst du besser in einem Editor und startest ihn im Terminal.)

model_columns = list(x.columns)
joblib.dump(model_columns, 'model_columns.pkl')
['model_columns.pkl']

Da die Spaltenliste persistiert ist, kannst du fehlende Spalten zur Vorhersagezeit abfangen. Lade die Spalten beim App-Start.

@app.route('/predict', methods=['POST']) # Your API endpoint URL would consist /predict
def predict():
    if lr:
        try:
            json_ = request.json
            query = pd.get_dummies(pd.DataFrame(json_))
            query = query.reindex(columns=model_columns, fill_value=0)

            prediction = list(lr.predict(query))

            return jsonify({'prediction': prediction})

        except:

            return jsonify({'trace': traceback.format_exc()})
    else:
        print ('Train the model first')
        return ('No model here to use')

Damit enthält "/predict" alles Nötige – es fehlt nur noch die Main-Klasse.

if __name__ == '__main__':
    try:
        port = int(sys.argv[1]) # This is for a command-line argument
    except:
        port = 12345 # If you don't provide any port then the port will be set to 12345
    lr = joblib.load(model_file_name) # Load "model.pkl"
    print ('Model loaded')
    model_columns = joblib.load(model_columns_file_name) # Load "model_columns.pkl"
    print ('Model columns loaded')
    app.run(port=port, debug=True)

Deine API ist bereit für das Hosting. Fassen wir zusammen, was du bisher getan hast:

Alles zusammenführen

  • Du hast den Titanic-Datensatz geladen und vier Features ausgewählt.
  • Du hast das nötige Preprocessing durchgeführt.
  • Du hast eine Logistic Regression trainiert und serialisiert.
  • Du hast zusätzlich die Trainingsspalten serialisiert, um Spaltenmismatches zur Laufzeit zu vermeiden.
  • Du hast eine einfache Flask-API geschrieben, die anhand von Alter, Geschlecht und Einschiffung vorhersagt, ob eine Person überlebt hat.

Packen wir jetzt alles in zwei Dateien – gute Praxis ist, Modell- und API-Code zu trennen (.py).

Deine model.py sieht so aus:

# Import dependencies
import pandas as pd
import numpy as np

# Load the dataset in a dataframe object and include only four features as mentioned
url = "http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/train.csv"
df = pd.read_csv(url)
include = ['Age', 'Sex', 'Embarked', 'Survived'] # Only four features
df_ = df[include]

# Data Preprocessing
categoricals = []
for col, col_type in df_.dtypes.iteritems():
     if col_type == 'O':
          categoricals.append(col)
     else:
          df_[col].fillna(0, inplace=True)

df_ohe = pd.get_dummies(df_, columns=categoricals, dummy_na=True)

# Logistic Regression classifier
from sklearn.linear_model import LogisticRegression
dependent_variable = 'Survived'
x = df_ohe[df_ohe.columns.difference([dependent_variable])]
y = df_ohe[dependent_variable]
lr = LogisticRegression()
lr.fit(x, y)

# Save your model
from sklearn.externals import joblib
joblib.dump(lr, 'model.pkl')
print("Model dumped!")

# Load the model that you just saved
lr = joblib.load('model.pkl')

# Saving the data columns from training
model_columns = list(x.columns)
joblib.dump(model_columns, 'model_columns.pkl')
print("Models columns dumped!")

Deine api.py sieht so aus:

# Dependencies
from flask import Flask, request, jsonify
from sklearn.externals import joblib
import traceback
import pandas as pd
import numpy as np

# Your API definition
app = Flask(__name__)

@app.route('/predict', methods=['POST'])
def predict():
    if lr:
        try:
            json_ = request.json
            print(json_)
            query = pd.get_dummies(pd.DataFrame(json_))
            query = query.reindex(columns=model_columns, fill_value=0)

            prediction = list(lr.predict(query))

            return jsonify({'prediction': str(prediction)})

        except:

            return jsonify({'trace': traceback.format_exc()})
    else:
        print ('Train the model first')
        return ('No model here to use')

if __name__ == '__main__':
    try:
        port = int(sys.argv[1]) # This is for a command-line input
    except:
        port = 12345 # If you don't provide any port the port will be set to 12345

    lr = joblib.load("model.pkl") # Load "model.pkl"
    print ('Model loaded')
    model_columns = joblib.load("model_columns.pkl") # Load "model_columns.pkl"
    print ('Model columns loaded')

    app.run(port=port, debug=True)

Sauber! Jetzt testen wir die API mit Postman. Stell sicher, dass model.py und api.py im selben Verzeichnis liegen und beide zuvor kompiliert wurden. So sieht das Terminal nach erfolgreichem Kompilieren beider Dateien aus:

terminal 2

Wenn alles geklappt hat, sollte die Verzeichnisstruktur so aussehen:

Hinweis: Die IPYNB-Datei ist optional.

Deine API mit Postman testen

Zum Testen brauchst du einen API-Client. Postman gehört zu den besten – lade es dir einfach über den Link herunter.

So sieht die Oberfläche in der aktuellen Version aus:
postman

Nachdem der Flask-Server läuft, gibst du in Postman die korrekte URL mit Port ein. Das sieht dann so aus:

flask server

Glückwunsch! Du hast deine erste Machine-Learning-API gebaut.

Deine API sagt voraus, ob ein Passagier das Titanic-Unglück überlebt hat – basierend auf age, sex und embarked. Deine Freundin kann sie nun vom Frontend aus aufrufen und das Ergebnis weiterverarbeiten.

Und jetzt weiterdenken

In diesem Tutorial hast du eine der gefragtesten Kompetenzen eines Full-Stack-Data-Scientists umgesetzt: eine API aus einem ML-Modell zu bauen. Auch wenn die API simpel ist – es lohnt sich, mit dem Einfachsten zu starten und die Details zu verstehen.

So kannst du weitermachen:

  • Schreibe eine "/train"-API, die eine Logistic Regression mit Daten trainiert.
  • Baue ein Neural Network mit keras und stelle es als API bereit.
  • Hoste deine API in der Cloud, damit sie konsumierbar ist.
  • Für fortgeschrittene Ansätze: Dieser Blog von Machine Learning Mastery zeigt industrieerprobte Wege.

Die Möglichkeiten sind riesig. Wähle gezielt, was für dich am besten passt.

Wenn du mehr über Machine Learning in Python lernen möchtest, besuche DataCamps Kurs Preprocessing for Machine Learning in Python und lies unser Tutorial Machine Learning Basics - The Norms.

Quellen

Diese Referenzen wurden beim Schreiben genutzt:

Themen
Maschinelles Lernen
Python

Mehr über Python und Machine Learning

Kurs

Vorverarbeitung für Machine Learning in Python

4 Std.
68.3K
Lerne, wie du deine Daten für maschinelles Lernen bereinigen und vorbereiten kannst!
Details anzeigenRight Arrow
Kurs Starten
Mehr anzeigenRight Arrow