MODELLBEWERTUNG & OPTIMIERUNG

Wenn alle Modelle eine ähnliche Genauigkeit haben, was nun?

Sie haben mehrere Klassifizierungsmodelle trainiert, und alle scheinen mit hohen Genauigkeitswerten eine gute Leistung zu erbringen. Glückwunsch!

Aber Second – ​​ist ein Modell wirklich besser als die anderen? Genauigkeit allein sagt nicht die ganze Geschichte. Was passiert, wenn ein Modell sein Vertrauen ständig überschätzt, während ein anderes es unterschätzt? Hier ist Modellkalibrierung kommt rein.

Hier sehen wir, was Modellkalibrierung ist, und untersuchen, wie Sie die Zuverlässigkeit der Vorhersagen Ihrer Modelle bewerten können. Mithilfe von Bildern und praktischen Codebeispielen zeigen wir Ihnen, wie Sie Kalibrierungsprobleme identifizieren. Machen Sie sich bereit, über die Genauigkeit hinauszugehen und das wahre Potenzial Ihrer Modelle für maschinelles Lernen auszuschöpfen!

Alle Grafiken: Vom Autor mit Canva Professional erstellt. Optimiert für Mobilgeräte; kann auf dem Desktop übergroß erscheinen.

Die Modellkalibrierung misst, wie intestine ein Modell ist Vorhersagewahrscheinlichkeiten seiner tatsächlichen Leistung entsprechen. Ein Modell, das einen Wahrscheinlichkeitswert von 70 % liefert, sollte bei ähnlichen Vorhersagen in 70 % der Fälle korrekt sein. Das bedeutet, dass seine Wahrscheinlichkeitswerte die tatsächliche Wahrscheinlichkeit widerspiegeln sollten, dass seine Vorhersagen richtig sind.

Warum Kalibrierung wichtig ist

Während die Genauigkeit uns sagt, wie oft ein Modell insgesamt korrekt ist, verrät uns die Kalibrierung ob wir seinen Wahrscheinlichkeitswerten vertrauen können. Zwei Modelle können beide eine Genauigkeit von 90 % aufweisen, aber eines liefert möglicherweise realistische Wahrscheinlichkeitswerte, während das andere übermäßig sichere Vorhersagen liefert. In vielen realen Anwendungen sind zuverlässige Wahrscheinlichkeitswerte genauso wichtig wie korrekte Vorhersagen.

Zwei Modelle, die gleich genau sind (70 % richtig), weisen unterschiedliche Vertrauensgrade in ihre Vorhersagen auf. Modell A verwendet ausgewogene Wahrscheinlichkeitswerte (0,3 und 0,7), während Modell B nur excessive Wahrscheinlichkeiten (0,0 und 1,0) verwendet, was zeigt, dass es bei jeder Vorhersage entweder völlig sicher oder völlig unsicher ist.

Perfekte Kalibrierung vs. Realität

Ein perfekt kalibriertes Modell würde eine direkte Übereinstimmung zwischen seinen Vorhersagewahrscheinlichkeiten und den tatsächlichen Erfolgsraten aufweisen: Wenn es mit einer Wahrscheinlichkeit von 90 % vorhersagt, sollte es in 90 % der Fälle korrekt sein. Das Gleiche gilt für alle Wahrscheinlichkeitsstufen.

Allerdings sind die meisten Modelle nicht perfekt kalibriert. Dies können sein:

  • Überhebliches Selbstvertrauen: Geben Sie Wahrscheinlichkeitswerte an, die für ihre tatsächliche Leistung zu hoch sind
  • Unterbewusst: Geben Sie Wahrscheinlichkeitswerte an, die für ihre tatsächliche Leistung zu niedrig sind
  • Beides: übersteigertes Selbstvertrauen in einigen Bereichen und mangelndes Selbstvertrauen in anderen
Vier Modelle mit der gleichen Genauigkeit (70 %) und unterschiedlichen Kalibrierungsmustern. Das übersichere Modell macht excessive Vorhersagen (0,0 oder 1,0), während das untersichere Modell nahe bei 0,5 bleibt. Das über- und untersichere Modell wechselt zwischen Extrem- und Mittelwerten. Das intestine kalibrierte Modell verwendet vernünftige Wahrscheinlichkeiten (0,3 für „NEIN“ und 0,7 für „JA“), die seiner tatsächlichen Leistung entsprechen.

Diese Diskrepanz zwischen vorhergesagten Wahrscheinlichkeiten und tatsächlicher Korrektheit kann zu einer schlechten Entscheidungsfindung führen, wenn diese Modelle in realen Anwendungen verwendet werden. Aus diesem Grund ist es für den Aufbau zuverlässiger maschineller Lernsysteme erforderlich, die Modellkalibrierung zu verstehen und zu verbessern.

Um die Modellkalibrierung zu erkunden, fahren wir mit fort der gleiche Datensatz, den ich in meinen vorherigen Artikeln über Klassifizierungsalgorithmen verwendet habe: Vorhersage, ob jemand Golf spielen wird oder nicht, basierend auf den Wetterbedingungen.

Spalten: „Bewölkt (einfach kodiert in 3 Spalten)“, „Temperatur“ (in Fahrenheit), „Luftfeuchtigkeit“ (in %), „Windig“ (Ja/Nein) und „Spielen“ (Ja/Nein, Ziel). Besonderheit)
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

# Create and put together dataset
dataset_dict = {
'Outlook': ('sunny', 'sunny', 'overcast', 'wet', 'wet', 'wet', 'overcast',
'sunny', 'sunny', 'wet', 'sunny', 'overcast', 'overcast', 'wet',
'sunny', 'overcast', 'wet', 'sunny', 'sunny', 'wet', 'overcast',
'wet', 'sunny', 'overcast', 'sunny', 'overcast', 'wet', 'overcast'),
'Temperature': (85.0, 80.0, 83.0, 70.0, 68.0, 65.0, 64.0, 72.0, 69.0, 75.0, 75.0,
72.0, 81.0, 71.0, 81.0, 74.0, 76.0, 78.0, 82.0, 67.0, 85.0, 73.0,
88.0, 77.0, 79.0, 80.0, 66.0, 84.0),
'Humidity': (85.0, 90.0, 78.0, 96.0, 80.0, 70.0, 65.0, 95.0, 70.0, 80.0, 70.0,
90.0, 75.0, 80.0, 88.0, 92.0, 85.0, 75.0, 92.0, 90.0, 85.0, 88.0,
65.0, 70.0, 60.0, 95.0, 70.0, 78.0),
'Wind': (False, True, False, False, False, True, True, False, False, False, True,
True, False, True, True, False, False, True, False, True, True, False,
True, False, False, True, False, False),
'Play': ('No', 'No', 'Sure', 'Sure', 'Sure', 'No', 'Sure', 'No', 'Sure', 'Sure', 'Sure',
'Sure', 'Sure', 'No', 'No', 'Sure', 'Sure', 'No', 'No', 'No', 'Sure', 'Sure',
'Sure', 'Sure', 'Sure', 'Sure', 'No', 'Sure')
}
# Put together information
df = pd.DataFrame(dataset_dict)

Vor dem Coaching unserer Modelle haben wir numerische Wettermessungen normalisiert Standardskalierung und transformierte kategoriale Merkmale mit One-Scorching-Kodierung. Diese Vorverarbeitungsschritte stellen sicher, dass alle Modelle die Daten effektiv nutzen können und gleichzeitig faire Vergleiche zwischen ihnen aufrechterhalten.

from sklearn.preprocessing import StandardScaler
df = pd.get_dummies(df, columns=('Outlook'), prefix='', prefix_sep='', dtype=int)
df('Wind') = df('Wind').astype(int)
df('Play') = (df('Play') == 'Sure').astype(int)

# Rearrange columns
column_order = ('sunny', 'overcast', 'wet', 'Temperature', 'Humidity', 'Wind', 'Play')
df = df(column_order)

# Put together options and goal
X,y = df.drop('Play', axis=1), df('Play')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Scale numerical options
scaler = StandardScaler()
X_train(('Temperature', 'Humidity')) = scaler.fit_transform(X_train(('Temperature', 'Humidity')))
X_test(('Temperature', 'Humidity')) = scaler.rework(X_test(('Temperature', 'Humidity')))

Modelle und Coaching

Für diese Untersuchung haben wir vier Klassifizierungsmodelle auf ähnliche Genauigkeitswerte trainiert:

  • Ok-Nächste Nachbarn (kNN)
  • Bernoulli Naive Bayes
  • Logistische Regression
  • Mehrschichtiges Perzeptron (MLP)

Für diejenigen, die neugierig sind, wie diese Algorithmen Vorhersagen treffen und welche Wahrscheinlichkeiten sie haben, können Sie sich auf diesen Artikel beziehen:

Während diese Modelle bei diesem einfachen Downside die gleiche Genauigkeit erreichten, berechnen sie ihre Vorhersagewahrscheinlichkeiten unterschiedlich.

Obwohl die vier Modelle in 85,7 % der Fälle korrekt sind, weisen sie unterschiedliche Vertrauensgrade in ihre Vorhersagen auf. Hier tendiert das MLP-Modell dazu, sich seiner Antworten sehr sicher zu sein (es liefert Werte nahe 1,0), während das kNN-Modell vorsichtiger ist und vielfältigere Konfidenzwerte liefert.
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
from sklearn.naive_bayes import BernoulliNB

# Initialize the fashions with the discovered parameters
knn = KNeighborsClassifier(n_neighbors=4, weights='distance')
bnb = BernoulliNB()
lr = LogisticRegression(C=1, random_state=42)
mlp = MLPClassifier(hidden_layer_sizes=(4, 2),random_state=42, max_iter=2000)

# Practice all fashions
fashions = {
'KNN': knn,
'BNB': bnb,
'LR': lr,
'MLP': mlp
}

for identify, mannequin in fashions.objects():
mannequin.match(X_train, y_train)

# Create predictions and chances for every mannequin
results_dict = {
'True Labels': y_test
}

for identify, mannequin in fashions.objects():
# results_dict(f'{identify} Pred') = mannequin.predict(X_test)
results_dict(f'{identify} Prob') = mannequin.predict_proba(X_test)(:, 1)

# Create outcomes dataframe
results_df = pd.DataFrame(results_dict)

# Print predictions and chances
print("nPredictions and Chances:")
print(results_df)

# Print accuracies
print("nAccuracies:")
for identify, mannequin in fashions.objects():
accuracy = accuracy_score(y_test, mannequin.predict(X_test))
print(f"{identify}: {accuracy:.3f}")

Anhand dieser Unterschiede werden wir untersuchen, warum wir über die Genauigkeit hinausblicken müssen.

Um zu beurteilen, wie intestine die Vorhersagewahrscheinlichkeiten eines Modells mit seiner tatsächlichen Leistung übereinstimmen, verwenden wir verschiedene Methoden und Metriken. Diese Messungen helfen uns zu verstehen, ob die Konfidenzniveaus unseres Modells zuverlässig sind.

Brier-Rating

Der Brier-Rating misst die mittlere quadratische Differenz zwischen vorhergesagten Wahrscheinlichkeiten und tatsächlichen Ergebnissen. Er reicht von 0 bis 1, wobei niedrigere Werte auf eine bessere Kalibrierung hinweisen. Dieser Wert ist besonders nützlich, da er sowohl die Kalibrierung als auch die Genauigkeit zusammen berücksichtigt.

Der Wert (0,148) zeigt, wie intestine die Zuverlässigkeit des Modells mit seiner tatsächlichen Leistung übereinstimmt. Dies wird durch den Vergleich der vom Modell vorhergesagten Chancen mit dem, was tatsächlich passiert ist, ermittelt (0 für „NEIN“, 1 für „JA“), wobei kleinere Unterschiede bessere Vorhersagen bedeuten.

Protokollverlust

Protokollverlust berechnet die unfavourable logarithmische Wahrscheinlichkeit korrekter Vorhersagen. Diese Metrik reagiert besonders empfindlich auf sichere, aber falsche Vorhersagen – wenn ein Modell angibt, dass es zu 90 % sicher ist, aber falsch ist, erhält es eine viel größere Strafe als wenn es zu 60 % sicher und falsch ist. Niedrigere Werte weisen auf eine bessere Kalibrierung hin.

Bei jeder Vorhersage wird untersucht, wie sicher das Modell bei der richtigen Antwort warfare. Wenn das Modell sehr zuversichtlich ist, aber falsch liegt (wie in Index 26), erhält es eine größere Strafe. Das Endergebnis von 0,455 ist der Durchschnitt aller dieser Strafen, wobei niedrigere Zahlen bessere Vorhersagen bedeuten.

Erwarteter Kalibrierungsfehler (ECE)

ECE misst die durchschnittliche Differenz zwischen vorhergesagten und tatsächlichen Wahrscheinlichkeiten (angenommen als Durchschnitt der Bezeichnung), gewichtet danach, wie viele Vorhersagen in jede Wahrscheinlichkeitsgruppe fallen. Diese Metrik hilft uns zu verstehen, ob unser Modell systematische Verzerrungen in seinen Wahrscheinlichkeitsschätzungen aufweist.

Die Vorhersagen werden basierend auf der Zuverlässigkeit des Modells in fünf Klassen eingeteilt. Für jede Gruppe vergleichen wir das durchschnittliche Vertrauen des Modells damit, wie oft es tatsächlich richtig lag. Das Endergebnis (0,1502) sagt uns, wie intestine diese übereinstimmen, wobei niedrigere Zahlen besser sind.“

Zuverlässigkeitsdiagramme

Ähnlich wie bei ECE visualisiert ein Zuverlässigkeitsdiagramm (oder eine Kalibrierungskurve) die Modellkalibrierung, indem Vorhersagen gruppiert und mit tatsächlichen Ergebnissen verglichen werden. Während ECE uns eine einzelne Zahl zur Messung des Kalibrierungsfehlers liefert, das Zuverlässigkeitsdiagramm zeigt uns die gleichen Informationen grafisch. Wir verwenden denselben Binning-Ansatz und berechnen die tatsächliche Häufigkeit positiver Ergebnisse in jeder Klasse. Bei der grafischen Darstellung zeigen uns diese Punkte genau, wo die Vorhersagen unseres Modells von der perfekten Kalibrierung abweichen, was als diagonale Linie erscheinen würde.

Wie bei ECE werden die Vorhersagen basierend auf dem Konfidenzniveau in 5 Klassen gruppiert. Jeder Punkt zeigt an, wie oft das Modell tatsächlich richtig lag (oben/unten) im Vergleich dazu, wie sicher es warfare (hyperlinks/rechts). Die gepunktete Linie zeigt die perfekte Übereinstimmung – die Kurve des Modells zeigt, dass es manchmal denkt, es sei besser oder schlechter, als es tatsächlich ist.

Vergleich von Kalibrierungsmetriken

Jede dieser Metriken zeigt unterschiedliche Aspekte von Kalibrierungsproblemen:

  • Ein hoher Brier-Rating deutet auf insgesamt schlechte Wahrscheinlichkeitsschätzungen hin.
  • Ein hoher Log-Verlust weist auf zu zuversichtliche falsche Vorhersagen hin.
  • Ein hoher ECE weist auf eine systematische Verzerrung der Wahrscheinlichkeitsschätzungen hin.

Zusammengenommen geben uns diese Metriken ein vollständiges Bild davon, wie intestine die Wahrscheinlichkeitswerte unseres Modells seine tatsächliche Leistung widerspiegeln.

Unsere Modelle

Berechnen wir für unsere Modelle die Kalibrierungsmetriken und zeichnen wir ihre Kalibrierungskurven:

from sklearn.metrics import brier_score_loss, log_loss
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt

# Initialize fashions
fashions = {
'k-Nearest Neighbors': KNeighborsClassifier(n_neighbors=4, weights='distance'),
'Bernoulli Naive Bayes': BernoulliNB(),
'Logistic Regression': LogisticRegression(C=1.5, random_state=42),
'Multilayer Perceptron': MLPClassifier(hidden_layer_sizes=(4, 2), random_state=42, max_iter=2000)
}

# Get predictions and calculate metrics
metrics_dict = {}
for identify, mannequin in fashions.objects():
mannequin.match(X_train, y_train)
y_prob = mannequin.predict_proba(X_test)(:, 1)
metrics_dict(identify) = {
'Brier Rating': brier_score_loss(y_test, y_prob),
'Log Loss': log_loss(y_test, y_prob),
'ECE': calculate_ece(y_test, y_prob),
'Chances': y_prob
}

# Plot calibration curves
fig, axes = plt.subplots(2, 2, figsize=(8, 8), dpi=300)
colours = ('orangered', 'slategrey', 'gold', 'mediumorchid')

for idx, (identify, metrics) in enumerate(metrics_dict.objects()):
ax = axes.ravel()(idx)
prob_true, prob_pred = calibration_curve(y_test, metrics('Chances'),
n_bins=5, technique='uniform')

ax.plot((0, 1), (0, 1), 'k--', label='Completely calibrated')
ax.plot(prob_pred, prob_true, colour=colours(idx), marker='o',
label='Calibration curve', linewidth=2, markersize=8)

title = f'{identify}nBrier: {metrics("Brier Rating"):.3f} | Log Loss: {metrics("Log Loss"):.3f} | ECE: {metrics("ECE"):.3f}'
ax.set_title(title, fontsize=11, pad=10)
ax.grid(True, alpha=0.7)
ax.set_xlim((-0.05, 1.05))
ax.set_ylim((-0.05, 1.05))
ax.spines(('high', 'proper', 'left', 'backside')).set_visible(False)
ax.legend(fontsize=10, loc='higher left')

plt.tight_layout()
plt.present()

Lassen Sie uns nun die Kalibrierungsleistung jedes Modells anhand dieser Metriken analysieren:

Das k-Nearest Neighbors (KNN)-Modell schneidet intestine ab, wenn es darum geht, abzuschätzen, wie sicher es bei seinen Vorhersagen sein sollte. Die Grafiklinie bleibt nahe der gepunkteten Linie, was auf eine gute Leistung hinweist. Es hat solide Werte – einen Brier-Wert von 0,148 und den besten ECE-Wert von 0,090. Während es im mittleren Bereich manchmal zu viel Selbstvertrauen zeigt, ist es macht im Allgemeinen verlässliche Schätzungen über seine Gewissheit.

Das Modell Bernoulli Naive Bayes zeigt in seiner Linie ein ungewöhnliches Treppenstufenmuster. Dies bedeutet, dass zwischen verschiedenen Sicherheitsniveaus hin- und hergewechselt wird, anstatt sich reibungslos zu ändern. Obwohl es den gleichen Brier-Rating wie KNN (0,148) hat, zeigt sein höherer ECE von 0,150, dass es seine Sicherheit weniger genau einschätzt. Das Modell wechselt zwischen zu viel Selbstvertrauen und nicht genug Selbstvertrauen.

Das logistische Regressionsmodell zeigt deutliche Probleme mit seinen Vorhersagen. Seine Linie entfernt sich weit von der gepunkteten Linie, was bedeutet, dass er oft falsch einschätzt, wie sicher er sein sollte. Es hat den schlechtesten ECE-Wert (0,181) und einen schlechten Brier-Wert (0,164). Das Modell zeigt konsequent zu viel Vertrauen in seine Vorhersagenwas es unzuverlässig macht.

Das Multilayer-Perzeptron zeigt ein deutliches Downside. Obwohl es den besten Brier-Rating (0,129) hat, verrät seine Linie dies es macht meist excessive Vorhersagen – entweder sehr sicher oder sehr unsicher, mit wenig dazwischen. Sein hoher ECE-Wert (0,167) und die flache Linie in den mittleren Bereichen zeigen, dass es ihm schwerfällt, ausgewogene Schätzungen vorzunehmen.

Nach Prüfung aller vier Modelle kam das k-Nearest Neighbors schneidet eindeutig am besten ab bei der Einschätzung seiner Vorhersagesicherheit. Es sorgt für eine konsistente Leistung über verschiedene Sicherheitsebenen hinweg und zeigt das zuverlässigste Muster in seinen Vorhersagen. Während andere Modelle bei bestimmten Messungen intestine abschneiden könnten (wie der Brier-Rating des Multilayer Perceptron), zeigen ihre Diagramme, dass sie nicht so zuverlässig sind, wenn wir ihren Sicherheitsschätzungen vertrauen müssen.

Bei der Auswahl zwischen verschiedenen Modellen müssen wir sowohl deren Genauigkeit als auch die Kalibrierungsqualität berücksichtigen. Ein Modell mit etwas geringerer Genauigkeit, aber besserer Kalibrierung könnte wertvoller sein als ein hochgenaues Modell mit schlechten Wahrscheinlichkeitsschätzungen.

Indem wir die Kalibrierung und ihre Bedeutung verstehen, können wir zuverlässigere Systeme für maschinelles Lernen entwickeln, denen Benutzer nicht nur hinsichtlich ihrer Vorhersagen, sondern auch hinsichtlich ihres Vertrauens in diese Vorhersagen vertrauen können.

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import brier_score_loss, log_loss
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt

# Outline ECE
def calculate_ece(y_true, y_prob, n_bins=5):
bins = np.linspace(0, 1, n_bins + 1)
ece = 0
for bin_lower, bin_upper in zip(bins(:-1), bins(1:)):
masks = (y_prob >= bin_lower) & (y_prob < bin_upper)
if np.sum(masks) > 0:
bin_conf = np.imply(y_prob(masks))
bin_acc = np.imply(y_true(masks))
ece += np.abs(bin_conf - bin_acc) * np.sum(masks)
return ece / len(y_true)

# Create dataset and put together information
dataset_dict = {
'Outlook': ('sunny', 'sunny', 'overcast', 'wet', 'wet', 'wet', 'overcast','sunny', 'sunny', 'wet', 'sunny', 'overcast', 'overcast', 'wet','sunny', 'overcast', 'wet', 'sunny', 'sunny', 'wet', 'overcast','wet', 'sunny', 'overcast', 'sunny', 'overcast', 'wet', 'overcast'),
'Temperature': (85.0, 80.0, 83.0, 70.0, 68.0, 65.0, 64.0, 72.0, 69.0, 75.0, 75.0,72.0, 81.0, 71.0, 81.0, 74.0, 76.0, 78.0, 82.0, 67.0, 85.0, 73.0,88.0, 77.0, 79.0, 80.0, 66.0, 84.0),
'Humidity': (85.0, 90.0, 78.0, 96.0, 80.0, 70.0, 65.0, 95.0, 70.0, 80.0, 70.0,90.0, 75.0, 80.0, 88.0, 92.0, 85.0, 75.0, 92.0, 90.0, 85.0, 88.0,65.0, 70.0, 60.0, 95.0, 70.0, 78.0),
'Wind': (False, True, False, False, False, True, True, False, False, False, True,True, False, True, True, False, False, True, False, True, True, False,True, False, False, True, False, False),
'Play': ('No', 'No', 'Sure', 'Sure', 'Sure', 'No', 'Sure', 'No', 'Sure', 'Sure', 'Sure','Sure', 'Sure', 'No', 'No', 'Sure', 'Sure', 'No', 'No', 'No', 'Sure', 'Sure','Sure', 'Sure', 'Sure', 'Sure', 'No', 'Sure')
}

# Put together and encode information
df = pd.DataFrame(dataset_dict)
df = pd.get_dummies(df, columns=('Outlook'), prefix='', prefix_sep='', dtype=int)
df('Wind') = df('Wind').astype(int)
df('Play') = (df('Play') == 'Sure').astype(int)
df = df(('sunny', 'overcast', 'wet', 'Temperature', 'Humidity', 'Wind', 'Play'))

# Cut up and scale information
X, y = df.drop('Play', axis=1), df('Play')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)
scaler = StandardScaler()
X_train(('Temperature', 'Humidity')) = scaler.fit_transform(X_train(('Temperature', 'Humidity')))
X_test(('Temperature', 'Humidity')) = scaler.rework(X_test(('Temperature', 'Humidity')))

# Practice mannequin and get predictions
mannequin = BernoulliNB()
mannequin.match(X_train, y_train)
y_prob = mannequin.predict_proba(X_test)(:, 1)

# Calculate metrics
metrics = {
'Brier Rating': brier_score_loss(y_test, y_prob),
'Log Loss': log_loss(y_test, y_prob),
'ECE': calculate_ece(y_test, y_prob)
}

# Plot calibration curve
plt.determine(figsize=(6, 6), dpi=300)
prob_true, prob_pred = calibration_curve(y_test, y_prob, n_bins=5, technique='uniform')

plt.plot((0, 1), (0, 1), 'k--', label='Completely calibrated')
plt.plot(prob_pred, prob_true, colour='slategrey', marker='o',
label='Calibration curve', linewidth=2, markersize=8)

title = f'Bernoulli Naive BayesnBrier: {metrics("Brier Rating"):.3f} | Log Loss: {metrics("Log Loss"):.3f} | ECE: {metrics("ECE"):.3f}'
plt.title(title, fontsize=11, pad=10)
plt.grid(True, alpha=0.7)
plt.xlim((-0.05, 1.05))
plt.ylim((-0.05, 1.05))
plt.gca().spines(('high', 'proper', 'left', 'backside')).set_visible(False)
plt.legend(fontsize=10, loc='decrease proper')

plt.tight_layout()
plt.present()

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import BernoulliNB
from sklearn.linear_model import LogisticRegression
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import brier_score_loss, log_loss
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt

# Outline ECE
def calculate_ece(y_true, y_prob, n_bins=5):
bins = np.linspace(0, 1, n_bins + 1)
ece = 0
for bin_lower, bin_upper in zip(bins(:-1), bins(1:)):
masks = (y_prob >= bin_lower) & (y_prob < bin_upper)
if np.sum(masks) > 0:
bin_conf = np.imply(y_prob(masks))
bin_acc = np.imply(y_true(masks))
ece += np.abs(bin_conf - bin_acc) * np.sum(masks)
return ece / len(y_true)

# Create dataset and put together information
dataset_dict = {
'Outlook': ('sunny', 'sunny', 'overcast', 'wet', 'wet', 'wet', 'overcast','sunny', 'sunny', 'wet', 'sunny', 'overcast', 'overcast', 'wet','sunny', 'overcast', 'wet', 'sunny', 'sunny', 'wet', 'overcast','wet', 'sunny', 'overcast', 'sunny', 'overcast', 'wet', 'overcast'),
'Temperature': (85.0, 80.0, 83.0, 70.0, 68.0, 65.0, 64.0, 72.0, 69.0, 75.0, 75.0,72.0, 81.0, 71.0, 81.0, 74.0, 76.0, 78.0, 82.0, 67.0, 85.0, 73.0,88.0, 77.0, 79.0, 80.0, 66.0, 84.0),
'Humidity': (85.0, 90.0, 78.0, 96.0, 80.0, 70.0, 65.0, 95.0, 70.0, 80.0, 70.0,90.0, 75.0, 80.0, 88.0, 92.0, 85.0, 75.0, 92.0, 90.0, 85.0, 88.0,65.0, 70.0, 60.0, 95.0, 70.0, 78.0),
'Wind': (False, True, False, False, False, True, True, False, False, False, True,True, False, True, True, False, False, True, False, True, True, False,True, False, False, True, False, False),
'Play': ('No', 'No', 'Sure', 'Sure', 'Sure', 'No', 'Sure', 'No', 'Sure', 'Sure', 'Sure','Sure', 'Sure', 'No', 'No', 'Sure', 'Sure', 'No', 'No', 'No', 'Sure', 'Sure','Sure', 'Sure', 'Sure', 'Sure', 'No', 'Sure')
}

# Put together and encode information
df = pd.DataFrame(dataset_dict)
df = pd.get_dummies(df, columns=('Outlook'), prefix='', prefix_sep='', dtype=int)
df('Wind') = df('Wind').astype(int)
df('Play') = (df('Play') == 'Sure').astype(int)
df = df(('sunny', 'overcast', 'wet', 'Temperature', 'Humidity', 'Wind', 'Play'))

# Cut up and scale information
X, y = df.drop('Play', axis=1), df('Play')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)
scaler = StandardScaler()
X_train(('Temperature', 'Humidity')) = scaler.fit_transform(X_train(('Temperature', 'Humidity')))
X_test(('Temperature', 'Humidity')) = scaler.rework(X_test(('Temperature', 'Humidity')))

# Initialize fashions
fashions = {
'k-Nearest Neighbors': KNeighborsClassifier(n_neighbors=4, weights='distance'),
'Bernoulli Naive Bayes': BernoulliNB(),
'Logistic Regression': LogisticRegression(C=1.5, random_state=42),
'Multilayer Perceptron': MLPClassifier(hidden_layer_sizes=(4, 2), random_state=42, max_iter=2000)
}

# Get predictions and calculate metrics
metrics_dict = {}
for identify, mannequin in fashions.objects():
mannequin.match(X_train, y_train)
y_prob = mannequin.predict_proba(X_test)(:, 1)
metrics_dict(identify) = {
'Brier Rating': brier_score_loss(y_test, y_prob),
'Log Loss': log_loss(y_test, y_prob),
'ECE': calculate_ece(y_test, y_prob),
'Chances': y_prob
}

# Plot calibration curves
fig, axes = plt.subplots(2, 2, figsize=(8, 8), dpi=300)
colours = ('orangered', 'slategrey', 'gold', 'mediumorchid')

for idx, (identify, metrics) in enumerate(metrics_dict.objects()):
ax = axes.ravel()(idx)
prob_true, prob_pred = calibration_curve(y_test, metrics('Chances'),
n_bins=5, technique='uniform')

ax.plot((0, 1), (0, 1), 'k--', label='Completely calibrated')
ax.plot(prob_pred, prob_true, colour=colours(idx), marker='o',
label='Calibration curve', linewidth=2, markersize=8)

title = f'{identify}nBrier: {metrics("Brier Rating"):.3f} | Log Loss: {metrics("Log Loss"):.3f} | ECE: {metrics("ECE"):.3f}'
ax.set_title(title, fontsize=11, pad=10)
ax.grid(True, alpha=0.7)
ax.set_xlim((-0.05, 1.05))
ax.set_ylim((-0.05, 1.05))
ax.spines(('high', 'proper', 'left', 'backside')).set_visible(False)
ax.legend(fontsize=10, loc='higher left')

plt.tight_layout()
plt.present()

Technisches Umfeld

Dieser Artikel verwendet Python 3.7 und scikit-learn 1.5. Während die besprochenen Konzepte allgemein anwendbar sind, können spezifische Code-Implementierungen je nach Model leicht variieren.

Über die Illustrationen

Sofern nicht anders angegeben, wurden alle Bilder vom Autor erstellt und enthalten lizenzierte Designelemente von Canva Professional.

𝙎𝙚𝙚 𝙢𝙤𝙧𝙚 𝙈𝙤𝙙𝙚𝙡 𝙀𝙫𝙖𝙡𝙪𝙖𝙩𝙞𝙤𝙣 & 𝙊𝙥𝙩𝙞𝙢𝙞𝙯𝙖𝙩𝙞𝙤𝙣 𝙢𝙚𝙩𝙝𝙤𝙙𝙨 𝙝𝙚𝙧𝙚:

Samy Baladram

Modellbewertung und -optimierung

𝙔𝙤𝙪 𝙢𝙞𝙜𝙝𝙩 𝙖𝙡𝙨𝙤 𝙡𝙞𝙠𝙚:

Samy Baladram

Ensemble-Lernen

Samy Baladram

Klassifizierungsalgorithmen

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert