In letzter Zeit sind maschinelles Lernen, künstliche Intelligenz usw. populär geworden, und ich denke, dass das Wissen über die Statistiken, die ihnen zugrunde liegen, wichtig ist. Daher möchte ich versuchen, das Prinzip der Regressionsanalyse zu erklären, dessen Wirkung selbst in der Statistik leicht zu verstehen ist, um es beim Berechnen und Zeichnen von Diagrammen in Python konzeptionell verstehen zu können. Ich bin kein Statistiker. Wenn Sie Vorschläge oder Kommentare haben, können Sie sich gerne an mich wenden. Ich denke, es gibt einige Punkte, die mathematisch nicht streng sind, aber bitte verzeihen Sie mir ...
Holen Sie sich zuerst den Datensatz.
Diese Seite verwendet Python zur Erläuterung, aber die verwendeten Daten sind die Fahrzeugdaten des Datensatzes in der statistischen Analysesoftware R. Bitte laden Sie CSV-Daten von [hier] herunter und verwenden Sie sie (https://www.dropbox.com/s/bjmd4g22ubxxrgn/cars.csv?dl=0). (Laut der Beschreibung dieser Daten sieht es jedoch wie die Daten der 1920er Jahre aus, es handelt sich also nur um Beispieldaten.) In dieser Erklärung wird davon ausgegangen, dass es als "cars.csv" gespeichert ist.
teble definition of cars data
[,0] index
[,1] speed numeric Speed (mph)
[,2] dist numeric Stopping distance (ft)
Eine ausführliche Erläuterung der Daten finden Sie unter hier, aber die Geschwindigkeit des Autos und seiner Dies sind Daten, die 50 Sätze Bremsweg erfassen, wenn die Bremse mit Geschwindigkeit betätigt wird.
Python verwendet Version 2.7. Es wird auch davon ausgegangen, dass die folgenden Bibliotheken bereits installiert sind.
Importieren Sie diese.
import numpy as np
import matplotlib.pyplot as plt
Lesen Sie die Daten und zeichnen Sie zuerst ein Streudiagramm. Um ein Bild der Daten zu erhalten, ist es einfach, ein Diagramm zu zeichnen.
Übrigens, da es sich bei den Originaldaten um eine Einheit handelt, die den Japanern nicht bekannt ist, wie z. B. Meilen und Fuß, werden wir die Einheit in Meter umrechnen.
1 Fuß ≒ 0,3048 Meter 1 mph ≒ 1.61 km/h Konvertieren Sie die Dateneinheit also wie folgt.
data= np.loadtxt('cars.csv',delimiter=',',skiprows=1)
data[:,1] = map(lambda x: x * 1.61, data[:,1]) #km von mph/In h konvertieren
data[:,2] = map(lambda y: y * 0.3048, data[:,2]) #Konvertieren Sie von ft nach m
Zeichnen Sie dann ein Streudiagramm basierend auf diesen Daten.
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
ax.set_title("Stopping Distances of Cars")
ax.set_xlabel("speed(km/h)")
ax.set_ylabel("distance(m)")
plt.scatter(data[:,1],data[:,2])
Anhand dieser Daten kann mithilfe einer Regressionsanalyse ermittelt werden, wie weit ein mit einer bestimmten Geschwindigkeit fahrendes Auto beim plötzlichen Bremsen vollständig anhalten kann. Mit anderen Worten
distance = \alpha * speed + \beta
Es kann durch eine lineare Gleichung ausgedrückt werden, wie in gezeigt. Dies wird als einfache Regressionsanalyse bezeichnet. (Da es nur eine Variable gibt, ist sie "einfach".) Diese lineare Anpassung wird manchmal als Näherung erster Ordnung bezeichnet. $ \ Alpha $ ist die Steigung der geraden Linie und $ \ beta $ ist der Abschnittswert. Nennen wir diese gerade Linie eine ungefähre gerade Linie.
Ich werde versuchen, dies visuell mit einer geraden Linie zu versehen. Das Diagramm, das ich visuell angewendet habe, ist unten, aber ich habe $ \ alpha $ auf 0,74 und $ \ beta $ auf -5 gesetzt. Wie ist das? Ist es nicht wahrscheinlich, dass eine so gerade Linie irgendwie angewendet werden kann?
# y = 0.74x -5 gerade Linien((0,-5),(50,32)Durchlaufen)
x = [0, 50]
y = [-5, 32]
plt.plot(x,y)
Ich habe dies jedoch nur visuell angewendet, sodass ich nicht weiß, ob es wirklich die beste gerade Linie ist. Mal sehen, wie man das optimale $ \ alpha $ und $ \ beta $ findet, die Methode der kleinsten Quadrate.
Was ist die Methode der kleinsten Quadrate und was ist das "Minimum"? Was "quadrieren" Sie?
Das Minimum ist der Fehler zwischen der geraden Linie und den Daten. Der Fehler ist die vertikale Linie, die von jedem Punkt zur ungefähren geraden Linie gezogen wird. Siehe die Grafik unten.
# line: y = 0.74 -5
x = [0, 50]
y = [-5, 32]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*0.74-5],"k")
Der Fehler wird durch diese schwarze Linie dargestellt. Intuitiv halte ich die gerade Linie, die all diese Fehler addiert, für diese Daten am wenigsten geeignet.
Mal sehen, was passiert, wenn Sie $ \ alpha $ oder $ \ beta $ für die gerade Linie ändern, die Sie zuvor visuell angewendet haben.
Schauen wir uns zunächst die gerade Linie an, die $ \ alpha $ geändert hat.
# line: y = 0.54x -5
x = [0, 50]
y = [-5, 72]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*1.54-5],"k")
Werfen wir einen Blick auf das modifizierte $ \ beta $.
# line: y = 0.74x +15
x = [0, 50]
y = [15, 52]
plt.plot(x,y)
# draw errors
for d in data:
plt.plot([d[1],d[1]],[d[2],d[1]*0.74+15],"k")
Wie ist das? Es scheint, dass dieser Fehler gering ist, wenn Sie zum ersten Mal eine ungefähre gerade Linie zeichnen, die optisch gut aussieht und die es wagt, $ \ alpha $ und $ \ beta $ zu verschieben. Die Methode der kleinsten Quadrate ist eine Methode, um $ \ alpha $ und $ \ beta $ zu finden, die diesen Fehler minimieren.
Dies quadriert auch den Fehler. Der Grund ist, dass ich den Abstand zwischen der Geraden und der Geraden, die die Punkte der einzelnen Daten verbindet, ermitteln möchte. Wenn dieser jedoch unverändert bleibt, ist der Fehler für die Daten über der Geraden positiv und für die Daten darunter negativ, also quadratisch. Nehmen Sie dann das Plus und Minus und machen Sie alles positiv.
Nachdem Sie nun wissen, was zu quadrieren und zu minimieren ist, fahren wir mit der konkreten Berechnung fort.
Zunächst aus der Definition von Begriffen. Die $ i $ -ten Daten sind $ x_i, y_i $ und ihre Annäherung ist $ \ hat {y} _i $.
Der Fehler sei außerdem $ \ epsilon_i $. Erweitern wir die 19. Daten.
i = 18
x_i = data[i,1]
y_i = data[i,2]
y_hat = x_i*0.74-5
ax.set_ylim(0,y_i+3)
ax.set_xlim(x_i-5,x_i+5)
plt.plot([x_i,x_i],[y_i,y_hat],"k")
plt.plot(x,y)
plt.scatter([x_i],[y_i])
Wenn Sie diesen Fehler quadrieren und alle Daten hinzufügen,
S = \sum_i^n\epsilon_i^2=\sum_i^n (y_i-\hat{y}_i )^2
Kann ausgedrückt werden als.
\hat{y}_i = \alpha x_i + \beta
Wenn Sie also die ungefähren Wertedaten ersetzen, ist dies wie folgt.
S = \sum_i^n \epsilon_i^2 = \sum_i^n ( y_i-\alpha x_i - \beta )^2
Die optimale ungefähre gerade Linie kann erhalten werden, indem dieses $ S $ mit den Parametern $ \ alpha und \ beta $ differenziert und der Minimalwert ermittelt wird. Ausdrücken dieses $ S $ durch die Gleichung von $ \ alpha $,
S(\alpha) = \left( \sum_i^n x_i^2 \right) \alpha^2
+ 2\left( \sum_i^n (x_i\beta - x_i y_i ) \right) \alpha
+ n\beta^2 - 2\beta\sum_i^n y_i + \sum_i^n y_i^2
Wird sein. Was für eine Funktion ist das $ S (\ alpha) $? Es ist eine quadratische Funktion von $ \ alpha $. Da der Koeffizient von $ \ alpha $ die Summe der Quadrate ist, ist er immer 0 oder ein positiver Wert, also eine nach unten konvexe quadratische Funktion. Zeichnen wir hier ein Diagramm unter der Annahme, dass $ \ beta = 0 $ ist, um ein Bild der Form zu erhalten.
S(\alpha) = \left( \sum_i^n x_i^2 \right) \alpha^2
- 2\left( \sum_i^n x_i y_i \right) \alpha
+ \sum_i^n y_i^2 ... (if \beta = 0 )
Es wird einfach sein. Berechnen wir diesen Koeffizienten aus den Daten.
sum_x2 = np.sum([x ** 2 for x in data[:,1]]) # \sum x_i^2
sum_y2 = np.sum([x ** 2 for y in data[:,2]]) # \sum y_i^2
sum_xy = data[:,1].dot(data[:,2]) # \sum x_i y_i
print sum_x2
>>> 34288.2988
print sum_y2
>>> 11603.8684051
print sum_xy
>>> 18884.194896
Deshalb,
S(\alpha) ≒ 34288 \alpha^2 - 37768 \alpha + 11604
Wenn Sie dieses Diagramm zeichnen,
x1 = np.linspace(-1,5,200)
x1_2 = np.array([x ** 2 for x in x1])
#34288α2−37768α+ 11604
y1 = np.array(34288 * x1_2) - (37768 * x1) + 11604
plt.plot(x1,y1)
# Y =Linie von 11604
plt.plot([-1,5],[11604, 11604])
plt.plot([0,0],[13000, 0], "--k")
Wenn Sie $ \ alpha $ verschieben, finden Sie irgendwo den Mindestwert.
Ähnliches gilt für $ \ beta $
S(\beta) = n\beta^2
+ 2 \left( \sum_i^n (x_i\alpha - y_i) \right) \beta
+ \alpha^2\sum_i^n x_i^2 - 2\alpha \sum_i^n x_iy_i + \sum_i^n y_i^2
Zeichnen wir ein Diagramm unter der Annahme, dass $ \ alpha = 0 $ ist.
S(\beta) = n\beta^2
- 2 \left( \sum_i^n y_i \right) \beta + \sum_i^n y_i^2
... (if \alpha = 0 )
Da der zuvor berechnete Wert kein $ \ sum y_i $ enthielt, als ich ihn berechnete (und auch $ \ sum x_i $),
sum_x = np.sum(data[:,1])
print sum_x
>>> 1239.7
sum_y = np.sum(data[:,2])
print sum_y
>>> 655.0152
Daher lautet die quadratische Gleichung für $ \ beta $
S(\beta) ≒ 50\beta^2 - 1310 \beta + 11604
Und zeichne ein Diagramm
x1 = np.arange(-100,100,0.01)
x1_2 = np.array([x ** 2 for x in x1])
n = len(data[:,2])
# nβ^2-1310β+11604
y1 = np.array(n * x1_2) - (1310 * x1) + 11604
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
ax.set_xlim(-5,30)
ax.set_ylim(0,20000)
ax.set_xlabel("beta")
plt.plot([-50,30],[11604,11604],"g")
plt.plot([0,0],[30000,0],"--k")
plt.plot(x1,y1)
Und wenn Sie $ \ beta $ verschieben, können Sie schließlich sehen, dass ein bestimmtes $ \ beta $ den Mindestwert annimmt.
Fahren Sie mit [Teil 2] fort (http://qiita.com/kenmatsu4/items/1e37da1d55292035d985).
Recommended Posts