Auf der Cloud AI Platform bereitgestelltes ML-Modell mit dem What-if-Tool analysieren

1. Übersicht

In diesem Lab verwenden Sie das What-If-Tool, um ein XGBoost-Modell zu analysieren, das mit Finanzdaten trainiert und auf der Cloud AI Platform bereitgestellt wurde.

Lerninhalte

Die folgenden Themen werden behandelt:

  • XGBoost-Modell mit einem öffentlichen Hypotheken-Dataset in AI Platform Notebooks trainieren
  • XGBoost-Modell in AI Platform bereitstellen
  • Modell mit dem What-if-Tool analysieren

Die Gesamtkosten für das Lab in Google Cloud belaufen sich auf 1$.

2. Eine kurze Einführung in XGBoost

XGBoost ist ein Framework für maschinelles Lernen, das Entscheidungsbäume und Gradient-Boosting verwendet, um Vorhersagemodelle zu erstellen. Dabei werden mehrere Entscheidungsbäume basierend auf dem Wert zusammengefasst, der den verschiedenen Blattknoten in einem Baum zugeordnet ist.

Das folgende Diagramm zeigt eine Visualisierung eines einfachen Entscheidungsbaummodells, das anhand der Wettervorhersage auswertet, ob ein Sportspiel ausgetragen werden soll:

308a0bfc70733abf.png

Warum verwenden wir XGBoost für dieses Modell? Während traditionelle neuronale Netzwerke nachweislich am besten mit unstrukturierten Daten wie Bildern und Text funktionieren, funktionieren Entscheidungsbäume häufig sehr gut mit strukturierten Daten wie dem Hypotheken-Dataset, das wir in diesem Codelab verwenden werden.

3. Richten Sie Ihre Umgebung ein.

Sie benötigen ein Google Cloud Platform-Projekt mit aktivierter Abrechnung, um dieses Codelab auszuführen. Folgen Sie dieser Anleitung, um ein Projekt zu erstellen.

Schritt 1: Cloud AI Platform Models API aktivieren

Rufen Sie in der Cloud Console den Bereich AI Platform-Modelle auf und klicken Sie auf „Aktivieren“, falls die Option noch nicht aktiviert ist.

d0d38662851c6af3.png

Schritt 2: Compute Engine API aktivieren

Gehen Sie zu Compute Engine und wählen Sie Aktivieren aus, falls dies noch nicht geschehen ist. Sie benötigen dies zum Erstellen Ihrer Notebookinstanz.

Schritt 3: AI Platform Notebooks-Instanz erstellen

Rufen Sie in der Cloud Console den Bereich AI Platform Notebooks auf und klicken Sie auf Neue Instanz. Wählen Sie dann den neuesten TF Enterprise 2.x-Instanztyp ohne GPUs aus:

7d16190440ab2e9c.png

Verwenden Sie die Standardoptionen und klicken Sie dann auf Erstellen. Nachdem die Instanz erstellt wurde, wählen Sie JupyterLab öffnen aus:

772f8868d3841ba0.png

Schritt 4: XGBoost installieren

Nachdem die JupyterLab-Instanz geöffnet wurde, müssen Sie das XGBoost-Paket hinzufügen.

Wählen Sie dazu im Launcher „Terminal“ aus:

28dcf2790ce77c96.png

Führen Sie dann den folgenden Befehl aus, um die neueste von der Cloud AI Platform unterstützte Version von XGBoost zu installieren:

pip3 install xgboost==0.90

Öffnen Sie anschließend eine Python 3-Notebookinstanz im Launcher. Jetzt können Sie in Ihrem Notizbuch loslegen.

Schritt 5: Python-Pakete importieren

Fügen Sie in der ersten Zelle Ihres Notebooks die folgenden Importe hinzu und führen Sie die Zelle aus. Sie können ihn ausführen, indem Sie im oberen Menü den Rechtspfeil oder Befehlstaste + Eingabetaste drücken:

import pandas as pd
import xgboost as xgb
import numpy as np
import collections
import witwidget

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.utils import shuffle
from witwidget.notebook.visualization import WitWidget, WitConfigBuilder

4. Daten herunterladen und verarbeiten

Wir verwenden ein Hypotheken-Dataset von ffiec.gov, um ein XGBoost-Modell zu trainieren. Wir haben das ursprüngliche Dataset vorverarbeitet und eine kleinere Version erstellt, die Sie zum Trainieren des Modells verwenden können. Das Modell prognostiziert, ob ein bestimmter Hypothekenantrag genehmigt wird oder nicht.

Schritt 1: Vorverarbeitetes Dataset herunterladen

Wir haben eine Version des Datasets in Google Cloud Storage für Sie verfügbar gemacht. Sie können es herunterladen, indem Sie den folgenden gsutil-Befehl in Ihrem Jupyter-Notebook ausführen:

!gsutil cp 'gs://mortgage_dataset_files/mortgage-small.csv' .

Schritt 2: Dataset mit Pandas lesen

Bevor wir den Pandas-DataFrame erstellen, erstellen wir ein Dictionary für den Datentyp jeder Spalte, damit Pandas das Dataset korrekt liest:

COLUMN_NAMES = collections.OrderedDict({
 'as_of_year': np.int16,
 'agency_code': 'category',
 'loan_type': 'category',
 'property_type': 'category',
 'loan_purpose': 'category',
 'occupancy': np.int8,
 'loan_amt_thousands': np.float64,
 'preapproval': 'category',
 'county_code': np.float64,
 'applicant_income_thousands': np.float64,
 'purchaser_type': 'category',
 'hoepa_status': 'category',
 'lien_status': 'category',
 'population': np.float64,
 'ffiec_median_fam_income': np.float64,
 'tract_to_msa_income_pct': np.float64,
 'num_owner_occupied_units': np.float64,
 'num_1_to_4_family_units': np.float64,
 'approved': np.int8
})

Als Nächstes erstellen wir einen DataFrame und übergeben ihm die oben angegebenen Datentypen. Es ist wichtig, die Daten nach dem Zufallsprinzip zu mischen, falls das ursprüngliche Dataset auf eine bestimmte Weise angeordnet ist. Dazu verwenden wir ein sklearn-Dienstprogramm namens shuffle, das wir in die erste Zelle importiert haben:

data = pd.read_csv(
 'mortgage-small.csv',
 index_col=False,
 dtype=COLUMN_NAMES
)
data = data.dropna()
data = shuffle(data, random_state=2)
data.head()

Mit data.head() können wir eine Vorschau der ersten fünf Zeilen des Datasets in Pandas anzeigen lassen. Nach dem Ausführen der Zelle oben sollte in etwa Folgendes angezeigt werden:

29106b71103235a6.png

Mit diesen Features trainieren wir unser Modell. Wenn Sie ganz bis zum Ende scrollen, sehen Sie die letzte Spalte approved. Das ist das Ergebnis, das wir vorhersagen. Der Wert 1 bedeutet, dass ein bestimmter Antrag genehmigt wurde, und 0, dass er abgelehnt wurde.

Führen Sie folgenden Befehl aus, um die Verteilung der genehmigten / abgelehnten Werte im Dataset zu sehen und ein NumPy-Array der Labels zu erstellen:

# Class labels - 0: denied, 1: approved
print(data['approved'].value_counts())

labels = data['approved'].values
data = data.drop(columns=['approved'])

Etwa 66% des Datasets enthält genehmigte Bewerbungen.

Schritt 3: Dummy-Spalte für kategoriale Werte erstellen

Dieses Dataset enthält eine Mischung aus kategorialen und numerischen Werten. Für XGBoost müssen jedoch alle Funktionen numerisch sein. Anstelle der Darstellung kategorialer Werte mit der One-Hot-Codierung nutzen wir für unser XGBoost-Modell die Pandas-Funktion get_dummies.

get_dummies wandelt eine Spalte mit mehreren möglichen Werten in eine Reihe von Spalten um, die jeweils nur Nullen und Einsen enthalten. Hätten wir z. B. die Spalte „Farbe“ für „Farbe“ mit den möglichen Werten "blue" und „Rot“, get_dummies würde dies in zwei Spalten namens „color_blue“ umwandeln und „color_red“ mit allen booleschen Werten 0 und 1.

Führen Sie den folgenden Code aus, um Dummy-Spalten für unsere kategorialen Features zu erstellen:

dummy_columns = list(data.dtypes[data.dtypes == 'category'].index)
data = pd.get_dummies(data, columns=dummy_columns)

data.head()

Wenn Sie sich diesmal die Daten in der Vorschau ansehen, werden Sie feststellen, dass einzelne Elemente (wie unten abgebildet purchaser_type) in mehrere Spalten aufgeteilt sind:

83aacfaad626e538.png

Schritt 4: Daten in Trainings- und Test-Datasets aufteilen

Ein wichtiges Konzept beim maschinellen Lernen ist die Trainings-/Testaufteilung. Wir nehmen den Großteil unserer Daten zum Trainieren unseres Modells und räumen den Rest ein, um unser Modell mit Daten zu testen, die es zuvor noch nicht gesehen hat.

Fügen Sie Ihrem Notebook den folgenden Code hinzu, der die Scikit Learn-Funktion train_test_split verwendet, um unsere Daten aufzuteilen:

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

Jetzt können Sie Ihr Modell erstellen und trainieren.

5. XGBoost-Modell erstellen, trainieren und bewerten

Schritt 1: XGBoost-Modell definieren und trainieren

Das Erstellen eines Modells in XGBoost ist einfach. Wir verwenden die XGBClassifier-Klasse, um das Modell zu erstellen, und müssen für unsere spezifische Klassifizierungsaufgabe nur den richtigen objective-Parameter übergeben. In diesem Fall verwenden wir reg:logistic, da wir ein binäres Klassifizierungsproblem haben und das Modell einen einzelnen Wert im Bereich von (0,1) ausgeben soll: 0 für nicht genehmigt und 1 für genehmigt.

Mit dem folgenden Code wird ein XGBoost-Modell erstellt:

model = xgb.XGBClassifier(
    objective='reg:logistic'
)

Sie können das Modell mit einer einzigen Codezeile trainieren, indem Sie die Methode fit() aufrufen und ihr die Trainingsdaten und Labels übergeben.

model.fit(x_train, y_train)

Schritt 2: Genauigkeit des Modells bewerten

Jetzt können wir unser trainiertes Modell verwenden, um mit der Funktion predict() Vorhersagen für unsere Testdaten zu generieren.

Dann verwenden wir die accuracy_score-Funktion von Scikit Learn, um die Genauigkeit unseres Modells basierend auf dessen Leistung mit unseren Testdaten zu berechnen. Wir übergeben ihr die Ground-Truth-Werte zusammen mit den vorhergesagten Werten des Modells für jedes Beispiel in unserem Test-Dataset:

y_pred = model.predict(x_test)
acc = accuracy_score(y_test, y_pred.round())
print(acc, '\n')

Die Genauigkeit sollte bei etwa 87% liegen. Bei Ihnen wird sich diese jedoch leicht unterscheiden, da es beim maschinellen Lernen immer ein Element der Zufälligkeit gibt.

Schritt 3: Modell speichern

Führen Sie den folgenden Code aus, um das Modell bereitzustellen und in einer lokalen Datei zu speichern:

model.save_model('model.bst')

6. Modell in Cloud AI Platform bereitstellen

Unser Modell läuft zwar lokal, aber es wäre schön, wenn wir von überall aus Vorhersagen treffen könnten (nicht nur von diesem Notebook!). In diesem Schritt stellen wir es in der Cloud bereit.

Schritt 1: Cloud Storage-Bucket für das Modell erstellen

Definieren wir zuerst einige Umgebungsvariablen, die wir im weiteren Codelab verwenden. Geben Sie unten den Namen Ihres Google Cloud-Projekts, den Namen des Cloud Storage-Buckets, den Sie erstellen möchten (muss global eindeutig sein), und den Versionsnamen für die erste Version Ihres Modells ein:

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
VERSION_NAME = 'v1'
MODEL_NAME = 'xgb_mortgage'

Jetzt können wir einen Storage-Bucket zum Speichern der XGBoost-Modelldatei erstellen. Cloud AI Platform verweist bei der Bereitstellung auf diese Datei.

Führen Sie den folgenden gsutil-Befehl in Ihrem Notebook aus, um einen Bucket zu erstellen:

!gsutil mb $MODEL_BUCKET

Schritt 2: Modelldatei in Cloud Storage kopieren

Als Nächstes kopieren wir die in XGBoost gespeicherte Modelldatei nach Cloud Storage. Führen Sie den folgenden gsutil-Befehl aus:

!gsutil cp ./model.bst $MODEL_BUCKET

Prüfen Sie im Storage-Browser in der Cloud Console, ob die Datei kopiert wurde:

21e1727fa02721412.png

Schritt 3: Modell erstellen und bereitstellen

Wir sind fast bereit, das Modell bereitzustellen. Mit dem folgenden gcloud-Befehl ai-platform wird ein neues Modell in Ihrem Projekt erstellt. Wir nennen diese Datei xgb_mortgage:

!gcloud ai-platform models create $MODEL_NAME --region='global'

Jetzt ist es an der Zeit, das Modell bereitzustellen. Dazu können wir folgenden gcloud-Befehl verwenden:

!gcloud ai-platform versions create $VERSION_NAME \
--model=$MODEL_NAME \
--framework='XGBOOST' \
--runtime-version=2.1 \
--origin=$MODEL_BUCKET \
--python-version=3.7 \
--project=$GCP_PROJECT \
--region='global'

Prüfen Sie während der Ausführung den Abschnitt „Modelle“ in der AI Platform Console. Dort sollte Ihre neue Version bereitgestellt werden:

342875ba92becad1.png

Wenn die Bereitstellung erfolgreich abgeschlossen wurde, wird an der Stelle, an der sich das Ladesymbol befindet, ein grünes Häkchen angezeigt. Die Bereitstellung dauert 2–3 Minuten.

Schritt 4: Bereitgestelltes Modell testen

Prüfen Sie, ob das bereitgestellte Modell funktioniert, indem Sie es mit gcloud testen, um eine Vorhersage zu treffen. Speichern Sie zuerst eine JSON-Datei mit dem ersten Beispiel aus unserem Test-Dataset:

%%writefile predictions.json
[2016.0, 1.0, 346.0, 27.0, 211.0, 4530.0, 86700.0, 132.13, 1289.0, 1408.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]

Testen Sie Ihr Modell, indem Sie diesen Code ausführen:

prediction = !gcloud ai-platform predict --model=xgb_mortgage --region='global' --json-instances=predictions.json --version=$VERSION_NAME --verbosity=none

print(prediction)

In der Ausgabe sollten Sie die Vorhersage Ihres Modells sehen. Dieses Beispiel wurde genehmigt, der Wert sollte nahe 1 liegen.

7. What-if-Tool zur Interpretation Ihres Modells verwenden

Schritt 1: What-if-Tool-Visualisierung erstellen

Wenn Sie das What-If-Tool mit Ihren AI Platform-Modellen verbinden möchten, müssen Sie ihm eine Teilmenge Ihrer Testbeispiele zusammen mit den Ground-Truth-Werten für diese Beispiele übergeben. Lassen Sie uns ein Numpy-Array von 500 unserer Testbeispiele und den zugehörigen Ground-Truth-Labels erstellen:

num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples].values,y_test[:num_wit_examples].reshape(-1,1)))

Zum Instanziieren des What-if-Tools müssen Sie nur ein WitConfigBuilder-Objekt erstellen und an das zu analysierende AI Platform-Modell übergeben.

Wir verwenden hier den optionalen Parameter adjust_prediction, da das What-if-Tool eine Liste von Punktzahlen für jede Klasse in unserem Modell erwartet (in diesem Fall 2). Da unser Modell nur einen einzelnen Wert von 0 bis 1 zurückgibt, transformieren wir ihn in dieser Funktion in das richtige Format:

def adjust_prediction(pred):
  return [1 - pred, pred]

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_ai_platform_model(GCP_PROJECT, MODEL_NAME, VERSION_NAME, adjust_prediction=adjust_prediction)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

Es kann eine Minute dauern, bis die Visualisierung geladen ist. Beim Laden sollte Folgendes angezeigt werden:

4c0b00e6afcdbe01.png

Die Y-Achse zeigt die Vorhersage des Modells, wobei 1 eine approved-Vorhersage mit hoher Zuverlässigkeit und 0 eine hohe Konfidenz für denied-Vorhersage ist. Die X-Achse ist einfach die Streuung aller geladenen Datenpunkte.

Schritt 2: Einzelne Datenpunkte untersuchen

Die Standardansicht des What-if-Tools ist der Tab Datenpunkteditor. Hier können Sie auf einen einzelnen Datenpunkt klicken, um dessen Merkmale anzuzeigen, Featurewerte zu ändern und zu sehen, wie sich diese Änderung auf die Vorhersage des Modells für einen einzelnen Datenpunkt auswirkt.

Im folgenden Beispiel haben wir einen Datenpunkt in der Nähe des 0,5-Schwellenwerts ausgewählt. Der mit diesem speziellen Datenpunkt verknüpfte Hypothekenantrag stammt aus CFPB. Wir haben diese Funktion in 0 geändert und auch den Wert von agency_code_Department of Housing and Urban Development (HUD) in 1 geändert, um zu sehen, was mit der Vorhersage des Modells passiert, wenn dieser Kredit stattdessen von HUD stammt:

717620d6a1330479.png

Wie Sie im What-if-Tool unten links sehen können, wurde die approved-Vorhersage des Modells durch eine Änderung dieses Features um 32 % deutlich reduziert. Dies könnte darauf hindeuten, dass die Agentur, von der ein Darlehen erhalten wurde, einen starken Einfluss auf die Ergebnisse des Modells hat. Um sicherzugehen, müssen wir jedoch weitere Analysen durchführen.

Unten links in der Benutzeroberfläche können wir auch den Ground-Truth-Wert für jeden Datenpunkt sehen und mit der Vorhersage des Modells vergleichen:

60ff20ae80ed5e27.png

Schritt 3: Kontrafaktische Analyse

Klicken Sie dann auf einen Datenpunkt und bewegen Sie den Schieberegler Nächsten kontrafaktischen Datenpunkt anzeigen nach rechts:

ae64fd7abefe5449.png

Wenn Sie diese Option auswählen, wird der Datenpunkt angezeigt, der dem ursprünglich ausgewählten Element die ähnlichsten Featurewerte hat, jedoch die entgegengesetzte Vorhersage. Sie können dann durch die Featurewerte scrollen, um zu sehen, wo sich die beiden Datenpunkte unterscheiden (die Unterschiede sind grün und fett markiert).

Schritt 4: Teilabhängigkeitsdiagramme ansehen

Um zu sehen, wie sich die einzelnen Funktionen insgesamt auf die Vorhersagen des Modells auswirken, klicken Sie das Kästchen Teilabhängigkeitsdiagramme an und achten Sie darauf, dass Globale Teilabhängigkeitsdiagramme ausgewählt sind:

72117b5ceb683841.png

Hier sehen wir, dass bei Krediten, die von HUD stammen, die Wahrscheinlichkeit, dass sie abgelehnt werden, etwas höher ist. Die Grafik zeigt diese Form, weil der Agenturcode ein boolesches Merkmal ist, sodass Werte nur genau 0 oder 1 sein können.

applicant_income_thousands ist ein numerisches Merkmal. Im Diagramm der Teilabhängigkeit können wir sehen, dass ein höheres Einkommen die Wahrscheinlichkeit, dass ein Antrag genehmigt wird, geringfügig erhöht, jedoch nur bis zu etwa 200.000 $. Nach 200.000 $hat dieses Feature keinen Einfluss auf die Vorhersage des Modells.

Schritt 5: Gesamtleistung und Fairness untersuchen

Klicken Sie als Nächstes auf den Tab Leistung und Fairness. Hier werden Gesamtleistungsstatistiken zu den Ergebnissen des Modells für das bereitgestellte Dataset angezeigt, einschließlich Wahrheitsmatrizen, PR-Kurven und ROC-Kurven.

Wählen Sie mortgage_status als Ground Truth-Feature aus, um eine Wahrheitsmatrix aufzurufen:

fe1384ee47699498.png

Diese Wahrheitsmatrix zeigt die richtigen und falschen Vorhersagen unseres Modells als Prozentsatz der Gesamtzahl. Wenn Sie die Quadrate Tatsächliches Ja / Vorhergesagtes Ja und Tatsächliches Nein / Vorhergesagtes Nein addieren, sollte das Ergebnis dieselbe Genauigkeit wie bei Ihrem Modell haben (etwa 87%).

Sie können auch mit dem Schieberegler für den Schwellenwert experimentieren, um den positiven Klassifizierungswert, den das Modell zurückgeben muss, zu erhöhen oder zu senken, bevor es entscheidet, approved für den Kredit vorherzusagen. So können Sie sehen, wie sich dies auf die Genauigkeit sowie auf falsch positive und falsch negative Ergebnisse auswirkt. In diesem Fall ist die Genauigkeit um einen Schwellenwert von 0, 55 am höchsten.

Wählen Sie dann im linken Drop-down-Menü Slice nach die Option loan_purpose_Home_purchase aus:

f3f1858d627d57ab.png

Sie sehen nun die Leistung für die beiden Teilmengen Ihrer Daten: die "0" wird angezeigt, wenn der Kredit nicht für den Kauf einer Immobilie vorgesehen ist, und die „1“ Ein Segment bezieht sich auf den Darlehen für den Kauf einer Immobilie. Überprüfen Sie die Genauigkeit, die falsch positive und die falsch negative Rate zwischen den beiden Segmenten, um Leistungsunterschiede zu ermitteln.

Wenn Sie die Zeilen erweitern, um sich die Wahrheitsmatrizen anzusehen, sehen Sie, dass das Modell „genehmigt“ vorhersagt für ca. 70% Kreditanträge für den Kauf von Immobilien und nur 46% der Darlehen, die nicht für den Kauf von Immobilien bestimmt sind (die genauen Prozentsätze variieren je nach Modell):

318a8d5a8ffc6bea.png

Wenn Sie über die Optionsfelder auf der linken Seite Demografische Gleichheit auswählen, werden die beiden Grenzwerte angepasst. Das Modell prognostiziert dann approved für einen ähnlichen Prozentsatz von Bewerbern in beiden Segmenten. Wie wirkt sich dies auf die Genauigkeit sowie auf falsch positive und falsch negative Ergebnisse für jedes Segment aus?

Schritt 6: Featureverteilung untersuchen

Gehen Sie schließlich zum Tab Funktionen im What-if-Tool. Hier sehen Sie die Verteilung der Werte für jedes Feature in Ihrem Dataset:

48ab3c4879793324.png

Mit diesem Tab können Sie dafür sorgen, dass Ihr Dataset ausgewogen ist. Es sieht beispielsweise so aus, als ob nur sehr wenige Kredite in dem Dataset von der Farm Service Agency stammen. Um die Genauigkeit des Modells zu verbessern, könnten wir erwägen, weitere Kredite von dieser Agentur hinzuzufügen, sofern die Daten verfügbar sind.

Hier sind nur ein paar Ideen für die explorative Datenanalyse für das What-if-Tool beschrieben. Probieren Sie einfach weiter mit dem Tool, es gibt noch viele weitere Bereiche zu erkunden!

8. Bereinigen

Wenn Sie dieses Notebook weiterverwenden möchten, empfehlen wir Ihnen, es bei Nichtgebrauch auszuschalten. Wählen Sie in der Notebooks-UI in der Cloud Console das Notebook und dann Beenden aus:

879147427150b6c7.png

Wenn Sie alle Ressourcen löschen möchten, die Sie in diesem Lab erstellt haben, löschen Sie einfach die Notebookinstanz, anstatt sie zu beenden.

Gehen Sie im Navigationsmenü der Cloud Console zu „Storage“ und löschen Sie beide Buckets, die Sie zum Speichern Ihrer Modell-Assets erstellt haben.