Baladram – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Fri, 10 Jan 2025 14:48:23 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Modellkalibrierung, erklärt: Ein visueller Leitfaden mit Codebeispielen für Anfänger | von Samy Baladram | Januar 2025 https://chatgpz.de/machine-learning/modellkalibrierung-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-januar-2025/ https://chatgpz.de/machine-learning/modellkalibrierung-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-januar-2025/#respond Fri, 10 Jan 2025 14:48:22 +0000 http://chatgpz.de/machine-learning/modellkalibrierung-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-januar-2025/ [ad_1]

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

[ad_2]

]]>
https://chatgpz.de/machine-learning/modellkalibrierung-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-januar-2025/feed/ 0 6439
Überabtastung und Unterabtastung, erklärt: Ein visueller Leitfaden mit Mini-2D-Datensatz | von Samy Baladram | Okt. 2024 https://chatgpz.de/artificial-intelligence/ueberabtastung-und-unterabtastung-erklaert-ein-visueller-leitfaden-mit-mini-2d-datensatz-von-samy-baladram-okt-2024/ https://chatgpz.de/artificial-intelligence/ueberabtastung-und-unterabtastung-erklaert-ein-visueller-leitfaden-mit-mini-2d-datensatz-von-samy-baladram-okt-2024/#respond Sun, 27 Oct 2024 07:19:56 +0000 http://chatgpz.de/artificial-intelligence/ueberabtastung-und-unterabtastung-erklaert-ein-visueller-leitfaden-mit-mini-2d-datensatz-von-samy-baladram-okt-2024/ [ad_1]

DATENVORVERARBEITUNG

Künstliches Generieren und Löschen von Daten zum Wohle der Allgemeinheit

⛳ Extra DATA PREPROCESSING, defined:
· Lacking Worth Imputation
· Categorical Encoding
· Information Scaling
· Discretization
▶ Oversampling & Undersampling

Das Sammeln eines Datensatzes, bei dem jede Klasse genau die gleiche Anzahl vorherzusagender Klassen hat, kann eine Herausforderung sein. In der Realität sind die Dinge selten perfekt ausbalanciert, und wenn Sie ein Klassifizierungsmodell erstellen, kann dies ein Drawback sein. Wenn ein Modell auf einem solchen Datensatz trainiert wird, bei dem eine Klasse mehr Beispiele hat als die andere, ist es in der Regel besser bei der Vorhersage der größeren Gruppen und schlechter bei der Vorhersage der kleineren. Um dieses Drawback zu lösen, können wir Taktiken wie Oversampling und Undersampling anwenden – indem wir mehr Beispiele der kleineren Gruppe erstellen oder einige Beispiele aus der größeren Gruppe entfernen.

Es gibt viele verschiedene Oversampling- und Undersampling-Methoden (mit einschüchternden Namen wie SMOTE, ADASYN und Tomek Hyperlinks), aber es scheint nicht viele Ressourcen zu geben, die ihre Funktionsweise visuell vergleichen. Hier verwenden wir additionally einen einfachen 2D-Datensatz, um die Änderungen zu zeigen, die in den Daten nach der Anwendung dieser Methoden auftreten, damit wir sehen können, wie unterschiedlich die Ausgabe der einzelnen Methoden ist. Sie werden in den Bildern sehen, dass diese verschiedenen Ansätze unterschiedliche Lösungen liefern, und wer weiß, vielleicht ist einer für Ihre spezifische Herausforderung des maschinellen Lernens geeignet!

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

Überabtastung

Durch Überabtastung wird ein Datensatz ausgewogener, wenn eine Gruppe viel weniger Beispiele hat als die andere. Die Funktionsweise besteht darin, mehr Kopien der Beispiele aus der kleineren Gruppe anzufertigen. Dies trägt dazu bei, dass der Datensatz beide Gruppen gleichmäßiger darstellt.

Unterabtastung

Andererseits funktioniert die Unterabtastung dadurch, dass einige Beispiele aus der größeren Gruppe gelöscht werden, bis sie quick die gleiche Größe wie die kleinere Gruppe haben. Am Ende ist der Datensatz zwar kleiner, aber beide Gruppen werden eine ähnlichere Anzahl an Beispielen haben.

Hybride Probenahme

Die Kombination von Oversampling und Undersampling kann als „hybrides Sampling“ bezeichnet werden. Es vergrößert die kleinere Gruppe, indem es mehr Kopien seiner Beispiele erstellt, und entfernt außerdem einige Beispiele der größeren Gruppe, indem es einige seiner Beispiele entfernt. Es wird versucht, einen ausgewogeneren Datensatz zu erstellen – nicht zu groß und nicht zu klein.

Lassen Sie uns einen einfachen künstlichen Golfdatensatz verwenden, um sowohl Überabtastung als auch Unterabtastung zu zeigen. Dieser Datensatz zeigt, welche Artwork von Golfaktivität eine Particular person bei einer bestimmten Wetterbedingung ausübt.

Spalten: Temperatur (0–3), Luftfeuchtigkeit (0–3), Golfaktivität (A=Normaler Platz, B=Drive Vary oder C=Indoor-Golf). Der Trainingsdatensatz hat 2 Dimensionen und 9 Stichproben.

⚠ Beachten Sie, dass dieser kleine Datensatz zwar intestine für das Verständnis der Konzepte ist, Sie in realen Anwendungen jedoch viel größere Datensätze benötigen, bevor Sie diese Techniken anwenden, da die Stichprobenentnahme mit zu wenigen Daten zu unzuverlässigen Ergebnissen führen kann.

Zufälliges Oversampling

Zufälliges Oversampling ist eine einfache Möglichkeit, die kleinere Gruppe zu vergrößern. Es funktioniert, indem Duplikate der Beispiele aus der kleineren Gruppe erstellt werden, bis alle Klassen ausgeglichen sind.

👍 Am besten für sehr kleine Datensätze geeignet, die schnell ausgeglichen werden müssen
👎 Nicht empfohlen für komplizierte Datensätze

Beim zufälligen Oversampling werden lediglich ausgewählte Stichproben aus der kleineren Gruppe (A) dupliziert, während alle Stichproben aus den größeren Gruppen (B und C) unverändert bleiben, wie durch die A×2-Markierungen im rechten Diagramm dargestellt.

SMOTE

SMOTE (Artificial Minority Oversampling Method) ist eine Oversampling-Technik, die durch Interpolation der kleineren Gruppe neue Beispiele erstellt. Im Gegensatz zur zufälligen Überabtastung wird nicht einfach kopiert, was vorhanden ist, sondern es werden die Beispiele der kleineren Gruppe verwendet, um einige Beispiele dazwischen zu generieren.

👍 Am besten, wenn Sie über eine angemessene Menge an Beispielen verfügen, mit denen Sie arbeiten können, und Abwechslung in Ihren Daten benötigen
👎 Nicht empfohlen, wenn Sie nur sehr wenige Beispiele haben
👎 Nicht empfohlen, wenn Datenpunkte zu verstreut oder verrauscht sind

SMOTE erstellt neue A-Samples, indem es Paare von A-Punkten auswählt und neue Punkte irgendwo entlang der Linie zwischen ihnen platziert. Ebenso wird ein neuer B-Punkt zwischen Paaren zufällig ausgewählter B-Punkte platziert

ADASYN

ADASYN (Adaptive Artificial) ähnelt SMOTE, konzentriert sich jedoch darauf, neue Beispiele in den schwieriger zu erlernenden Teilen der kleineren Gruppe zu erstellen. Es werden die Beispiele gefunden, die am schwierigsten zu klassifizieren sind, und weitere neue Punkte rund um diese hervorgebracht. Dies hilft dem Modell, die herausfordernden Bereiche besser zu verstehen.

👍 Am besten, wenn einige Teile Ihrer Daten schwerer zu klassifizieren sind als andere
👍 Am besten für komplexe Datensätze mit anspruchsvollen Bereichen geeignet
👎 Nicht empfohlen, wenn Ihre Daten recht einfach und unkompliziert sind

ADASYN erstellt mehr synthetische Punkte aus der kleineren Gruppe (A) in „schwierigen Bereichen“, in denen A-Punkte nahe an anderen Gruppen (B und C) liegen. Es generiert auch neue B-Punkte in ähnlichen Bereichen.

Durch Unterabtastung wird die größere Gruppe verkleinert, um sie in ihrer Größe der kleineren Gruppe anzunähern. Es gibt verschiedene Möglichkeiten, dies zu tun:

Zufällige Unterabtastung

Zufällige Unterabtastung Entfernt Beispiele aus der größeren Gruppe nach dem Zufallsprinzip, bis sie die gleiche Größe wie die kleinere Gruppe haben. Genau wie die zufällige Überabtastung ist die Methode ziemlich einfach, aber sie kann wichtige Informationen vernichten, die wirklich zeigen, wie unterschiedlich die Gruppen sind.

👍 Am besten für sehr große Datensätze mit vielen sich wiederholenden Beispielen geeignet
👍 Am besten, wenn Sie eine schnelle, einfache Lösung benötigen
👎 Nicht empfohlen, wenn jedes Beispiel in Ihrer größeren Gruppe wichtig ist
👎 Nicht empfohlen, wenn Sie es sich nicht leisten können, Informationen zu verlieren

Bei der zufälligen Unterabtastung werden zufällig ausgewählte Punkte aus den größeren Gruppen (B und C) entfernt, während alle Punkte aus der kleineren Gruppe (A) unverändert bleiben.

Tomek-Hyperlinks

Tomek-Hyperlinks ist eine Unterabtastungsmethode, die die „Linien“ zwischen Gruppen klarer macht. Es wird nach Paaren von Beispielen aus verschiedenen Gruppen gesucht, die wirklich ähnlich sind. Wenn ein Paar gefunden wird, bei dem die Beispiele die nächsten Nachbarn des anderen sind, aber zu unterschiedlichen Gruppen gehören, wird das Beispiel aus der größeren Gruppe entfernt.

👍 Am besten, wenn sich Ihre Gruppen zu sehr überschneiden
👍 Am besten zum Bereinigen unordentlicher oder verrauschter Daten geeignet
👍 Am besten, wenn Sie klare Grenzen zwischen Gruppen benötigen
👎 Nicht empfohlen, wenn Ihre Gruppen bereits intestine getrennt sind

Tomek Hyperlinks identifiziert Punktepaare aus verschiedenen Gruppen (AB, BC), die einander am nächsten liegen. Punkte aus den größeren Gruppen (B und C), die diese Paare bilden, werden dann entfernt, während alle Punkte aus der kleineren Gruppe (A) behalten werden.“

Beinahe verfehlt

Beinahe verfehlt ist eine Reihe von Unterabtastungstechniken, die nach unterschiedlichen Regeln arbeiten:

  • Quick Miss-1: Behält Beispiele aus der größeren Gruppe bei, die den Beispielen in der kleineren Gruppe am nächsten kommen.
  • Quick Miss-2: Behält Beispiele aus der größeren Gruppe bei, die den geringsten durchschnittlichen Abstand zu ihren drei nächsten Nachbarn in der kleineren Gruppe haben.
  • Quick Miss-3: Behält Beispiele aus der größeren Gruppe bei, die am weitesten von anderen Beispielen in ihrer eigenen Gruppe entfernt sind.

Die Hauptidee besteht darin, die informativsten Beispiele aus der größeren Gruppe zu behalten und diejenigen zu entfernen, die nicht so wichtig sind.

👍 Am besten, wenn Sie die Kontrolle darüber haben möchten, welche Beispiele Sie behalten möchten
👎 Nicht empfohlen, wenn Sie eine einfache, schnelle Lösung benötigen

NearMiss-1 behält Punkte von den größeren Gruppen (B und C), die der kleineren Gruppe (A) am nächsten liegen, während der Relaxation entfernt wird. Hier werden nur die B- und C-Punkte beibehalten, die den A-Punkten am nächsten liegen.

ENN

Nächste Nachbarn bearbeitet (ENN)-Methode entfernt Beispiele, bei denen es sich wahrscheinlich um Rauschen oder Ausreißer handelt. Für jedes Beispiel in der größeren Gruppe prüft es, ob die meisten seiner nächsten Nachbarn derselben Gruppe angehören. Ist dies nicht der Fall, wird das Beispiel entfernt. Dies trägt dazu bei, klarere Grenzen zwischen den Gruppen zu schaffen.

👍 Am besten zum Bereinigen unordentlicher Daten geeignet
👍 Am besten, wenn Sie Ausreißer entfernen müssen
👍 Am besten geeignet, um klarere Gruppengrenzen zu schaffen
👎 Nicht empfohlen, wenn Ihre Daten bereits sauber und intestine organisiert sind

ENN entfernt Punkte aus größeren Gruppen (B und C), deren nächste Nachbarn mehrheitlich zu einer anderen Gruppe gehören. Im rechten Diagramm werden durchgestrichene Punkte entfernt, da die meisten ihrer nächsten Nachbarn aus anderen Gruppen stammen.

SMOTETomek

SMOTETomek funktioniert, indem zunächst mit SMOTE neue Beispiele für die kleinere Gruppe erstellt werden und dann unordentliche Grenzen aufgeräumt werden, indem „verwirrende“ Beispiele mithilfe von Tomek Hyperlinks entfernt werden. Dies trägt dazu bei, einen ausgewogeneren Datensatz mit klareren Grenzen und weniger Rauschen zu erstellen.

👍 Am besten für unausgeglichene Daten geeignet, die wirklich schwerwiegend sind
👍 Am besten, wenn Sie sowohl mehr Beispiele als auch klarere Grenzen benötigen
👍 Am besten geeignet, wenn es um laute, sich überschneidende Gruppen geht
👎 Nicht empfohlen, wenn Ihre Daten bereits sauber und intestine organisiert sind
👎 Nicht für kleine Datensätze empfohlen

SMOTETomek kombiniert zwei Schritte: Zuerst wird SMOTE angewendet, um neue A-Punkte entlang von Linien zwischen vorhandenen A-Punkten zu erstellen (dargestellt im mittleren Diagramm), und dann werden Tomek-Hyperlinks aus größeren Gruppen (B und C) entfernt. Das Endergebnis weist ausgeglichenere Gruppen mit klareren Grenzen zwischen ihnen auf.

SMOTEENN

SMOTEENN funktioniert, indem zunächst mit SMOTE neue Beispiele für die kleinere Gruppe erstellt werden und dann mit ENN beide Gruppen bereinigt werden, indem Beispiele entfernt werden, die nicht intestine zu ihren Nachbarn passen. Genau wie SMOTETomek trägt dies dazu bei, einen saubereren Datensatz mit klareren Grenzen zwischen den Gruppen zu erstellen.

👍 Am besten zum gleichzeitigen Aufräumen beider Gruppen
👍 Am besten, wenn Sie mehr Beispiele, aber sauberere Daten benötigen
👍 Am besten, wenn es um viele Ausreißer geht
👎 Nicht empfohlen, wenn Ihre Daten bereits sauber und intestine organisiert sind
👎 Nicht für kleine Datensätze empfohlen

SMOTEENN kombiniert zwei Schritte: Zuerst wird SMOTE verwendet, um neue A-Punkte entlang von Linien zwischen vorhandenen A-Punkten zu erstellen (mittleres Diagramm), dann wird ENN angewendet, um Punkte aus größeren Gruppen (B und C) zu entfernen, deren nächste Nachbarn größtenteils aus unterschiedlichen Gruppen stammen. Das endgültige Diagramm zeigt den bereinigten, ausgeglichenen Datensatz.

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/ueberabtastung-und-unterabtastung-erklaert-ein-visueller-leitfaden-mit-mini-2d-datensatz-von-samy-baladram-okt-2024/feed/ 0 4809
Gaußsche Naive Bayes, erklärt: Ein visueller Leitfaden mit Codebeispielen für Anfänger | von Samy Baladram | Okt. 2024 https://chatgpz.de/artificial-intelligence/gausssche-naive-bayes-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-okt-2024/ https://chatgpz.de/artificial-intelligence/gausssche-naive-bayes-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-okt-2024/#respond Sat, 12 Oct 2024 01:08:51 +0000 https://chatgpz.de/artificial-intelligence/gausssche-naive-bayes-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-okt-2024/ [ad_1]

KLASSIFIZIERUNGSALGORITHMUS

Glockenförmige Annahmen für bessere Vorhersagen

Bernoulli NB geht von Binärdaten aus, Multinomial NB arbeitet mit diskreten Zählungen und Gaußian NB verarbeitet kontinuierliche Daten unter der Annahme einer Normalverteilung.

Aufbauend auf unserem vorherigen Artikel über Bernoulli Naive Bayesdas Binärdaten verarbeitet, untersuchen wir nun Gaussian Naive Bayes für kontinuierliche Daten. Im Gegensatz zum binären Ansatz geht dieser Algorithmus davon aus, dass jedes Merkmal einer Normalverteilung (Gaußverteilung) folgt.

Hier werden wir sehen, wie Gaussian Naive Bayes mit kontinuierlichen, glockenförmigen Daten umgeht und genaue Vorhersagen liefert ohne in die komplizierte Mathematik einzusteigen des Satzes von Bayes.

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

Wie andere Naive-Bayes-Varianten geht Gaussian Naive Bayes von der „naiven“ Annahme der Merkmalsunabhängigkeit aus. Es wird davon ausgegangen, dass die Options angesichts der Klassenbezeichnung bedingt unabhängig sind.

Während Bernoulli Naive Bayes jedoch für Datensätze mit binären Merkmalen geeignet ist, geht Gaußian Naive Bayes davon aus, dass die Merkmale folgen eine kontinuierliche Normale (Gaussian) Verteilung. Auch wenn diese Annahme in der Realität nicht immer zutrifft, vereinfacht sie die Berechnungen und führt oft zu überraschend genauen Ergebnissen.

Naive Bayes-Methoden sind ein probabilistisches Modell im maschinellen Lernen, das Wahrscheinlichkeitsfunktionen verwendet, um Vorhersagen zu treffen.

In diesem Artikel verwenden wir diesen künstlichen Golfdatensatz (vom Autor erstellt) als Beispiel. Dieser Datensatz sagt anhand der Wetterbedingungen voraus, ob eine Individual Golf spielen wird.

Spalten: „RainfallAmount“ (in mm), „Temperatur“ (in Celsius), „Luftfeuchtigkeit“ (in %), „WindSpeed“ (in km/h) und „Play“ (Ja/Nein, Zielfunktion)
# IMPORTING DATASET #
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np

dataset_dict = {
'Rainfall': (0.0, 2.0, 7.0, 18.0, 3.0, 3.0, 0.0, 1.0, 0.0, 25.0, 0.0, 18.0, 9.0, 5.0, 0.0, 1.0, 7.0, 0.0, 0.0, 7.0, 5.0, 3.0, 0.0, 2.0, 0.0, 8.0, 4.0, 4.0),
'Temperature': (29.4, 26.7, 28.3, 21.1, 20.0, 18.3, 17.8, 22.2, 20.6, 23.9, 23.9, 22.2, 27.2, 21.7, 27.2, 23.3, 24.4, 25.6, 27.8, 19.4, 29.4, 22.8, 31.1, 25.0, 26.1, 26.7, 18.9, 28.9),
'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),
'WindSpeed': (2.1, 21.2, 1.5, 3.3, 2.0, 17.4, 14.9, 6.9, 2.7, 1.6, 30.3, 10.9, 3.0, 7.5, 10.3, 3.0, 3.9, 21.9, 2.6, 17.3, 9.6, 1.9, 16.0, 4.6, 3.2, 8.3, 3.2, 2.2),
'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')
}
df = pd.DataFrame(dataset_dict)

# Set characteristic matrix X and goal vector y
X, y = df.drop(columns='Play'), df('Play')

# Break up the information into coaching and testing units
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)
print(pd.concat((X_train, y_train), axis=1), finish='nn')
print(pd.concat((X_test, y_test), axis=1))

Gaussian Naive Bayes arbeitet mit kontinuierlichen Daten und geht davon aus, dass jedes Merkmal einer Gaußschen (Regular-)Verteilung folgt.

  1. Berechnen Sie die Wahrscheinlichkeit jeder Klasse in den Trainingsdaten.
  2. Schätzen Sie für jedes Merkmal und jede Klasse den Mittelwert und die Varianz der Merkmalswerte innerhalb dieser Klasse.
  3. Für eine neue Instanz:
    A. Berechnen Sie für jede Klasse die Wahrscheinlichkeitsdichtefunktion (PDF) jedes Merkmalswerts unter der Gaußschen Verteilung dieses Merkmals innerhalb der Klasse.
    B. Multiplizieren Sie die Klassenwahrscheinlichkeit mit dem Produkt der PDF-Werte für alle Options.
  4. Sagen Sie die Klasse mit der höchsten resultierenden Wahrscheinlichkeit voraus.
Gaussian Naive Bayes verwendet die Normalverteilung, um die Wahrscheinlichkeit unterschiedlicher Merkmalswerte für jede Klasse zu modellieren. Anschließend werden diese Wahrscheinlichkeiten kombiniert, um eine Vorhersage zu treffen.

Transformieren nicht-gaußscher verteilter Daten

Denken Sie daran, dass dieser Algorithmus naiv davon ausgeht, dass alle Eingabemerkmale eine Gauß-/Normalverteilung aufweisen?

Da wir uns über die Verteilung unserer Daten nicht wirklich sicher sind, insbesondere bei Merkmalen, die eindeutig keiner Gaußschen Verteilung folgen, wenden wir a an Machttransformation (wie Field-Cox) vor der Verwendung von Gaussian Naive Bayes kann von Vorteil sein. Dieser Ansatz kann dazu beitragen, die Daten gaußähnlicher zu machen, was besser mit den Annahmen des Algorithmus übereinstimmt.

Alle Spalten werden mittels Energy Transformation (Field-Cox Transformation) skaliert und anschließend standardisiert.
from sklearn.preprocessing import PowerTransformer

# Initialize and match the PowerTransformer
pt = PowerTransformer(standardize=True) # Commonplace Scaling already included
X_train_transformed = pt.fit_transform(X_train)
X_test_transformed = pt.rework(X_test)

Jetzt sind wir bereit für das Coaching.

1. Berechnung der Klassenwahrscheinlichkeit: Berechnen Sie für jede Klasse ihre Wahrscheinlichkeit: (Anzahl der Instanzen in dieser Klasse) / (Gesamtzahl der Instanzen)

from fractions import Fraction

def calc_target_prob(attr):
total_counts = attr.value_counts().sum()
prob_series = attr.value_counts().apply(lambda x: Fraction(x, total_counts).limit_denominator())
return prob_series

print(calc_target_prob(y_train))

2. Characteristic-Wahrscheinlichkeitsberechnung : Berechnen Sie für jedes Merkmal und jede Klasse den Mittelwert (μ) und die Standardabweichung (σ) der Merkmalswerte innerhalb dieser Klasse anhand der Trainingsdaten. Berechnen Sie dann die Wahrscheinlichkeit mithilfe der Gaußschen Wahrscheinlichkeitsdichtefunktion (PDF)-Formel.

Bestimmen Sie für jede Wetterbedingung den Mittelwert und die Standardabweichung für die Fälle „JA“ und „NEIN“. Berechnen Sie dann ihre PDF mithilfe der PDF-Formel für die Regular-/Gaußverteilung.
Der gleiche Vorgang wird auf alle anderen Funktionen angewendet.
def calculate_class_probabilities(X_train_transformed, y_train, feature_names):
courses = y_train.distinctive()
equations = pd.DataFrame(index=courses, columns=feature_names)

for cls in courses:
X_class = X_train_transformed(y_train == cls)
imply = X_class.imply(axis=0)
std = X_class.std(axis=0)
k1 = 1 / (std * np.sqrt(2 * np.pi))
k2 = 2 * (std ** 2)

for i, column in enumerate(feature_names):
equation = f"{k1(i):.3f}·exp(-(x-({imply(i):.2f}))²/{k2(i):.3f})"
equations.loc(cls, column) = equation

return equations

# Use the operate with the reworked coaching knowledge
equation_table = calculate_class_probabilities(X_train_transformed, y_train, X.columns)

# Show the equation desk
print(equation_table)

3. Glätten: Gaussian Naive Bayes verwendet einen einzigartigen Glättungsansatz. Im Gegensatz zur Laplace-Glättung in anderen Variantenfügt es allen Varianzen einen winzigen Wert (0,000000001-mal die größte Varianz) hinzu. Dies verhindert numerische Instabilität durch Division durch Null oder sehr kleine Zahlen.

Gegeben eine neue Instanz mit kontinuierlichen Funktionen:

1. Wahrscheinlichkeitssammlung:
Für jede mögliche Klasse:
· Beginnen Sie mit der Wahrscheinlichkeit des Auftretens dieser Klasse (Klassenwahrscheinlichkeit).
· Berechnen Sie für jedes Characteristic in der neuen Instanz die Wahrscheinlichkeitsdichtefunktion dieses Options innerhalb der Klasse.

Für ID 14 berechnen wir das PDF jedes Merkmals sowohl für „JA“ als auch für „NEIN“-Instanzen.

2. Punkteberechnung und -vorhersage:
Für jede Klasse:
· Multiplizieren Sie alle gesammelten PDF-Werte miteinander.
· Das Ergebnis ist die Punktzahl für diese Klasse.
· Die Klasse mit der höchsten Punktzahl ist die Vorhersage.

from scipy.stats import norm

def calculate_class_probability_products(X_train_transformed, y_train, X_new, feature_names, target_name):
courses = y_train.distinctive()
n_features = X_train_transformed.form(1)

# Create column names utilizing precise characteristic names
column_names = (target_name) + listing(feature_names) + ('Product')

probability_products = pd.DataFrame(index=courses, columns=column_names)

for cls in courses:
X_class = X_train_transformed(y_train == cls)
imply = X_class.imply(axis=0)
std = X_class.std(axis=0)

prior_prob = np.imply(y_train == cls)
probability_products.loc(cls, target_name) = prior_prob

feature_probs = ()
for i, characteristic in enumerate(feature_names):
prob = norm.pdf(X_new(0, i), imply(i), std(i))
probability_products.loc(cls, characteristic) = prob
feature_probs.append(prob)

product = prior_prob * np.prod(feature_probs)
probability_products.loc(cls, 'Product') = product

return probability_products

# Assuming X_new is your new pattern reshaped to (1, n_features)
X_new = np.array((-1.28, 1.115, 0.84, 0.68)).reshape(1, -1)

# Calculate likelihood merchandise
prob_products = calculate_class_probability_products(X_train_transformed, y_train, X_new, X.columns, y.title)

# Show the likelihood product desk
print(prob_products)

Für diesen speziellen Datensatz wird diese Genauigkeit als recht intestine angesehen.
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score

# Initialize and prepare the Gaussian Naive Bayes mannequin
gnb = GaussianNB()
gnb.match(X_train_transformed, y_train)

# Make predictions on the take a look at set
y_pred = gnb.predict(X_test_transformed)

# Calculate the accuracy
accuracy = accuracy_score(y_test, y_pred)

# Print the accuracy
print(f"Accuracy: {accuracy:.4f}")

GaussianNB ist für seine Einfachheit und Wirksamkeit bekannt. Das Wichtigste, was Sie bei seinen Parametern beachten sollten, ist:

  1. Prioren: Dies ist der bemerkenswerteste Parameter, ähnlich wie Bernoulli Naive Bayes. In den meisten Fällen müssen Sie es nicht manuell festlegen. Standardmäßig wird es aus Ihren Trainingsdaten berechnet, was oft intestine funktioniert.
  2. var_smoothing: Dies ist ein Stabilitätsparameter, den Sie selten anpassen müssen. (Der Standardwert ist 0,000000001)

Die wichtigste Erkenntnis ist, dass dieser Algorithmus so konzipiert ist, dass er sofort funktioniert. In den meisten Situationen können Sie es verwenden, ohne sich Gedanken über die Parameterabstimmung machen zu müssen.

Vorteile:

  1. Einfachheit: Behält die einfach zu implementierende und verständliche Eigenschaft bei.
  2. Effizienz: Bleibt beim Coaching und bei der Vorhersage schnell und eignet sich daher für umfangreiche Anwendungen mit kontinuierlichen Funktionen.
  3. Flexibilität mit Daten: Bewältigt sowohl kleine als auch große Datensätze intestine und passt sich dem Umfang des jeweiligen Issues an.
  4. Kontinuierliches Characteristic-Dealing with: Gedeiht mit kontinuierlichen und realwertigen Options und eignet sich daher excellent für Aufgaben wie die Vorhersage realwertiger Ausgaben oder die Arbeit mit Daten, bei denen Options auf einem Kontinuum variieren.

Nachteile:

  1. Unabhängigkeitsannahme: Geht immer noch davon aus, dass Options angesichts der Klasse bedingt unabhängig sind, was möglicherweise nicht in allen realen Szenarien zutrifft.
  2. Annahme der Gaußschen Verteilung: Funktioniert am besten, wenn Merkmalswerte tatsächlich einer Normalverteilung folgen. Nicht-Normalverteilungen können zu einer suboptimalen Leistung führen (können jedoch mit der von uns besprochenen Energy Transformation behoben werden).
  3. Empfindlichkeit gegenüber Ausreißern: Kann durch Ausreißer in den Trainingsdaten erheblich beeinträchtigt werden, da sie die Mittelwert- und Varianzberechnungen verzerren.

Gaussian Naive Bayes ist ein effizienter Klassifikator für eine Vielzahl von Anwendungen mit kontinuierlichen Daten. Seine Fähigkeit, realwertige Funktionen zu verarbeiten, reicht über die Verwendung binärer Klassifizierungsaufgaben hinaus und macht es zu einer ersten Wahl für zahlreiche Anwendungen.

Es werden zwar einige Annahmen über Daten getroffen (Merkmalsunabhängigkeit und Normalverteilung), aber wenn diese Bedingungen erfüllt sind, bietet es eine robuste Leistung, was es aufgrund seines Gleichgewichts zwischen Einfachheit und Leistungsfähigkeit sowohl bei Anfängern als auch bei erfahrenen Datenwissenschaftlern zu einem Favoriten macht.

import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.preprocessing import PowerTransformer
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

# Load the dataset
dataset_dict = {
'Rainfall': (0.0, 2.0, 7.0, 18.0, 3.0, 3.0, 0.0, 1.0, 0.0, 25.0, 0.0, 18.0, 9.0, 5.0, 0.0, 1.0, 7.0, 0.0, 0.0, 7.0, 5.0, 3.0, 0.0, 2.0, 0.0, 8.0, 4.0, 4.0),
'Temperature': (29.4, 26.7, 28.3, 21.1, 20.0, 18.3, 17.8, 22.2, 20.6, 23.9, 23.9, 22.2, 27.2, 21.7, 27.2, 23.3, 24.4, 25.6, 27.8, 19.4, 29.4, 22.8, 31.1, 25.0, 26.1, 26.7, 18.9, 28.9),
'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),
'WindSpeed': (2.1, 21.2, 1.5, 3.3, 2.0, 17.4, 14.9, 6.9, 2.7, 1.6, 30.3, 10.9, 3.0, 7.5, 10.3, 3.0, 3.9, 21.9, 2.6, 17.3, 9.6, 1.9, 16.0, 4.6, 3.2, 8.3, 3.2, 2.2),
'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')
}

df = pd.DataFrame(dataset_dict)

# Put together knowledge for mannequin
X, y = df.drop('Play', axis=1), (df('Play') == 'Sure').astype(int)

# Break up knowledge into coaching and testing units
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, shuffle=False)

# Apply PowerTransformer
pt = PowerTransformer(standardize=True)
X_train_transformed = pt.fit_transform(X_train)
X_test_transformed = pt.rework(X_test)

# Prepare the mannequin
nb_clf = GaussianNB()
nb_clf.match(X_train_transformed, y_train)

# Make predictions
y_pred = nb_clf.predict(X_test_transformed)

# Verify accuracy
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/gausssche-naive-bayes-erklaert-ein-visueller-leitfaden-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-okt-2024/feed/ 0 4481
Skalierung numerischer Daten, erklärt: Eine visuelle Anleitung mit Codebeispielen für Anfänger | von Samy Baladram | September 2024 https://chatgpz.de/artificial-intelligence/skalierung-numerischer-daten-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-september-2024/ https://chatgpz.de/artificial-intelligence/skalierung-numerischer-daten-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-september-2024/#respond Fri, 06 Sep 2024 07:19:33 +0000 http://chatgpz.de/artificial-intelligence/skalierung-numerischer-daten-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-september-2024/ [ad_1]

DATENVORVERARBEITUNG

Daten im Erwachsenenformat für kindliche Modelle umwandeln

Numerische Merkmale in Rohdatensätzen sind wie Erwachsene in einer Welt, die für Erwachsene geschaffen wurde. Einige ragen wie Wolkenkratzer empor (denken Sie an Milliardenumsätze), während andere kaum sichtbar sind (wie Wahrscheinlichkeiten von 0,001). Aber unsere Modelle für maschinelles Lernen? Sie sind Kinder, die sich bemühen, diese Welt der Erwachsenen zu verstehen.

Bei der Datenskalierung (auch „Normalisierung“ genannt) handelt es sich um den Prozess, diese Zahlen in Erwachsenengröße in kindgerechte Proportionen umzuwandeln. Es geht darum, gleiche Bedingungen zu schaffen, bei denen jedes Merkmal, ob groß oder klein, verstanden und angemessen bewertet werden kann.

Wir werden uns fünf verschiedene Skalierungstechniken ansehen, die alle anhand eines kleinen Datensatzes demonstriert werden (natürlich mit einigen visuellen Elementen). Von der sanften Normalisierung bis hin zur mathematischen Akrobatik der Field-Cox-Transformation werden Sie sehen, warum die Wahl der richtigen Skalierungsmethode die Geheimzutat für Ihr maschinelles Lernrezept sein kann.

Alle Bilder: Vom Autor mit Canva Professional erstellt. Für Mobilgeräte optimiert; kann auf dem Desktop übergroß erscheinen.

Bevor wir auf die Einzelheiten der Skalierungstechniken eingehen, sollten wir verstehen, welche Datentypen von der Skalierung profitieren und welche nicht:

Daten, die normalerweise nicht skaliert werden müssen:

  1. Kategoriale Variablen: Diese sollten normalerweise kodiert und nicht skaliert werden. Dies umfasst sowohl nominale als auch ordinale kategorische Daten.
  2. Binäre Variablen: Options, die nur zwei Werte annehmen können (0 und 1 oder Wahr und Falsch), müssen im Allgemeinen nicht skaliert werden.
  3. Zähldaten: Ganzzahlige Zählungen sind oft so, wie sie sind, sinnvoll und durch Skalierung können sie schwerer verständlich werden. Behandeln Sie sie stattdessen als kategorisch. Es gibt einige Ausnahmen, insbesondere bei sehr großen Zählbereichen.
  4. Zyklische Merkmale: Daten mit zyklischer Natur (wie Wochentage oder Monate des Jahres) profitieren häufig mehr von der zyklischen Kodierung als von Standardskalierungstechniken.

Daten, die normalerweise skaliert werden müssen:

  1. Kontinuierliche numerische Merkmale mit großen Bereichen: Options, die einen weiten Wertebereich annehmen können, profitieren häufig von einer Skalierung, um zu verhindern, dass sie andere Options im Modell dominieren.
  2. In unterschiedlichen Einheiten gemessene Merkmale: Wenn Ihr Datensatz Merkmale enthält, die in unterschiedlichen Einheiten gemessen werden (z. B. Meter, Kilogramm, Jahre), hilft die Skalierung dabei, sie auf eine vergleichbare Skala zu bringen.
  3. Merkmale mit deutlich unterschiedlichen Ausmaßen: Wenn einige Options Werte im Tausenderbereich haben, während andere zwischen 0 und 1 liegen, kann die Skalierung dabei helfen, ihren Einfluss auf das Modell auszugleichen.
  4. Prozent- oder Verhältnisfunktionen: Obwohl diese bereits auf einer festen Skala basieren (normalerweise 0–100 oder 0–1), kann eine Skalierung dennoch von Vorteil sein, insbesondere wenn sie zusammen mit Funktionen mit viel größeren Bereichen verwendet wird.
  5. Begrenzte kontinuierliche Options: Options mit einem bekannten Minimal und Most profitieren häufig von der Skalierung, insbesondere wenn ihr Bereich sich erheblich von anderen Options im Datensatz unterscheidet.
  6. Schiefe Verteilungen: Options mit stark schiefen Verteilungen profitieren häufig von bestimmten Arten der Skalierung oder Transformation, um sie normaler zu verteilen und die Modellleistung zu verbessern.

Jetzt fragen Sie sich vielleicht: „Warum überhaupt skalieren? Können wir die Daten nicht einfach so lassen?“ Tatsächlich funktionieren viele Algorithmen des maschinellen Lernens am besten, wenn alle Merkmale auf einer ähnlichen Skala liegen. Aus diesen Gründen ist Skalierung erforderlich:

  1. Gleiche Merkmalswichtigkeit: Nicht skalierte Merkmale können das Modell versehentlich dominieren. Beispielsweise kann die Windgeschwindigkeit (0–50 km/h) die Temperatur (10–35 °C) überschatten, und zwar einfach aufgrund ihres größeren Maßstabs und nicht, weil sie wichtiger ist.
  2. Schnellere Konvergenz: Viele beim maschinellen Lernen verwendete Optimierungsalgorithmen konvergieren schneller, wenn die Merkmale eine ähnliche Größenordnung aufweisen.
  3. Verbesserte Algorithmusleistung: Einige Algorithmen, wie Okay-Nearest Neighbors und Neuronale Netzwerke, erfordern ausdrücklich skalierte Daten, um eine gute Leistung zu erzielen.
  4. Interpretierbarkeit: Skalierte Koeffizienten in linearen Modellen sind einfacher zu interpretieren und zu vergleichen.
  5. Vermeidung numerischer Instabilität: Sehr große oder sehr kleine Werte können bei einigen Algorithmen zu numerischer Instabilität führen.

Nachdem wir nun wissen, welche numerischen Daten skaliert werden müssen und warum, werfen wir einen Blick auf unseren Datensatz und sehen, wie wir seine numerischen Variablen mithilfe von fünf verschiedenen Skalierungsmethoden skalieren können. Es geht nicht nur um Skalierung – es geht darum, richtig zu skalieren.

Bevor wir uns mit den Skalierungstechniken befassen, sehen wir uns unseren Datensatz an. Wir werden mit Daten von diesem fiktiven Golfclub arbeiten.

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
from scipy import stats

# Learn the info
information = {
'Temperature_Celsius': (15, 18, 22, 25, 28, 30, 32, 29, 26, 23, 20, 17),
'Humidity_Percent': (50, 55, 60, 65, 70, 75, 80, 72, 68, 62, 58, 52),
'Wind_Speed_kmh': (5, 8, 12, 15, 10, 7, 20, 18, 14, 9, 6, 11),
'Golfers_Count': (20, 35, 50, 75, 100, 120, 90, 110, 85, 60, 40, 25),
'Green_Speed': (8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 11.0, 10.5, 10.0, 9.5, 9.0)
}

df = pd.DataFrame(information)

Dieser Datensatz ist perfekt für unsere Skalierungsaufgaben, da er Options mit unterschiedlichen Einheiten, Skalen und Verteilungen enthält.

Lassen Sie uns jetzt auf alle Skalierungsmethoden eingehen.

Die Min-Max-Skalierung transformiert alle Werte in einen festen Bereich, normalerweise zwischen 0 und 1, indem der Minimalwert subtrahiert und durch den Bereich dividiert wird.

📊 Gängige Datentypen: Options mit einem breiten Wertebereich, für die ein bestimmter Bereich gewünscht wird.

🎯 Ziele:
–
Beschränken Sie Funktionen auf einen bestimmten Bereich (z. B. 0 bis 1).
– Bewahren Sie die ursprünglichen Beziehungen zwischen den Datenpunkten.
– Sicherstellung der Interpretierbarkeit skalierter Werte.

In unserem Fall: Wir wenden dies auf die Temperatur an, da die Temperatur in unserem Golfkontext ein natürliches Minimal und Most hat. Dabei bleiben die relativen Unterschiede zwischen den Temperaturen erhalten, sodass 0 der kälteste Tag, 1 der heißeste und 0,5 ein Tag mit durchschnittlicher Temperatur ist.

# 1. Min-Max Scaling for Temperature_Celsius
min_max_scaler = MinMaxScaler()
df('Temperature_MinMax') = min_max_scaler.fit_transform(df(('Temperature_Celsius')))

Bei der Standardskalierung werden die Daten um einen Mittelwert von 0 zentriert und auf eine Standardabweichung von 1 skaliert. Dies wird durch Subtrahieren des Mittelwerts und Division durch die Standardabweichung erreicht.

📊 Gängige Datentypen: Merkmale mit unterschiedlichen Maßstäben und Verteilungen.

🎯 Ziele:
–
Standardisieren Sie die Merkmale so, dass sie einen Mittelwert von 0 und eine Standardabweichung von 1 haben.
– Stellen Sie sicher, dass Options mit unterschiedlichen Maßstäben gleichermaßen zu einem Modell beitragen.
– Bereiten Sie Daten für Algorithmen vor, die auf Merkmalsskalen reagieren (z. B. SVM, KNN).

In unserem Fall: Wir verwenden dies für die Windgeschwindigkeit, da die Windgeschwindigkeit häufig einer annähernd normalen Verteilung folgt. So können wir außergewöhnlich ruhige oder windige Tage ganz einfach anhand der Anzahl ihrer Standardabweichungen vom Mittelwert identifizieren.

# 2. Normal Scaling for Wind_Speed_kmh
std_scaler = StandardScaler()
df('Wind_Speed_Standardized') = std_scaler.fit_transform(df(('Wind_Speed_kmh')))

Bei der robusten Skalierung werden die Daten um den Median zentriert und mithilfe des Interquartilsabstands (IQR) skaliert.

📊 Gängige Datentypen: Options mit Ausreißern oder verrauschten Daten.

🎯 Ziele:
–
Gehen Sie effektiv mit Ausreißern um, ohne sich zu sehr von ihnen beeinflussen zu lassen.
– Behalten Sie die relative Reihenfolge der Datenpunkte bei.
– Erreichen Sie eine stabile Skalierung bei verrauschten Daten.

In unserem Fall: Wir wenden dies auf die Luftfeuchtigkeit an, da Luftfeuchtigkeitswerte aufgrund extremer Wetterbedingungen oder Messfehler Ausreißer aufweisen können. Diese Skalierung stellt sicher, dass unsere Messungen weniger empfindlich auf diese Ausreißer reagieren.

# 3. Sturdy Scaling for Humidity_Percent
robust_scaler = RobustScaler()
df('Humidity_Robust') = robust_scaler.fit_transform(df(('Humidity_Percent')))

Bisher haben wir uns einige Möglichkeiten zum Skalieren von Daten angesehen. Lassen Sie uns nun einen anderen Ansatz untersuchen – die Verwendung von Transformationen zum Skalieren, beginnend mit der gängigen Technik der Log-Transformation.

Dabei wird eine logarithmische Funktion auf die Daten angewendet, die den Maßstab sehr großer Werte komprimiert.

📊 Gängige Datentypen:
– Rechtsschiefe Daten (Lengthy Tail).
– Daten zählen.
– Daten mit multiplikativen Beziehungen.

🎯 Ziele:
–
Beheben Sie die Rechtsschiefe und normalisieren Sie die Verteilung.
– Stabilisieren Sie die Varianz über den gesamten Funktionsbereich.
– Verbessern Sie die Modellleistung für Daten mit diesen Eigenschaften.

In unserem Fall: Wir verwenden dies für die Anzahl der Golfer, da die Zähldaten häufig einer rechtsschiefen Verteilung folgen. Dadurch ist der Unterschied zwischen 10 und 20 Golfern signifikanter als zwischen 100 und 110, was den tatsächlichen Auswirkungen dieser Unterschiede entspricht.

# 4. Log Transformation for Golfers_Count
df('Golfers_Log') = np.log1p(df('Golfers_Count'))

Hierbei handelt es sich um eine Familie von Potenztransformationen (zu der als Spezialfall auch die Log-Transformation gehört), deren Ziel die Normalisierung der Datenverteilung durch die Anwendung einer Potenztransformation mit dem Parameter Lambda (λ) ist, der zur Erreichung der gewünschten Normalität optimiert ist.

Allgemeine Datentypen: Merkmale, die normalisiert werden müssen, um eine Normalverteilung anzunähern.

🎯 Ziele:
–
Normalisieren Sie die Verteilung eines Options.
– Verbessern Sie die Leistung von Modellen, die regular verteilte Daten voraussetzen.
– Varianz stabilisieren und möglicherweise die Linearität verbessern.

In unserem Fall: Wir wenden dies auf Inexperienced Pace ​​an, da es eine komplexe Verteilung haben könnte, die sich mit einfacheren Methoden nicht leicht normalisieren lässt. So können uns die Daten zur am besten geeigneten Transformation führen und möglicherweise ihre Beziehungen zu anderen Variablen verbessern.

# 5. Field-Cox Transformation for Green_Speed
df('Green_Speed_BoxCox'), lambda_param = stats.boxcox(df('Green_Speed'))

Nach der Durchführung der Transformation ist es auch üblich, sie weiter zu skalieren, damit sie einer bestimmten Verteilung folgt (wie regular). Wir können dies mit beiden transformierten Spalten tun, die wir hatten.


df('Golfers_Count_Log') = np.log1p(df('Golfers_Count'))
df('Golfers_Count_Log_std') = standard_scaler.fit_transform(df(('Golfers_Count_Log')))

box_cox_transformer = PowerTransformer(methodology='box-cox') # By default already has standardizing
df('Green_Speed_BoxCox') = box_cox_transformer.fit_transform(df(('Green_Speed')))print("nBox-Cox lambda parameter:", lambda_param)
print("nBox-Cox lambda parameter:", lambda_param)

Das warfare’s additionally. Fünf verschiedene Skalierungstechniken, alle auf unseren Golfplatz-Datensatz angewendet. Jetzt sind alle numerischen Merkmale transformiert und bereit für maschinelle Lernmodelle.

Hier ist eine kurze Zusammenfassung jeder Methode und ihrer Anwendung:

  • Min-Max-Skalierung: Auf die Temperatur angewendet, wobei die Werte für eine bessere Interpretierbarkeit des Modells auf einen Bereich von 0–1 normalisiert werden.
  • Standardskalierung: Wird für die Windgeschwindigkeit verwendet. Die Verteilung wird standardisiert, um die Auswirkungen extremer Werte zu reduzieren.
  • Robuste Skalierung: Wird auf die Luftfeuchtigkeit angewendet, um potenzielle Ausreißer zu verarbeiten und ihre Auswirkungen auf die Modellleistung zu reduzieren.
  • Log-Transformation: Wird für „Golfers Depend“ verwendet, um rechtsschiefe Zähldaten zu normalisieren und die Modellstabilität zu verbessern.
  • Field-Cox-Transformation: Wird auf Inexperienced Pace ​​angewendet, um die Verteilung normalähnlicher zu gestalten, was häufig von Algorithmen des maschinellen Lernens gefordert wird.

Jede Skalierungsmethode dient einem bestimmten Zweck und wird basierend auf der Artwork der Daten und den Anforderungen des maschinellen Lernalgorithmus ausgewählt. Durch die Anwendung dieser Techniken haben wir unsere numerischen Merkmale für die Verwendung in verschiedenen Modellen des maschinellen Lernens vorbereitet und so möglicherweise deren Leistung und Zuverlässigkeit verbessert.

import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler, PowerTransformer

# Learn the info
information = {
'Temperature_Celsius': (15, 18, 22, 25, 28, 30, 32, 29, 26, 23, 20, 17),
'Humidity_Percent': (50, 55, 60, 65, 70, 75, 80, 72, 68, 62, 58, 52),
'Wind_Speed_kmh': (5, 8, 12, 15, 10, 7, 20, 18, 14, 9, 6, 11),
'Golfers_Count': (20, 35, 50, 75, 100, 120, 90, 110, 85, 60, 40, 25),
'Green_Speed': (8.5, 9.0, 9.5, 10.0, 10.5, 11.0, 11.5, 11.0, 10.5, 10.0, 9.5, 9.0)
}

df = pd.DataFrame(information)

# 1. Min-Max Scaling for Temperature_Celsius
min_max_scaler = MinMaxScaler()
df('Temperature_MinMax') = min_max_scaler.fit_transform(df(('Temperature_Celsius')))

# 2. Normal Scaling for Wind_Speed_kmh
std_scaler = StandardScaler()
df('Wind_Speed_Standardized') = std_scaler.fit_transform(df(('Wind_Speed_kmh')))

# 3. Sturdy Scaling for Humidity_Percent
robust_scaler = RobustScaler()
df('Humidity_Robust') = robust_scaler.fit_transform(df(('Humidity_Percent')))

# 4. Log Transformation for Golfers_Count
df('Golfers_Log') = np.log1p(df('Golfers_Count'))
df('Golfers_Log_std') = standard_scaler.fit_transform(df(('Golfers_Log')))

# 5. Field-Cox Transformation for Green_Speed
box_cox_transformer = PowerTransformer(methodology='box-cox') # By default already has standardizing
df('Green_Speed_BoxCox') = box_cox_transformer.fit_transform(df(('Green_Speed')))

# Show the outcomes
transformed_data = df((
'Temperature_MinMax',
'Humidity_Robust',
'Wind_Speed_Standardized',
'Green_Speed_BoxCox',
'Golfers_Log_std',
))

transformed_data = transformed_data.spherical(2)
print(transformed_data)

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/skalierung-numerischer-daten-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-september-2024/feed/ 0 3717
Entscheidungsbaum-Klassifikator, erklärt: Eine visuelle Anleitung mit Codebeispielen für Anfänger | von Samy Baladram | August 2024 https://chatgpz.de/machine-learning/entscheidungsbaum-klassifikator-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ https://chatgpz.de/machine-learning/entscheidungsbaum-klassifikator-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/#respond Fri, 30 Aug 2024 08:25:16 +0000 https://chatgpz.de/machine-learning/entscheidungsbaum-klassifikator-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ [ad_1]

KLASSIFIZIERUNGSALGORITHMUS

Der einzige umgedrehte Baum, den Sie brauchen

Entscheidungsbäume sind im maschinellen Lernen allgegenwärtig und werden wegen ihrer intuitiven Ergebnisse geschätzt. Wer liebt nicht ein einfaches „Wenn-Dann“-Flussdiagramm? Trotz ihrer Beliebtheit ist es überraschend schwierig, eine klare, schrittweise Erklärung zu finden, wie Entscheidungsbäume funktionieren. (Es ist mir tatsächlich peinlich, wie lange ich gebraucht habe, um tatsächlich zu verstehen, wie der Algorithmus funktioniert.)

In dieser Aufschlüsselung werde ich mich additionally auf die Grundlagen der Baumkonstruktion konzentrieren. Wir werden GENAU darlegen, was in jedem Knoten passiert und warum, von der Wurzel bis zu den letzten Blättern (natürlich mit visuellen Darstellungen).

Alle Bilder: Vom Autor mit Canva Professional erstellt. Für Mobilgeräte optimiert; kann auf dem Desktop übergroß erscheinen.

Ein Entscheidungsbaum-Klassifikator erstellt einen umgedrehten Baum, um Vorhersagen zu treffen. Er beginnt oben mit einer Frage zu einem wichtigen Merkmal Ihrer Daten und verzweigt sich dann basierend auf den Antworten. Wenn Sie diesen Zweigen nach unten folgen, wird an jeder Haltestelle eine weitere Frage gestellt, wodurch die Möglichkeiten eingeschränkt werden. Dieses Frage-und-Antwort-Spiel geht weiter, bis Sie das untere Ende erreichen – einen Blattknoten –, wo Sie Ihre endgültige Vorhersage oder Klassifizierung erhalten.

Der Entscheidungsbaum ist einer der wichtigsten Algorithmen des maschinellen Lernens – es handelt sich um eine Reihe von Ja- oder Nein-Fragen.

In diesem Artikel verwenden wir diesen künstlichen Golfdatensatz (inspiriert von (1)) als Beispiel. Dieser Datensatz sagt basierend auf den Wetterbedingungen voraus, ob eine Individual Golf spielen wird.

Spalten: „Ausblick“ (bereits One-Sizzling-kodiert als sonnig, bewölkt, regnerisch), „Temperatur“ (in Fahrenheit), „Luftfeuchtigkeit“ (in %), „Wind“ (ja/nein) und „Wiedergabe“ (Zielfunktion)
# Import libraries
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np

# Load 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')
}
df = pd.DataFrame(dataset_dict)

# Preprocess information
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)

# Reorder the columns
df = df(('sunny', 'overcast', 'wet', 'Temperature', 'Humidity', 'Wind', 'Play'))

# Put together options and goal
X, y = df.drop(columns='Play'), df('Play')

# Cut up information
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Show outcomes
print(pd.concat((X_train, y_train), axis=1), 'n')
print(pd.concat((X_test, y_test), axis=1))

Der Entscheidungsbaum-Klassifikator funktioniert, indem er die Daten rekursiv auf der Grundlage der informativsten Merkmale aufteilt. So funktioniert es:

  1. Beginnen Sie mit dem gesamten Datensatz beim Stammknoten.
  2. Wählen Sie das beste Merkmal zum Aufteilen der Daten aus (basierend auf Maßen wie der Gini-Unreinheit).
  3. Erstellen Sie untergeordnete Knoten für jeden möglichen Wert der ausgewählten Funktion.
  4. Wiederholen Sie die Schritte 2–3 für jeden untergeordneten Knoten, bis ein Abbruchkriterium erfüllt ist (z. B. maximale Tiefe erreicht, Mindestanzahl an Stichproben professional Blatt oder reine Blattknoten).
  5. Weisen Sie jedem Blattknoten die Mehrheitsklasse zu.

In scikit-learn heißt der Entscheidungsbaumalgorithmus CART (Classification and Regression Timber). Er erstellt binäre Bäume und folgt normalerweise diesen Schritten:

  1. Beginnen Sie mit allen Trainingsbeispielen im Stammknoten.
Ausgehend vom Stammknoten, der alle 14 Trainingsbeispiele enthält, ermitteln wir die beste Funktion und den besten Punkt zum Aufteilen der Daten, um mit dem Erstellen des Baums zu beginnen.

2.Für jede Funktion:
a. Sortieren Sie die Merkmalswerte.
b. Betrachten Sie alle möglichen Schwellenwerte zwischen benachbarten Werten als potenzielle Teilungspunkte.

In diesem Stammknoten müssen 23 Teilungspunkte geprüft werden. Binäre Spalten haben nur einen Teilungspunkt.
def potential_split_points(attr_name, attr_values):
sorted_attr = np.kind(attr_values)
unique_values = np.distinctive(sorted_attr)
split_points = ((unique_values(i) + unique_values(i+1)) / 2 for i in vary(len(unique_values) - 1))
return {attr_name: split_points}

# Calculate and show potential cut up factors for all columns
for column in X_train.columns:
splits = potential_split_points(column, X_train(column))
for attr, factors in splits.objects():
print(f"{attr:11}: {factors}")

3. Für jeden potenziellen Splittpunkt:
a. Berechnen Sie die Unreinheit (z. B. Gini-Unreinheit) des aktuellen Knotens.
b. Berechnen Sie den gewichteten Durchschnitt der Verunreinigungen.

Beispielsweise wird für das Merkmal „sonnig“ mit dem Teilungspunkt 0,5 die Unreinheit (wie die „Gini-Unreinheit“) für beide Teile des Datensatzes berechnet.
Ein weiteres Beispiel: Derselbe Vorgang kann auch für kontinuierliche Funktionen wie „Temperatur“ durchgeführt werden.
def gini_impurity(y):
p = np.bincount(y) / len(y)
return 1 - np.sum(p**2)

def weighted_average_impurity(y, split_index):
n = len(y)
left_impurity = gini_impurity(y(:split_index))
right_impurity = gini_impurity(y(split_index:))
return (split_index * left_impurity + (n - split_index) * right_impurity) / n

# Type 'sunny' function and corresponding labels
sunny = X_train('sunny')
sorted_indices = np.argsort(sunny)
sorted_sunny = sunny.iloc(sorted_indices)
sorted_labels = y_train.iloc(sorted_indices)

# Discover cut up index for 0.5
split_index = np.searchsorted(sorted_sunny, 0.5, facet='proper')

# Calculate impurity
impurity = weighted_average_impurity(sorted_labels, split_index)

print(f"Weighted common impurity for 'sunny' at cut up level 0.5: {impurity:.3f}")

4. Nachdem Sie alle Unreinheiten für alle Merkmale und Teilungspunkte berechnet haben, wählen Sie die niedrigste aus.

Die Funktion „überdeckt“ mit einem Splitpunkt von 0,5 ergibt die geringste Unreinheit. Das bedeutet, dass der Cut up von allen anderen Splitpunkten der reinste ist!
def calculate_split_impurities(X, y):
split_data = ()

for function in X.columns:
sorted_indices = np.argsort(X(function))
sorted_feature = X(function).iloc(sorted_indices)
sorted_y = y.iloc(sorted_indices)

unique_values = sorted_feature.distinctive()
split_points = (unique_values(1:) + unique_values(:-1)) / 2

for cut up in split_points:
split_index = np.searchsorted(sorted_feature, cut up, facet='proper')
impurity = weighted_average_impurity(sorted_y, split_index)
split_data.append({
'function': function,
'split_point': cut up,
'weighted_avg_impurity': impurity
})

return pd.DataFrame(split_data)

# Calculate cut up impurities for all options
calculate_split_impurities(X_train, y_train).spherical(3)

5. Erstellen Sie zwei untergeordnete Knoten basierend auf der gewählten Funktion und dem Teilungspunkt:
– Linkes Sort: Beispiele mit Merkmalswert <= Cut up-Punkt
– Rechtes Sort: Beispiele mit Merkmalswert > Cut up-Punkt

Der ausgewählte Teilungspunkt teilt die Daten in zwei Teile. Da ein Teil bereits rein ist (die rechte Seite! Deshalb ist die Unreinheit gering!), müssen wir den Baum nur am linken Knoten fortsetzen.

6. Wiederholen Sie die Schritte 2 bis 5 rekursiv für jeden untergeordneten Knoten. Sie können auch anhalten, bis ein Abbruchkriterium erfüllt ist (z. B. maximale Tiefe erreicht, Mindestanzahl von Samples professional Blattknoten oder minimale Verunreinigungsabnahme).

# Calculate cut up impurities forselected index
selected_index = (4,8,3,13,7,9,10) # Change it relying on which indices you need to examine
calculate_split_impurities(X_train.iloc(selected_index), y_train.iloc(selected_index)).spherical(3)
from sklearn.tree import DecisionTreeClassifier

# The entire Coaching Part above is finished inside sklearn like this
dt_clf = DecisionTreeClassifier()
dt_clf.match(X_train, y_train)

Endgültiger vollständiger Baum

Die Klassenbezeichnung eines Blattknotens ist die Mehrheitsklasse der Trainingsbeispiele, die diesen Knoten erreicht haben.

Der rechte ist der endgültige Baum, der zur Klassifizierung verwendet wird. Die Beispiele benötigen wir an dieser Stelle nicht mehr.
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
# Plot the choice tree
plt.determine(figsize=(20, 10))
plot_tree(dt_clf, stuffed=True, feature_names=X.columns, class_names=('Not Play', 'Play'))
plt.present()
In dieser Scikit-Be taught-Ausgabe werden auch die Informationen des Nicht-Blattknotens gespeichert, wie beispielsweise die Anzahl der Samples und die Nummer jeder Klasse im Knoten (Wert).

So funktioniert der Vorhersageprozess, nachdem der Entscheidungsbaum trainiert wurde:

  1. Beginnen Sie beim Stammknoten des trainierten Entscheidungsbaums.
  2. Bewerten Sie die Funktion und die Teilungsbedingung am aktuellen Knoten.
  3. Wiederholen Sie Schritt 2 an jedem nachfolgenden Knoten, bis Sie einen Blattknoten erreichen.
  4. Die Klassenbezeichnung des Blattknotens wird zur Vorhersage für die neue Instanz.
Wir benötigen nur die Spalten, die vom Baum abgefragt werden. Abgesehen von „bewölkt“ und „Temperatur“ spielen andere Werte bei der Vorhersage keine Rolle.
# Make predictions
y_pred = dt_clf.predict(X_test)
print(y_pred)
Der Entscheidungsbaum liefert eine angemessene Genauigkeit. Da unser Baum nur zwei Merkmale prüft, erfasst er die Eigenschaften des Testsatzes möglicherweise nicht intestine.
# Consider the classifier
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

Entscheidungsbäume haben mehrere wichtige Parameter, die ihr Wachstum und ihre Komplexität steuern:

1 . Max. Tiefe: Dadurch wird die maximale Tiefe des Baums festgelegt. Dies kann ein wertvolles Werkzeug zur Vermeidung einer Überanpassung sein.

👍 Hilfreicher Tipp: Beginnen Sie am besten mit einem flachen Baum (vielleicht 3–5 Ebenen tief) und erhöhen Sie die Tiefe schrittweise.

Beginnen Sie mit einem flachen Baum (z. B. Tiefe 3–5) und steigern Sie diese schrittweise, bis Sie das optimale Gleichgewicht zwischen Modellkomplexität und Leistung bei Validierungsdaten gefunden haben.

2. Mindestprobenaufteilung: Dieser Parameter bestimmt die Mindestanzahl an Samples, die zum Aufteilen eines internen Knotens erforderlich ist.

👍 Hilfreicher Tipp: Wenn Sie hier einen höheren Wert einstellen (etwa 5–10 % Ihrer Trainingsdaten), können Sie verhindern, dass der Baum zu viele kleine, spezifische Aufteilungen erstellt, die sich möglicherweise nicht intestine auf neue Daten übertragen lassen.

3. Min. Proben Blatt: Dies gibt die Mindestanzahl an Samples an, die an einem Blattknoten erforderlich sind.

👍 Hilfreicher Tipp: Wählen Sie einen Wert, der sicherstellt, dass jedes Blatt eine sinnvolle Teilmenge Ihrer Daten darstellt (ungefähr 1–5 % Ihrer Trainingsdaten). Dies kann dazu beitragen, zu spezifische Vorhersagen zu vermeiden.

4. Kriterium: Die Funktion, die zum Messen der Qualität einer Aufteilung verwendet wird (normalerweise „Gini“ für Gini-Unreinheit oder „Entropie“ für Informationsgewinn).

👍 Hilfreicher Tipp: Während Gini im Allgemeinen einfacher und schneller zu berechnen ist, ist die Entropie bei Mehrklassenproblemen oft besser. Allerdings führen sie häufig zu ähnlichen Ergebnissen.

Beispiel einer Entropieberechnung für „sonnig“ mit Splittpunkt 0,5.

Wie jeder Algorithmus im maschinellen Lernen haben Entscheidungsbäume ihre Stärken und Schwächen.

Vorteile:

  1. Interpretierbarkeit: Der Entscheidungsprozess ist leicht zu verstehen und zu visualisieren.
  2. Keine Characteristic-Skalierung: Kann sowohl numerische als auch kategorische Daten ohne Normalisierung verarbeiten.
  3. Behandelt nichtlineare Beziehungen: Kann komplexe Muster in den Daten erfassen.
  4. Wichtigkeit der Funktion: Bietet einen klaren Hinweis darauf, welche Merkmale für die Vorhersage am wichtigsten sind.

Nachteile:

  1. Überanpassung: Neigt zur Erstellung übermäßig komplexer Bäume, die sich nicht intestine verallgemeinern lassen, insbesondere bei kleinen Datensätzen.
  2. Instabilität: Kleine Änderungen in den Daten können dazu führen, dass ein völlig anderer Baum generiert wird.
  3. Verzerrt durch unausgewogene Datensätze: Kann gegenüber dominanten Klassen voreingenommen sein.
  4. Unfähigkeit zur Extrapolation: Es können keine Vorhersagen über den Bereich der Trainingsdaten hinaus getroffen werden.

In unserem Golfbeispiel könnte ein Entscheidungsbaum sehr genaue und interpretierbare Regeln erstellen, um basierend auf den Wetterbedingungen zu entscheiden, ob Golf gespielt werden soll. Er könnte jedoch bei bestimmten Kombinationen von Bedingungen überangepasst sein, wenn er nicht richtig beschnitten wird oder wenn der Datensatz klein ist.

Entscheidungsbaum-Klassifikatoren sind ein großartiges Werkzeug zum Lösen vieler Arten von Problemen im maschinellen Lernen. Sie sind leicht zu verstehen, können komplexe Daten verarbeiten und zeigen uns, wie sie Entscheidungen treffen. Dies macht sie in vielen Bereichen nützlich, von der Wirtschaft bis zur Medizin. Obwohl Entscheidungsbäume leistungsstark und interpretierbar sind, werden sie oft als Bausteine ​​für fortgeschrittenere Ensemblemethoden wie Random Forests oder Gradient Boosting Machines verwendet.

# Import libraries
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.tree import plot_tree, DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Load 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')
}
df = pd.DataFrame(dataset_dict)

# Put together information
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)

# Cut up information
X, y = df.drop(columns='Play'), df('Play')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Practice mannequin
dt_clf = DecisionTreeClassifier(
max_depth=None, # Most depth of the tree
min_samples_split=2, # Minimal variety of samples required to separate an inner node
min_samples_leaf=1, # Minimal variety of samples required to be at a leaf node
criterion='gini' # Operate to measure the standard of a cut up
)
dt_clf.match(X_train, y_train)

# Make predictions
y_pred = dt_clf.predict(X_test)

# Consider mannequin
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

# Visualize tree
plt.determine(figsize=(20, 10))
plot_tree(dt_clf, stuffed=True, feature_names=X.columns,
class_names=('Not Play', 'Play'), impurity=False)
plt.present()

[ad_2]

]]>
https://chatgpz.de/machine-learning/entscheidungsbaum-klassifikator-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/feed/ 0 3567
Imputation fehlender Werte, erklärt: Eine visuelle Anleitung mit Codebeispielen für Anfänger | von Samy Baladram | August 2024 https://chatgpz.de/artificial-intelligence/imputation-fehlender-werte-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ https://chatgpz.de/artificial-intelligence/imputation-fehlender-werte-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/#respond Tue, 27 Aug 2024 15:27:17 +0000 http://chatgpz.de/artificial-intelligence/imputation-fehlender-werte-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ [ad_1]

DATENVORVERARBEITUNG

Ein (winziger) Datensatz, sechs Imputationsmethoden?

Lassen Sie uns über etwas sprechen, mit dem sich jeder Datenwissenschaftler, Analyst oder neugierige Zahlenjongleur früher oder später auseinandersetzen muss: fehlende Werte. Ich weiß, was Sie jetzt denken: „Oh toll, schon wieder ein Leitfaden zu fehlenden Werten.“ Aber hören Sie mir zu. Ich werde Ihnen zeigen, wie Sie dieses Drawback mit nicht einer, nicht zwei, sondern sechs verschiedenen Imputationsmethoden angehen können, und zwar mit einem einzigen Datensatz (und das auch noch mit hilfreichen visuellen Darstellungen!). Am Ende werden Sie sehen, warum Fachwissen Gold wert ist (etwas, das selbst unsere KI-Freunde nur schwer nachbilden können).

Alle Bilder: Vom Autor mit Canva Professional erstellt. Für Mobilgeräte optimiert; kann auf dem Desktop übergroß erscheinen.

Bevor wir uns mit unserem Datensatz und den Imputationsmethoden befassen, wollen wir uns kurz damit befassen, was fehlende Werte sind und warum sie in der Datenwissenschaft so häufig Probleme bereiten.

Was sind fehlende Werte?

Fehlende Werte, die in Pandas oft als NaN (Not a Quantity) oder in Datenbanken als NULL dargestellt werden, sind im Wesentlichen Lücken in Ihrem Datensatz. Es sind die leeren Zellen in Ihrer Tabelle, die Lücken in Ihren Umfrageantworten, die Datenpunkte, die Ihnen entgangen sind. In der Welt der Daten sind nicht alle fehlenden Werte gleich, und das Verständnis der Natur Ihrer fehlenden Werte ist entscheidend für die Entscheidung, wie Sie mit ihnen umgehen.

Bild vom Autor.

Warum treten fehlende Werte auf?

Fehlende Werte können sich aus verschiedenen Gründen in Ihre Daten einschleichen. Hier sind einige häufige Gründe:

  1. Dateneingabefehler: Manchmal handelt es sich einfach um einen menschlichen Fehler. Jemand könnte vergessen, einen Wert einzugeben, oder versehentlich einen löschen.
  2. Sensorstörungen: Beim IoT oder bei wissenschaftlichen Experimenten kann es vorkommen, dass ein fehlerhafter Sensor zu bestimmten Zeiten keine Daten aufzeichnet.
  3. Umfrage-Nichtbeantwortung: In Umfragen überspringen Befragte möglicherweise Fragen, deren Beantwortung ihnen unangenehm ist oder die sie nicht verstehen.
  4. Zusammengeführte Datensätze: Beim Kombinieren von Daten aus mehreren Quellen kann es vorkommen, dass für einige Einträge nicht in allen Datensätzen entsprechende Werte vorhanden sind.
  5. Datenbeschädigung: Während der Datenübertragung oder -speicherung können einige Werte beschädigt und unlesbar werden.
  6. Absichtliche Auslassungen: Einige Daten werden möglicherweise aus Datenschutzgründen oder aufgrund ihrer Irrelevanz absichtlich weggelassen.
  7. Probleme bei der Stichprobennahme: Bei der Methode zur Datenerfassung können bestimmte Datentypen systematisch übersehen werden.
  8. Zeitkritische Daten: In Zeitreihendaten können Werte für Zeiträume fehlen, in denen keine Daten erfasst wurden (z. B. Wochenenden, Feiertage).

Arten fehlender Daten

Wenn Sie wissen, mit welcher Artwork fehlender Daten Sie es zu tun haben, können Sie die am besten geeignete Imputationsmethode auswählen. Statistiker kategorisieren fehlende Daten im Allgemeinen in drei Typen:

  1. Völlig zufälliges Fehlen (MCAR): Das Fehlen ist völlig zufällig und ist von keiner anderen Variable abhängig. Beispielsweise, wenn eine Laborprobe versehentlich fallengelassen wurde.
  2. Zufälliges Fehlen (MAR): Die Wahrscheinlichkeit fehlender Daten hängt von anderen beobachteten Variablen ab aber nicht auf die fehlenden Daten selbst. So könnte es beispielsweise sein, dass Männer in einer Umfrage seltener Fragen zu Emotionen beantworten.
  3. Nicht zufällig vermisst (MNAR): Das Fehlen hängt vom Wert der fehlenden Daten selbst ab. Beispielsweise geben Personen mit hohem Einkommen ihr Einkommen in einer Umfrage möglicherweise seltener an.

Warum sind fehlende Werte wichtig?

Fehlende Werte können Ihre Analyse erheblich beeinflussen:

  1. Wenn sie nicht richtig gehandhabt werden, können sie zu Verzerrungen führen.
  2. Viele Algorithmen des maschinellen Lernens können fehlende Werte nicht sofort verarbeiten.
  3. Sie können zum Verlust wichtiger Informationen führen, wenn Instanzen mit fehlenden Werten einfach verworfen werden.
  4. Ein unsachgemäßer Umgang mit fehlenden Werten kann zu falschen Schlussfolgerungen oder Vorhersagen führen.

Deshalb ist es wichtig, eine solide Strategie für den Umgang mit fehlenden Werten zu haben. Und genau das werden wir in diesem Artikel untersuchen!

Zunächst einmal möchten wir unseren Datensatz vorstellen. Wir werden mit einem Golfplatz-Datensatz arbeiten, der verschiedene Faktoren verfolgt, die sich auf die Überfüllung des Platzes auswirken. Dieser Datensatz enthält von allem etwas – numerische Daten, kategorische Daten und ja, jede Menge fehlende Werte.

Dieser Datensatz wurde vom Autor künstlich erstellt (inspiriert von (1)), um das Lernen zu erleichtern.
import pandas as pd
import numpy as np

# Create the dataset as a dictionary
knowledge = {
'Date': ('08-01', '08-02', '08-03', '08-04', '08-05', '08-06', '08-07', '08-08', '08-09', '08-10',
'08-11', '08-12', '08-13', '08-14', '08-15', '08-16', '08-17', '08-18', '08-19', '08-20'),
'Weekday': (0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5),
'Vacation': (0.0, 0.0, 0.0, 0.0, np.nan, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, np.nan, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
'Temp': (25.1, 26.4, np.nan, 24.1, 24.7, 26.5, 27.6, 28.2, 27.1, 26.7, np.nan, 24.3, 23.1, 22.4, np.nan, 26.5, 28.6, np.nan, 27.0, 26.9),
'Humidity': (99.0, np.nan, 96.0, 68.0, 98.0, 98.0, 78.0, np.nan, 70.0, 75.0, np.nan, 77.0, 77.0, 89.0, 80.0, 88.0, 76.0, np.nan, 73.0, 73.0),
'Wind': (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, np.nan, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, np.nan, 1.0, 0.0),
'Outlook': ('wet', 'sunny', 'wet', 'overcast', 'wet', np.nan, 'wet', 'wet', 'overcast', 'sunny', np.nan, 'overcast', 'sunny', 'wet', 'sunny', 'wet', np.nan, 'wet', 'overcast', 'sunny'),
'Crowdedness': (0.14, np.nan, 0.21, 0.68, 0.20, 0.32, 0.72, 0.61, np.nan, 0.54, np.nan, 0.67, 0.66, 0.38, 0.46, np.nan, 0.52, np.nan, 0.62, 0.81)
}

# Create a DataFrame from the dictionary
df = pd.DataFrame(knowledge)

# Show fundamental details about the dataset
print(df.information())

# Show the primary few rows of the dataset
print(df.head())

# Show the depend of lacking values in every column
print(df.isnull().sum())

Ausgabe:

<class 'pandas.core.body.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Knowledge columns (whole 8 columns):
# Column Non-Null Rely Dtype
--- ------ -------------- -----
0 Date 20 non-null object
1 Weekday 20 non-null int64
2 Vacation 19 non-null float64
3 Temp 16 non-null float64
4 Humidity 17 non-null float64
5 Wind 19 non-null float64
6 Outlook 17 non-null object
7 Crowdedness 15 non-null float64
dtypes: float64(5), int64(1), object(2)
reminiscence utilization: 1.3+ KB

Date Weekday Vacation Temp Humidity Wind Outlook Crowdedness
0 08-01 0 0.0 25.1 99.0 0.0 wet 0.14
1 08-02 1 0.0 26.4 NaN 0.0 sunny NaN
2 08-03 2 0.0 NaN 96.0 0.0 wet 0.21
3 08-04 3 0.0 24.1 68.0 0.0 overcast 0.68
4 08-05 4 NaN 24.7 98.0 0.0 wet 0.20

Date 0
Weekday 0
Vacation 1
Temp 4
Humidity 3
Wind 1
Outlook 3
Crowdedness 5
dtype: int64

Wie wir sehen können, enthält unser Datensatz 20 Zeilen und 8 Spalten:

  • Datum: Das Datum der Beobachtung
  • Wochentag: Wochentag (0–6, wobei 0 für Montag steht)
  • Feiertag: Boolescher Wert, der angibt, ob es ein Feiertag ist (0 oder 1)
  • Temp: Temperatur in Celsius
  • Luftfeuchtigkeit: Luftfeuchtigkeit in Prozent
  • Wind: Windverhältnisse (0 oder 1, zeigt möglicherweise Windstille oder Wind an)
  • Ausblick: Wetteraussichten (sonnig, bewölkt oder regnerisch)
  • Überfüllung: Prozentualer Anteil der Kursbelegung

Und sehen Sie sich das an! In jeder Spalte außer „Datum“ und „Wochentag“ fehlen Werte. Perfekt für unsere Imputationsparty.

Nachdem wir nun unseren Datensatz geladen haben, wollen wir diese fehlenden Werte mit sechs verschiedenen Imputationsmethoden angehen. Wir werden für jeden Datentyp eine andere Strategie verwenden.

Beim listenweisen Löschen, auch als vollständige Fallanalyse bezeichnet, werden ganze Zeilen entfernt, die fehlende Werte enthalten. Diese Methode ist einfach und bewahrt die Verteilung der Daten, kann jedoch zu einem erheblichen Informationsverlust führen, wenn viele Zeilen fehlende Werte enthalten.

👍 Häufige Verwendung: Die listenweise Löschung wird häufig verwendet, wenn die Anzahl der fehlenden Werte gering ist und die Daten völlig zufällig fehlen (MCAR). Sie ist auch nützlich, wenn Sie für bestimmte Analysen, die fehlende Werte nicht verarbeiten können, einen vollständigen Datensatz benötigen.

In unserem Fall: Wir verwenden die listenweise Löschung für Zeilen, die mindestens 4 fehlende Werte aufweisen. Diese Zeilen liefern möglicherweise nicht genügend zuverlässige Informationen, und ihre Entfernung kann uns helfen, uns auf die vollständigeren Datenpunkte zu konzentrieren. Wir sind jedoch vorsichtig und entfernen nur Zeilen mit erheblichen fehlenden Daten, um so viele Informationen wie möglich zu erhalten.

# Rely lacking values in every row
missing_count = df.isnull().sum(axis=1)

# Preserve solely rows with lower than 4 lacking values
df_clean = df(missing_count < 4).copy()

Wir haben zwei Zeilen entfernt, die zu viele fehlende Werte enthielten. Fahren wir nun mit der Imputation der verbleibenden fehlenden Daten fort.

Bei der einfachen Imputation werden fehlende Werte durch eine zusammenfassende Statistik der beobachteten Werte ersetzt. Gängige Ansätze sind die Verwendung des Mittelwerts, Medians oder Modus der nicht fehlenden Werte in einer Spalte.

👍 Häufige Verwendung: Die Mittelwertimputation wird häufig für kontinuierliche Variablen verwendet, wenn die Daten zufällig fehlen und die Verteilung annähernd symmetrisch ist. Die Modusimputation wird typischerweise für kategoriale Variablen verwendet.

In unserem Fall: Wir verwenden die Mittelwertimputation für die Luftfeuchtigkeit und die Modusimputation für den Urlaub. Für die Luftfeuchtigkeit liefert der Mittelwert eine vernünftige Schätzung der typischen Luftfeuchtigkeit, vorausgesetzt, die fehlenden Werte sind zufällig. Für den Urlaub liefert uns der Modus den häufigsten Zustand, da es sich um eine binäre Variable handelt (Urlaub oder nicht), was eine vernünftige Schätzung für fehlende Werte ist.

# Imply imputation for Humidity
df_clean('Humidity') = df_clean('Humidity').fillna(df_clean('Humidity').imply())

# Mode imputation for Vacation
df_clean('Vacation') = df_clean('Vacation').fillna(df_clean('Vacation').mode()(0))

Die lineare Interpolation schätzt fehlende Werte, indem eine lineare Beziehung zwischen bekannten Datenpunkten angenommen wird. Sie ist besonders nützlich für Zeitreihendaten oder Daten mit einer natürlichen Ordnung.

👍 Häufige Verwendung: Lineare Interpolation wird häufig für Zeitreihendaten verwendet, bei denen fehlende Werte anhand der Werte davor und danach geschätzt werden können. Sie ist auch für alle Daten nützlich, bei denen eine annähernd lineare Beziehung zwischen benachbarten Punkten erwartet wird.

In unserem Fall: Wir verwenden lineare Interpolation für die Temperatur. Da sich die Temperatur im Laufe der Zeit tendenziell allmählich ändert und unsere Daten nach Datum sortiert sind, kann die lineare Interpolation auf Grundlage der an den nächsten Tagen aufgezeichneten Temperaturen vernünftige Schätzungen für die fehlenden Temperaturwerte liefern.

df_clean('Temp') = df_clean('Temp').interpolate(technique='linear')

Beim Vorwärtsfüllen (oder „letzte Beobachtung vorwärtsgetragen“) wird der letzte bekannte Wert vorwärts weitergegeben, um Lücken zu füllen, während beim Rückwärtsfüllen das Gegenteil der Fall ist. Bei dieser Methode wird davon ausgegangen, dass der fehlende Wert wahrscheinlich dem nächsten bekannten Wert ähnelt.

👍 Häufige Verwendung: Vorwärts-/Rückwärtsfüllen wird häufig für Zeitreihendaten verwendet, insbesondere wenn der Wert wahrscheinlich konstant bleibt, bis er geändert wird (wie bei Finanzdaten) oder wenn der letzte bekannte Wert die beste Schätzung für den aktuellen Standing ist.

In unserem Fall: Wir verwenden für Outlook eine Kombination aus Vorwärts- und Rückwärtsfüllung. Wetterbedingungen halten oft mehrere Tage an, daher ist es vernünftig anzunehmen, dass ein fehlender Outlook-Wert dem Outlook des vorherigen oder folgenden Tages ähneln könnte.

df_clean('Outlook') = df_clean('Outlook').fillna(technique='ffill').fillna(technique='bfill')

Bei dieser Methode werden alle fehlenden Werte in einer Variablen durch einen bestimmten konstanten Wert ersetzt. Diese Konstante kann basierend auf Domänenwissen oder einem sicheren Standardwert gewählt werden.

👍 Häufige Verwendung: Die Imputation konstanter Werte wird häufig verwendet, wenn es einen logischen Standardwert für fehlende Daten gibt oder wenn Sie explizit kennzeichnen möchten, dass ein Wert fehlt (indem Sie einen Wert außerhalb des normalen Datenbereichs verwenden).

In unserem Fall: Wir verwenden für die Spalte „Wind“ die Imputation konstanter Werte und ersetzen fehlende Werte durch -1. Dieser Ansatz kennzeichnet imputierte Werte explizit (da -1 außerhalb des normalen 0–1-Bereichs für Wind liegt) und bewahrt die Info, dass diese Werte ursprünglich fehlten.

df_clean('Wind') = df_clean('Wind').fillna(-1)

Ok-Nächste Nachbarn (KNN) Imputation schätzt fehlende Werte, indem die Ok ähnlichsten Stichproben im Datensatz gefunden werden (genau wie KNN als Klassifizierungsalgorithmus) und ihre Werte zum Imputieren der fehlenden Daten verwendet werden. Mit dieser Methode können komplexe Beziehungen zwischen Variablen erfasst werden.

👍 Häufige Verwendung: KNN-Imputation ist vielseitig und kann sowohl für kontinuierliche als auch für kategorische Variablen verwendet werden. Sie ist besonders nützlich, wenn komplexe Beziehungen zwischen Variablen zu erwarten sind, die einfachere Methoden möglicherweise übersehen.

In unserem Fall: Wir verwenden KNN-Imputation für Überfüllung. Überfüllung hängt wahrscheinlich von einer Kombination von Faktoren ab (wie Temperatur, Urlaubsstatus usw.), und KNN kann diese komplexen Beziehungen erfassen, um genauere Schätzungen fehlender Überfüllungswerte bereitzustellen.

from sklearn.impute import KNNImputer

# One-hot encode the 'Outlook' column
outlook_encoded = pd.get_dummies(df_clean('Outlook'), prefix='Outlook')

# Put together options for KNN imputation
features_for_knn = ('Weekday', 'Vacation', 'Temp', 'Humidity', 'Wind')
knn_features = pd.concat((df_clean(features_for_knn), outlook_encoded), axis=1)

# Apply KNN imputation
knn_imputer = KNNImputer(n_neighbors=3)
df_imputed = pd.DataFrame(knn_imputer.fit_transform(pd.concat((knn_features, df_clean(('Crowdedness'))), axis=1)),
columns=checklist(knn_features.columns) + ('Crowdedness'))

# Replace the unique dataframe with the imputed Crowdedness values
df_clean('Crowdedness') = df_imputed('Crowdedness')

Additionally, da haben Sie es! Sechs verschiedene Möglichkeiten, mit fehlenden Werten umzugehen, alle angewendet auf unseren Golfplatz-Datensatz.

Jetzt sind alle fehlenden Werte ausgefüllt!

Lassen Sie uns noch einmal zusammenfassen, wie die einzelnen Methoden mit unseren Daten umgegangen sind:

  1. Listenweises Löschen: Hat uns geholfen, uns auf vollständigere Datenpunkte zu konzentrieren, indem Zeilen mit vielen fehlenden Werten entfernt wurden.
  2. Einfache Imputation: Luftfeuchtigkeit mit Durchschnittswerten und Feiertag mit dem häufigsten Vorkommen ausgefüllt.
  3. Lineare Interpolation: Geschätzte fehlende Temperaturwerte basierend auf dem Pattern der umliegenden Tage.
  4. Vorwärts-/Rückwärtsfüllung: Geschätzte fehlende Outlook-Werte von benachbarten Tagen, welche die Beständigkeit von Wettermustern widerspiegeln.
  5. Konstante Wertimputation: Fehlende Winddaten mit -1 markiert, wobei die Tatsache erhalten bleibt, dass diese Werte ursprünglich unbekannt waren.
  6. KNN-Imputation: Geschätzte Menschenmenge basierend auf ähnlichen Tagen, wobei komplexe Beziehungen zwischen Variablen erfasst werden.

Jede Methode erzählt eine andere Geschichte über unsere fehlenden Daten und die „richtige“ Wahl hängt davon ab, was wir über unseren Golfplatzbetrieb wissen und welche Fragen wir beantworten möchten.

Die wichtigste Erkenntnis? Wenden Sie Imputationsmethoden nicht einfach blind an. Verstehen Sie Ihre Daten, berücksichtigen Sie den Kontext und wählen Sie die Methode, die für Ihre spezifische State of affairs am sinnvollsten ist.

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/imputation-fehlender-werte-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/feed/ 0 3494
Bernoulli Naive Bayes, erklärt: Eine visuelle Anleitung mit Codebeispielen für Anfänger | von Samy Baladram | August 2024 https://chatgpz.de/machine-learning/bernoulli-naive-bayes-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ https://chatgpz.de/machine-learning/bernoulli-naive-bayes-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/#respond Sun, 25 Aug 2024 11:06:45 +0000 https://chatgpz.de/machine-learning/bernoulli-naive-bayes-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/ [ad_1]

Vorhersagekraft durch Ja/Nein-Wahrscheinlichkeit freisetzen

Alle Illustrationen in diesem Artikel wurden vom Autor unter Verwendung lizenzierter Designelemente von Canva Professional erstellt.

Im Gegensatz zum Basisansatz von Dummy-Klassifikatoren oder die Ähnlichkeitsbasiertes Denken von KNNNaive Bayes nutzt die Wahrscheinlichkeitstheorie. Es kombiniert die einzelnen Wahrscheinlichkeiten jedes „Hinweises“ (oder Merkmals), um eine endgültige Vorhersage zu treffen. Diese einfache, aber leistungsstarke Methode hat sich in verschiedenen Anwendungen des maschinellen Lernens als unschätzbar wertvoll erwiesen.

Naive Bayes ist ein maschineller Lernalgorithmus, der Wahrscheinlichkeit zur Klassifizierung von Daten verwendet. Er basiert auf Satz von Bayeseine Formel zur Berechnung bedingter Wahrscheinlichkeiten. Der „naive“ Teil bezieht sich auf die Kernannahme: Sie behandelt alle Merkmale als unabhängig voneinander, selbst wenn dies in Wirklichkeit nicht der Fall sein könnte. Diese Vereinfachung ist zwar oft unrealistisch, reduziert aber die Rechenkomplexität erheblich und funktioniert in vielen praktischen Szenarien intestine.

Naive Bayes-Methoden sind einfache Algorithmen des maschinellen Lernens, die auf Wahrscheinlichkeit basieren.

Es gibt drei Haupttypen von Naive-Bayes-Klassifikatoren. Der Hauptunterschied zwischen diesen Typen liegt in den Annahmen, die sie über die Verteilung der Merkmale treffen:

  1. Bernoulli Naive Bayes: Geeignet für binäre/boolesche Merkmale. Es wird angenommen, dass jedes Merkmal eine binärwertige (0/1) Variable ist.
  2. Multinomiale Naive Bayes: Wird normalerweise für diskrete Zählungen verwendet. Wird häufig bei der Textklassifizierung verwendet, wo Funktionen Wortanzahlen sein können.
  3. Gaußscher naiver Bayes-Algorithmus: Nimmt an, dass kontinuierliche Merkmale einer Normalverteilung folgen.
Die Bernoulli-NB geht von binären Daten aus, die multinomiale NB arbeitet mit diskreten Zählungen und die Gaussian-NB verarbeitet kontinuierliche Daten unter der Annahme einer Normalverteilung.

Es ist ein guter Anfang, sich auf die einfachste zu konzentrieren, nämlich Bernoulli NB. Das „Bernoulli“ in seinem Namen kommt von der Annahme, dass jedes Merkmal binärwertig ist.

In diesem Artikel verwenden wir diesen künstlichen Golfdatensatz (inspiriert von (1)) als Beispiel. Dieser Datensatz sagt basierend auf den Wetterbedingungen voraus, ob eine Individual Golf spielen wird.

Spalten: „Ausblick“, „Temperatur“ (in Fahrenheit), „Luftfeuchtigkeit“ (in %), „Wind“ und „Spielen“ (Zielfunktion)
# IMPORTING DATASET #
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np

dataset_dict = {
'Outlook': ('sunny', 'sunny', 'overcast', 'rain', 'rain', 'rain', 'overcast', 'sunny', 'sunny', 'rain', 'sunny', 'overcast', 'overcast', 'rain', 'sunny', 'overcast', 'rain', 'sunny', 'sunny', 'rain', 'overcast', 'rain', 'sunny', 'overcast', 'sunny', 'overcast', 'rain', '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')
}
df = pd.DataFrame(dataset_dict)

# ONE-HOT ENCODE 'Outlook' COLUMN
df = pd.get_dummies(df, columns=('Outlook'), prefix='', prefix_sep='', dtype=int)

# CONVERT 'Windy' (bool) and 'Play' (binary) COLUMNS TO BINARY INDICATORS
df('Wind') = df('Wind').astype(int)
df('Play') = (df('Play') == 'Sure').astype(int)

# Set function matrix X and goal vector y
X, y = df.drop(columns='Play'), df('Play')

# Cut up the info into coaching and testing units
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

print(pd.concat((X_train, y_train), axis=1), finish='nn')
print(pd.concat((X_test, y_test), axis=1))

Wir werden es leicht für Bernoulli Naive Bayes anpassen, indem wir unsere Merkmale ins Binärsystem umwandeln.

Da alle Daten im 0- und 1-Format vorliegen müssen, wird „Outlook“ One-Sizzling-codiert, während die Temperatur in ≤ 80 und > 80 unterteilt wird. Ebenso wird die Luftfeuchtigkeit in ≤ 75 und > 75 unterteilt.
# One-hot encode the categorized columns and drop them after, however do it individually for coaching and take a look at units
# Outline classes for 'Temperature' and 'Humidity' for coaching set
X_train('Temperature') = pd.minimize(X_train('Temperature'), bins=(0, 80, 100), labels=('Heat', 'Sizzling'))
X_train('Humidity') = pd.minimize(X_train('Humidity'), bins=(0, 75, 100), labels=('Dry', 'Humid'))

# Equally, outline for the take a look at set
X_test('Temperature') = pd.minimize(X_test('Temperature'), bins=(0, 80, 100), labels=('Heat', 'Sizzling'))
X_test('Humidity') = pd.minimize(X_test('Humidity'), bins=(0, 75, 100), labels=('Dry', 'Humid'))

# One-hot encode the categorized columns
one_hot_columns_train = pd.get_dummies(X_train(('Temperature', 'Humidity')), drop_first=True, dtype=int)
one_hot_columns_test = pd.get_dummies(X_test(('Temperature', 'Humidity')), drop_first=True, dtype=int)

# Drop the categorized columns from coaching and take a look at units
X_train = X_train.drop(('Temperature', 'Humidity'), axis=1)
X_test = X_test.drop(('Temperature', 'Humidity'), axis=1)

# Concatenate the one-hot encoded columns with the unique DataFrames
X_train = pd.concat((one_hot_columns_train, X_train), axis=1)
X_test = pd.concat((one_hot_columns_test, X_test), axis=1)

print(pd.concat((X_train, y_train), axis=1), 'n')
print(pd.concat((X_test, y_test), axis=1))

Bernoulli Naive Bayes arbeitet mit Daten, bei denen jedes Merkmal entweder 0 oder 1 ist.

  1. Berechnen Sie die Wahrscheinlichkeit jeder Klasse in den Trainingsdaten.
  2. Berechnen Sie für jedes Merkmal und jede Klasse die Wahrscheinlichkeit, dass das Merkmal bei einer gegebenen Klasse 1 bzw. 0 ist.
  3. Für eine neue Instanz: Multiplizieren Sie für jede Klasse ihre Wahrscheinlichkeit mit der Wahrscheinlichkeit jedes Merkmalswerts (0 oder 1) für diese Klasse.
  4. Sagen Sie die Klasse mit der höchsten resultierenden Wahrscheinlichkeit voraus.
Für unseren Golf-Datensatz untersucht ein Bernoulli-NB-Klassifikator die Wahrscheinlichkeit des Auftretens jedes Merkmals für jede Klasse (JA und NEIN) und trifft dann eine Entscheidung basierend darauf, welche Klasse die höhere Probability hat.

Der Trainingsprozess für Bernoulli Naive Bayes umfasst die Berechnung von Wahrscheinlichkeiten aus den Trainingsdaten:

  1. Berechnung der Klassenwahrscheinlichkeit: Berechnen Sie für jede Klasse ihre Wahrscheinlichkeit: (Anzahl der Instanzen in dieser Klasse) / (Gesamtzahl der Instanzen)
In unserem Golfbeispiel würde der Algorithmus berechnen, wie oft insgesamt Golf gespielt wird.
from fractions import Fraction

def calc_target_prob(attr):
total_counts = attr.value_counts().sum()
prob_series = attr.value_counts().apply(lambda x: Fraction(x, total_counts).limit_denominator())
return prob_series

print(calc_target_prob(y_train))

2.Berechnung der Merkmalswahrscheinlichkeit: Berechnen Sie für jedes Characteristic und jede Klasse:

  • (Anzahl der Instanzen, bei denen das Characteristic in dieser Klasse 0 ist) / (Anzahl der Instanzen in dieser Klasse)
  • (Anzahl der Instanzen, bei denen das Characteristic in dieser Klasse 1 ist) / (Anzahl der Instanzen in dieser Klasse)
Für jede Wetterbedingung (z. B. sonnig), wie oft Golf bei Sonnenschein gespielt wird und wie oft nicht bei Sonnenschein gespielt wird.
from fractions import Fraction

def sort_attr_label(attr, lbl):
return (pd.concat((attr, lbl), axis=1)
.sort_values((attr.identify, lbl.identify))
.reset_index()
.rename(columns={'index': 'ID'})
.set_index('ID'))

def calc_feature_prob(attr, lbl):
total_classes = lbl.value_counts()
counts = pd.crosstab(attr, lbl)
prob_df = counts.apply(lambda x: (Fraction(c, total_classes(x.identify)).limit_denominator() for c in x))

return prob_df

print(sort_attr_label(y_train, X_train('sunny')))
print(calc_feature_prob(X_train('sunny'), y_train))

Für alle anderen Funktionen wird derselbe Vorgang angewendet.
for col in X_train.columns:
print(calc_feature_prob(X_train(col), y_train), "n")

3. Glättung (optionally available): Fügen Sie dem Zähler und Nenner jeder Wahrscheinlichkeitsberechnung einen kleinen Wert (normalerweise 1) hinzu, um Nullwahrscheinlichkeiten zu vermeiden

Wir addieren 1 zu allen Zählern und 2 zu allen Nennern, um die Gesamtklassenwahrscheinlichkeit bei 1 zu belassen.
# In sklearn, all processes above is summarized on this 'match' methodology:
from sklearn.naive_bayes import BernoulliNB
nb_clf = BernoulliNB(alpha=1)
nb_clf.match(X_train, y_train)

4. Ergebnisse speichern: Speichern Sie alle berechneten Wahrscheinlichkeiten zur Verwendung während der Klassifizierung.

Die Glättung wird bereits auf alle Merkmalswahrscheinlichkeiten angewendet. Wir werden diese Tabellen verwenden, um Vorhersagen zu treffen.

Gegeben sei eine neue Instanz mit Options, die entweder 0 oder 1 sind:

  1. Wahrscheinlichkeitssammlung: Für jede mögliche Klasse:
  • Beginnen Sie mit der Wahrscheinlichkeit des Auftretens dieser Klasse (Klassenwahrscheinlichkeit).
  • Erfassen Sie für jedes Characteristic in der neuen Instanz die Wahrscheinlichkeit, dass dieses Characteristic für diese Klasse 0/1 ist.
Für ID 14 wählen wir die Wahrscheinlichkeit aus, mit der jedes Merkmal eintritt (entweder 0 oder 1).

2. Punkteberechnung und -vorhersage: Für jede Klasse:

  • Multiplizieren Sie alle gesammelten Wahrscheinlichkeiten miteinander
  • Das Ergebnis ist die Punktzahl für diese Klasse
  • Die Klasse mit der höchsten Punktzahl ist die Vorhersage
Nachdem wir die Klassenwahrscheinlichkeit und alle Merkmalswahrscheinlichkeiten multipliziert haben, wählen wir die Klasse mit der höheren Punktzahl aus.
y_pred = nb_clf.predict(X_test)
print(y_pred)
Dieses einfache Wahrscheinlichkeitsmodell bietet eine hohe Genauigkeit für diesen einfachen Datensatz.
# Consider the classifier
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

Bernoulli Naive Bayes hat einige wichtige Parameter:

  1. Alpha (α): Dies ist der Glättungsparameter. Er fügt jedem Merkmal eine kleine Zahl hinzu, um Nullwahrscheinlichkeiten zu vermeiden. Der Standardwert ist normalerweise 1,0 (Laplace-Glättung), wie zuvor gezeigt.
  2. Binarisieren: Wenn Ihre Options nicht bereits binär sind, werden sie mit diesem Schwellenwert konvertiert. Jeder Wert über diesem Schwellenwert wird zu 1 und jeder Wert darunter zu 0.
Für BernoulliNB in ​​scikit-learn werden numerische Merkmale häufig standardisiert und nicht manuell binärisiert. Das Modell konvertiert diese standardisierten Werte dann intern in Binärwerte, wobei normalerweise 0 (der Mittelwert) als Schwellenwert verwendet wird.

3. Vorher anpassen: Ob Klassen-A-priori-Wahrscheinlichkeiten gelernt oder gleichmäßige A-priori-Wahrscheinlichkeiten (50/50) angenommen werden sollen.

Für unseren Golf-Datensatz könnten wir mit dem Standardwert α=1,0 beginnen, keine Binärisierung durchführen (da wir unsere Options bereits binär gemacht haben) und fit_prior=True.

Wie jeder Algorithmus im maschinellen Lernen hat auch Bernoulli Naive Bayes seine Stärken und Schwächen.

  1. Einfachheit: Einfach umzusetzen und zu verstehen.
  2. Effizienz: Schnelles Trainieren und Vorhersagen, funktioniert intestine mit großen Merkmalsräumen.
  3. Leistung bei kleinen Datensätzen: Kann auch mit begrenzten Trainingsdaten gute Leistung erbringen.
  4. Verarbeitet hochdimensionale Daten: Funktioniert intestine mit vielen Funktionen, insbesondere bei der Textklassifizierung.
  1. Unabhängigkeitsannahme: Nimmt an, dass alle Options unabhängig sind, was bei realen Daten oft nicht zutrifft.
  2. Beschränkt auf binäre Funktionen: Funktioniert in seiner reinen Kind nur mit Binärdaten.
  3. Sensibilität der Eingabedaten: Kann darauf reagieren, wie die Options binärisiert werden.
  4. Nullfrequenzproblem: Ohne Glättung können Nullwahrscheinlichkeiten die Vorhersagen stark beeinflussen.

Der Bernoulli Naive Bayes-Klassifikator ist ein einfacher, aber leistungsstarker maschineller Lernalgorithmus für die binäre Klassifizierung. Er eignet sich hervorragend für die Textanalyse und Spam-Erkennung, bei denen die Merkmale normalerweise binär sind. Dieses für seine Geschwindigkeit und Effizienz bekannte probabilistische Modell eignet sich intestine für kleine Datensätze und hochdimensionale Räume.

Trotz seiner naiven Annahme der Merkmalsunabhängigkeit kann es hinsichtlich der Genauigkeit oft mit komplexeren Modellen mithalten. Bernoulli Naive Bayes dient als hervorragendes Foundation- und Echtzeit-Klassifizierungstool.

# Import wanted libraries
import pandas as pd
from sklearn.naive_bayes import BernoulliNB
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

# Load the 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')
}
df = pd.DataFrame(dataset_dict)

# Put together knowledge for mannequin
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)

# Cut up knowledge into coaching and testing units
X, y = df.drop(columns='Play'), df('Play')
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Scale numerical options (for automated binarization)
scaler = StandardScaler()
float_cols = X_train.select_dtypes(embody=('float64')).columns
X_train(float_cols) = scaler.fit_transform(X_train(float_cols))
X_test(float_cols) = scaler.remodel(X_test(float_cols))

# Practice the mannequin
nb_clf = BernoulliNB()
nb_clf.match(X_train, y_train)

# Make predictions
y_pred = nb_clf.predict(X_test)

# Examine accuracy
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

[ad_2]

]]>
https://chatgpz.de/machine-learning/bernoulli-naive-bayes-erklaert-eine-visuelle-anleitung-mit-codebeispielen-fuer-anfaenger-von-samy-baladram-august-2024/feed/ 0 3444