import pandas as pd
df = pd.read_csv('Euro_DM.csv', index_col='Unnamed: 0')
df.head()
| EURO | DM | |
|---|---|---|
| 1 | 3 | 5.86749 |
| 2 | 5 | 9.77915 |
| 3 | 6 | 11.73498 |
| 4 | 8 | 15.64664 |
| 5 | 12 | 23.46996 |
Wir wissen: Euro * 1,95583 ist der Umrechnungsfaktor für DM
Aber die Maschine nicht ;-)
Simpler konstruierter Fall für unser Beispiel; absolut linear; hier würde einfach DM/Euro ausreichen, was die Maschine aber nicht wissen kann
Normales Problem für lineare Regression
Maschinen berechnen die Differenz zwischen dem Ziel (hier DM) und einer Vorhersage
Vorhersage ist : f(x) = x * w + b
x ist hier unser Euro Wert
w ist ein Gewicht, welches es für die Maschine herauszufinden gilt, es bestimmt die Steigung der Funktion, also wie steil 𝑓 ( 𝑥 ) in Abhängigkeit von 𝑥 ansteigt oder abfällt.
b ist ein konstanter Wert, genannt Bias, welchen die Maschine ebenfalls ermitteln muss, er verschiebt die gesamte Funktion entlang der y-Achse nach oben oder unten.
Die Differenz ergibt sich aus dem (Ziel(DM) - (Vorhersage(x * w + b))
Dann bilden sie daraus den quadratischen Fehler : (DM - (x * w + b))²
Diesen Fehler versuchen sie soweit als möglich zu reduzieren und bedienen sich hier der partiellen Ableitungen für die quadratische Funktion.
Diese berechnet die Steigung für unsere Funktion und ist somit geeignet, als Maß für die Reduzierung des Fehlers zu dienen.
Die Grafik habe ich ins Deutsche übersetzt, sie stammt ursprünglich von: www.tpointtech.com/gradient-descent-in-machine-learning
Simples Gradienten Abstiegsverfahren manuell implemetiert; Beispiel lineare Regression mit einem Feature und einem Target
# Wir belegen unser Feature x und unser Target y
x = df['EURO'].astype(float).reset_index(drop=True)
y = df['DM'].astype(float).reset_index(drop=True)
'''
Optimizer Funktion
Update der Gewichte und des Bias für ein eindimensionales x-Array.
Parameter: Feature x[n], Target y[n], Gewicht w, Bias b, Lernrate alpha.
y_predict = (w*x[i] + b)
quadrierter_fehler = (y[i] - y_predict)²
Ableitung der Funktion nach w: 2x*(y[i] - (w*x[i] + b))
Ableitung der Funktion nach b: 2*(y[i] - (w*x[i] + b))
'''
def ralfs_optimizer(x, y, w, b, alpha):
sw = 0.0
sb = 0.0
for i in range(len(x)):
sw += 2*x[i]*(y[i] - (w*x[i] + b)) # Summenbildung Steigung für x
sb += 2*(y[i] - (w*x[i] + b)) # Summenbildung Steigung für Bias
# neues Gewicht w und neuen Bias b berechnen
w += (sw/len(x) *alpha) # altes Gewicht plus durschnittlicher Wert der Gradienten-Summe sw mal Lernrate
b += (sb/len(x) *alpha) # alter Bias plus durschnittlicher Wert des Bias-Gradienten sb mal Lernrate
#### für dieses Beispiel eines sehr einfachen, völlig linearen Falls benötigen wir keinen Bias,
#### also lasse ich ihn hier weg und bleibe bei 0.0
b = 0.0
return w, b
def avg_loss(x, y, w, b):
total_error = 0.0
for i in range(len(x)):
total_error += (y[i] - (w*x[i] + b))**2
return total_error / len(x)
import numpy as np
import matplotlib.pyplot as plt
def fit(x, y, epochs, optimizer, w = 0.0, b = 0.0, alpha = 0.00001 ):
for e in range(epochs+1):
w, b = optimizer(x, y, w, b, alpha)
''' ab hier reine Ausgabe '''
image_counter = 1
# Ausgabe des aktuellen loss der Epoche
# Plus Ausgabe als Plot
if (e == 0) or (e < 21 and e % 4 == 0) or (e >= 30 and e % 10 == 0) or (e == epochs):
print("epoche: ", str(e), "loss: "+ '%.10f'%(avg_loss(x, y, w, b)))
print("w, b: " + "%.8f"%(w)+ " " + "%.4f"%(b))
plt.figure(image_counter)
axes = plt.gca()
plt.scatter(x, y)
plt.xlabel("Euro")
plt.ylabel("DM")
plt.grid()
X_plot = np.linspace(0,200,200)
plt.plot(X_plot, X_plot*w + b)
#plt.show() # Einzelne Plots anzeigen mit show(); ohne show() -> gemeinsam nach dem Training in einem Plot anzeigen
image_counter += 1
return w, b
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['mathtext.fontset'] = 'stix'
matplotlib.rcParams['font.family'] = 'STIXGeneral'
matplotlib.rcParams.update({'font.size': 18})
plt.scatter(x, y, color='#1f77b4', marker='o')
plt.xlabel("EURO")
plt.ylabel("DM")
plt.grid()
Start des Trainings mit (x, y, Anzahl Epochen)
w, b = fit(x, y, epochs = 100, optimizer = ralfs_optimizer)
epoche: 0 loss: 20708.3222708693 w, b: 0.29294031 0.0000 epoche: 4 loss: 5654.6225693629 w, b: 1.08688399 0.0000 epoche: 8 loss: 1544.0534478705 w, b: 1.50176069 0.0000 epoche: 12 loss: 421.6198376878 w, b: 1.71855526 0.0000 epoche: 16 loss: 115.1276775924 w, b: 1.83184166 0.0000 epoche: 20 loss: 31.4368086201 w, b: 1.89103967 0.0000 epoche: 30 loss: 1.2248565228 w, b: 1.94304109 0.0000 epoche: 40 loss: 0.0477234671 w, b: 1.95330561 0.0000 epoche: 50 loss: 0.0018594254 w, b: 1.95533171 0.0000 epoche: 60 loss: 0.0000724479 w, b: 1.95573164 0.0000 epoche: 70 loss: 0.0000028227 w, b: 1.95581059 0.0000 epoche: 80 loss: 0.0000001100 w, b: 1.95582617 0.0000 epoche: 90 loss: 0.0000000043 w, b: 1.95582924 0.0000 epoche: 100 loss: 0.0000000002 w, b: 1.95582985 0.0000
def predict(x, w, b):
return (x * w + b)
''' Euro für Prediction '''
#euro = float(input("Eingabe Euro für Umrechnung: ").replace(",","."))
euro = 86.32
import locale
locale.setlocale(locale.LC_ALL, 'de_DE')
locale._override_localeconv["thousands_sep"] = "."
locale._override_localeconv["grouping"] = [3, 3, 0]
print('Berechnetes Gewicht w: {0} | Bias b: {1} \n'.format(locale.format_string('%.10f',w , grouping = True), locale.format_string('%.2f', b , grouping = True)))
print("Umrechnung für Eingabe: "+str(euro)+ " Euro in DM\n")
# ----------------------
dm = predict(euro, w, b) # Die Maschine sagt vorher ;-)
# ----------------------
dm_manuell = euro * 1.95583 # Wir wissen den Faktor: 1.95583
print("\tper Prediction (x * w + b): = "+str(dm))
print("\tmanuell mit Faktor 1,95583: = " +str(dm_manuell) + "\n")
print('DM aus Prediction gerundet: {0} für EURO: {1}'.format(locale.format_string('%.2f',round(dm,2), grouping = True), locale.format_string('%.2f', euro , grouping = True)))
print('DM aus Umrechnung manuell gerundet: {0} für EURO: {1} \n'.format(locale.format_string('%.2f',round(dm_manuell,2), grouping = True), locale.format_string('%.2f', euro , grouping = True)))
Berechnetes Gewicht w: 1,9558298507 | Bias b: 0,00 Umrechnung für Eingabe: 86.32 Euro in DM per Prediction (x * w + b): = 168.8272327113119 manuell mit Faktor 1,95583: = 168.82724559999997 DM aus Prediction gerundet: 168,83 für EURO: 86,32 DM aus Umrechnung manuell gerundet: 168,83 für EURO: 86,32
from sklearn.linear_model import LinearRegression
x = df["EURO"].to_numpy().reshape(-1, 1)
y = df["DM"].to_numpy()
model = LinearRegression()
model.fit(x, y)
print("Gewicht: " + str(model.coef_))
print("Bias: " + str(model.intercept_) + "\n")
dm = model.predict([[euro]])
print(str(euro) + " Euro sind: " + str(round(dm[0],2)))
Gewicht: [1.95583] Bias: 0.0 86.32 Euro sind: 168.83