[Statistischer Test 2. Klasse / quasi 1. Klasse] Regressives Analysetraining mit Python (1)

Einführung

Nachdem ich im November 2019 den statistischen Test Level 2 absolviert hatte, begann ich stetig zu lernen, um auch Level 1 anzustreben. Nach allem, was ich höre, scheint es notwendig zu sein, die multivariate Analyse zu unterdrücken, um die Quasi-Erstnote zu erreichen. Also werde ich das Nachschlagewerk lesen und multivariate Analysen lernen, aber ich denke, es ist am besten, meine Hände zu bewegen, um mein Verständnis zu vertiefen, also werde ich verschiedene Analysemethoden mit Python ausprobieren. Ich werde entscheiden.

Der Titel wurde jedoch auf [Statistical Test Level 2 / Level 1] gesetzt, da er ein wenig mit dem Problem des Lesens der Analyseergebnisse der statistischen Verarbeitungssoftware (R) zusammenhängt, das ich in der Studie von Level 2 irgendwie durchlaufen hatte. Es gibt Fragen wie "Die Anzahl der unabhängigen Variablen + 1" verringert den Freiheitsgrad des Regressionskoeffizienten der multiplen Regressionsanalyse und "Der Koeffizient ist nicht 0 auf dem Signifikanzniveau von xx%", aber die Geschichte darüber ist diesmal . </ del> Es bezieht sich auf den einzuführenden Inhalt.

Außerdem werden wir hier keine statistischen Bibliotheken verwenden, sondern nur Bibliotheken wie Numpy und Pandas (weil die Verwendung in einer Black Box nicht zum Verständnis beiträgt ...).

Nachschlagewerk

Katsuya Hasegawa, "Multivariate Analyse von Null" (2004) Kapitel 2

Gegenstand

Dieses Mal werden wir die Daten von "Nutzungsstatus nach Route" von JR East verarbeiten und verwenden. Die folgenden durch Kommas getrennten Daten wurden erstellt, indem der Routenname und die Betriebskilometer, die durchschnittliche Anzahl der durchreisenden Passagiere (GJ2018) und die Einnahmen aus dem Personenverkehr (GJ2018) in der PDF-Datei formatiert wurden. ("Ofunato Line", "Kesennuma Line" und "Yamada Line" mit unvollständigen Daten sind ausgeschlossen)

jreast2018.csv


Zeilenname,Geschäftskilometer,Durchschnittliche Anzahl der Passanten,Einnahmen aus dem Personenverkehr
Yamate Line,20.6,1134963,111014
Saikyo-Linie,5.5,752645,15032
Tokaido Hauptstrecke,169.2,367765,238493
Yokohama-Linie,42.6,231706,38214
Sobu Hauptlinie,145.4,207099,117700
Keiyo-Linie,54.3,181483,38201
Negishi Line,22.1,177099,16618
Nanbu Line,45,163148,29946
Mittlere Hauptleitung,247.8,160328,170577
Takasaki Linie,74.7,116646,34095
Musashino Linie,105.5,114847,43177
Tohoku Hauptleitung,572,84567,183688
Joban Line,351,71035,100757
Oume Line,37.2,63151,8989
Yokosuka Linie,23.9,62379,6107
Kawagoe Line,30.6,56191,6629
Sotobo Linie,93.3,34851,12038
Sagami-Linie,33.3,29643,4372
Gokaichi Linie,11.1,24712,1025
Sengoku-Linie,49,20497,4466
Uchibo-Linie,119.4,20483,8544
Ito Line,16.9,16907,1849
Weiße neue Linie,27.3,15978,1686
Narita Line,119.1,15183,8901
Tsurumi-Linie,9.7,14133,569
Shinonoi-Linie,66.7,12465,4717
Beide Haarlinien,84.4,11346,3176
Hachiko Line,92,9338,3612
Shinetsu Hauptleitung,175.3,9233,6260
Senzan Line,58,9046,2176
Tokin Line,13.8,8075,373
Tazawako Linie,75.6,7023,4421
Mito Line,50.2,7011,1255
Echigo Line,83.8,6021,1862
Sonnenlicht,40.5,5806,863
Joetsu Line,164.4,5389,3464
Ou Hauptleitung,484.5,4983,14111
Sazawa Line,24.3,3342,244
Oito Linie,70.1,3140,937
Yahiko Line,17.4,2338,150
Azuma Line,55.3,2327,615
Hagoshi Hauptlinie,271.7,2194,2731
Oshika Line,26.4,1877,146
Iwakoshi West Line,175.6,1745,1198
Mizugun Line,147,1666,760
Karasuyama Linie,20.4,1457,83
Iwakoshi East Line,85.6,1385,371
Steinwicklung,44.7,1255,190
Kashima Line,17.4,1221,87
Koumi Line,78.9,1194,420
Kururi-Linie,32.2,1094,96
Rikuha East Line,94.1,906,296
Hachinohe-Linie,64.9,883,269
Kamaishi Line,90.2,764,308
Gono Line,147.2,631,352
Iiyama Line,96.7,598,199
Ominato-Linie,58.4,578,168
Tsugaru Linie,55.8,464,112
Kranzlinie,106.9,382,124
Yonesaka Linie,90.7,379,105
Rikuha Nishi Line,43,345,67
Kitakami-Linie,61.1,311,70
Tadami-Linie,135.2,280,140

Speichern Sie diese Datei als ** jreast2018.csv mit ** Zeichencode UTF-8.

Trainieren

Im Folgenden haben wir den Vorgang mit Python 3.6.8 bestätigt.

Dateneingabe

Zunächst müssen Sie die Daten importieren. Importieren Sie Daten im CSV-Format mit Pandas.

import numpy as np
import pandas as pd
df = pd.read_csv("jreast2018.csv")
print(df) #Überprüfen Sie den Inhalt der importierten Daten
Linienname Geschäftskilometer Durchschnittliche Anzahl vorbeifahrender Passagiere Einnahmen aus dem Personenverkehr
0 Yamate Line 20.6  1134963  111014
1 Saikyo Linie 5.5   752645   15032
2 Tokaido-Hauptlinie 169.2   367765  238493
3 Yokohama Linie 42.6   231706   38214
4 Sobu-Hauptlinie 145.4   207099  117700
..    ...    ...      ...     ...
58 Kranzlinie 106.9      382     124
59 Yonesaka Linie 90.7      379     105
60 Rikuha Nishi Linie 43.0      345      67
61 Kitakami Line 61.1      311      70
62 Tadami Line 135.2      280     140

Finden Sie den Koeffizienten der Regressionslinie (Abschnitt 2-1)

Zunächst sei die unabhängige Variable (erklärende Variable) $ x $ die "durchschnittliche Anzahl der Passanten" und die abhängige Variable (objektive Variable) $ y $ das "Passagierbeförderungseinkommen" und zeichne eine gerade Linie $ y = ax + b $, die die Beziehung zwischen beiden gut ausdrückt. Ich denke über das Ziehen nach. Berücksichtigen Sie beim Zeichnen einer geraden Linie eine gerade Linie, die die Summe der Quadrate der Residuen jedes Datenpunkts (die Differenz zwischen dem beobachteten Wert (realisierter Wert) der abhängigen Variablen und dem theoretischen Wert (vorhergesagter Wert)) minimiert. Es ist die sogenannte "Minimum-Square-Methode". Für jeden Datenpunkt $ (x_1, y_1), ..., (x_n, y_n) $, wenn der beobachtete Wert der abhängigen Variablen $ y_i $ und der theoretische Wert $ \ hat {y} _i = ax_i + b $ ist Die Summe der Quadrate der Residuen $ L $ ist

\begin{align}
L &= \sum_{i=1}^n (y_i - \hat{y}_i)^2 \\
&= \sum_{i=1}^n (y_i - ax_i - b)^2
\end{align}

Es wird sein. Wenn $ L $ den Minimalwert annimmt, ist der partielle Differentialkoeffizient für $ a bzw. b $ 0.

\begin{align}
\frac{\partial L}{\partial a} &= \sum_{i=1}^n 2(y_i - ax_i - b)(-x_i) = 0 \\
\frac{\partial L}{\partial b} &= \sum_{i=1}^n 2(y_i - ax_i - b)(-1) = 0 \\
\end{align}

Wenn Sie dies für $ a und b $ organisieren

\begin{align}
\left(\sum_{i=1}^n x_i^2\right) a + \left( \sum_{i=1}^n x_i \right) b &= \sum_{i=1}^n x_i y_i \\
\left( \sum_{i=1}^n x_i \right) a + nb &= \sum_{i=1}^n y_i \\
\end{align}

Wenn als simultane Gleichung für $ a, b $ gelöst

\begin{align}
a  &= \frac{n\sum_{i=1}^n x_i y_i - \sum_{i=1}^n x_i \sum_{i=1}^n y_i}{n \sum_{i=1}^n x_i^2 - \left( \sum_{i=1}^n x_i \right)^2} \\
 b &=  \frac{ \sum_{i=1}^n x_i^2 \sum_{i=1}^n y_i - \sum_{i=1}^n x_i \sum_{i=1}^n x_i y_i}{n \sum_{i=1}^n x_i^2 - \left( \sum_{i=1}^n x_i \right)^2} \\
\end{align}

Es kann erhalten werden. Es ist schwierig, diese $ a und b $ von Hand zu berechnen (selbst wenn Sie einen Taschenrechner verwenden), aber Sie können sie einfach mit einem Programm berechnen.

n = len(df)
X = df["Durchschnittliche Anzahl der Passanten"]
y = df["Einnahmen aus dem Personenverkehr"]
a = (n * (x*y).sum() - x.sum() * y.sum()) / (n * (x**2).sum() - x.sum() ** 2)
b = ((x**2).sum() * y.sum() - x.sum() * (x*y).sum()) / (n * (x**2).sum() - x.sum() ** 2)
print(a) # Output: 0.12665116273608049
print(b) # Output: 11411.585376160469

Daraus ist ersichtlich, dass die jährlichen Einnahmen aus dem Personenverkehr tendenziell um etwa 0,127 Millionen Yen (= 127.000 Yen) für jede Zunahme der durchschnittlichen Anzahl vorbeifahrender Passagiere steigen. Zeichnen wir auch ein Diagramm.

import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(x, y, color="tab:blue")
ax.plot(x, a*x + b, color="tab:orange")
fig.savefig("output.png ")

output.png

Nun, ich habe nicht das Gefühl, dass ich es sehr gut analysiert habe. In Bezug auf die Grafik scheinen die Daten nicht sehr linear zu sein. Der Punkt unten rechts, an dem der Wert der x-Achse etwa 750.000 beträgt, ist die "Saikyo-Linie". Wenn Sie sich die Originaldaten genau ansehen, können Sie feststellen, dass die durchschnittliche Anzahl der Durchreisenden groß ist. Da die Betriebskilometer jedoch nur 5,5 km [^ saikyo] betragen, sind die Einnahmen aus dem Personenverkehr gering.

[^ saikyo]: Die "Saikyo-Linie" bezieht sich hier nicht auf die "Saikyo-Linie" (Osaki-Omiya) in den Passagierinformationen, sondern nur auf den Abschnitt (Ikebukuro-Akaha), dessen offizieller Routenname "Akaha-Linie" ist. Wird in der Fußnote (* C) auf der Quellseite angezeigt.

Wie hoch war übrigens die "durchschnittliche Anzahl der Passanten"? (Aus "Nutzungsstatus nach Route")

○ "Durchschnittliche Anzahl vorbeifahrender Fahrgäste" entspricht der Anzahl der Fahrgäste pro 1 km und Tag und wird anhand der folgenden Berechnung berechnet, die auf dem "Leistungsbericht der Eisenbahn" basiert, den wir dem Ministerium für Land, Infrastruktur, Verkehr und Tourismus jedes Jahr melden. Ich bin. [Durchschnittliche Anzahl vorbeifahrender Passagiere] = [Passagiertransportkilometer innerhalb des Geschäftsjahres für jede Route * A] ÷ [Geschäftskilometer innerhalb des Geschäftsjahres für die betreffende Route] ÷ [Geschäftstage innerhalb des Geschäftsjahres]

Da "Passagiertransportkilometer" (Anzahl der Benutzer x Entfernung) tatsächlich zu Einkommen führen, wird die "durchschnittliche Anzahl der Passanten x Geschäftskilometer x Anzahl der Geschäftstage" (Gesamtnutzungsentfernung während des ganzen Jahres) als unabhängige Variable verwendet. Wird als angemessener angesehen. 2018 gibt es 365 Tage. Berechnen Sie also die Anzahl der Geschäftstage als 365.

x = df["Durchschnittliche Anzahl der Passanten"] * df["Geschäftskilometer"] * 365
y = df["Einnahmen aus dem Personenverkehr"]
n = len(df)
a = (n * (x*y).sum() - x.sum() * y.sum()) / (n * (x**2).sum() - x.sum() ** 2)
b = ((x**2).sum() * y.sum() - x.sum() * (x*y).sum()) / (n * (x**2).sum() - x.sum() ** 2)
print(a) # Output: 1.082862145743171e-05
print(b) # Output: 331.32038547946183
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.scatter(x, y, color="tab:blue")
ax.plot(x, a*x + b, color="tab:orange")
fig.savefig("output.png ")

output.png

Es ist ein gutes Gefühl. Unter der Annahme, dass der jährliche Passagierkilometer x $ und der jährliche Passagiertransportumsatz (Millionen Yen) $ y $ beträgt, kann der theoretische Wert von $ y $ $ \ hat {y} $ wie folgt berechnet werden.

\hat{y} = (1.083 \times 10^{-5}) x + 331.3

Es wird berechnet, dass jedes Mal, wenn die Eisenbahn 1 km lang benutzt wird, das Einkommen um etwa 10,83 Yen steigt. Der reguläre Tarif von JR (3 Unternehmen in Honshu) für Kilometer (Tarif pro 1 km) wird mit 16,20 Yen berechnet (gegenseitige Abfahrt und Ankunft innerhalb der Hauptstrecke bei 300 km oder weniger ohne Steuern), ist jedoch regulärer [^ Tarif] Wenn Sie ein Ticket kaufen, wird der Fahrpreis ermäßigt, sodass das Einkommen, das Sie durch die Nutzung von 1 km erzielen, weniger als 16,20 Yen beträgt. Darüber hinaus gibt es tatsächlich verschiedene Tarifberechnungsmuster, wie z. B. kurze Entfernungen von 10 km oder weniger, lange Entfernungen von mehr als 300 km und lokale Transportlinien mit wenigen Benutzern, und die Daten fahren nicht gerade.

[^ Tarif]: [JR Ost: Vorschriften für das Passagiergeschäft> Band 2 Passagiergeschäft - Kapitel 3 Passagierpreis / Gebühr - Abschnitt 2 Normaler Passagierpreis](https://www.jreast.co.jp/ryokaku/02_hen / 03_syo / 02_setsu / index.html)

Finden Sie den Entscheidungsfaktor (Abschnitt 2-2)

Lassen Sie uns nun den Entscheidungsfaktor $ R ^ 2 $ finden, um zu sehen, wie gut diese Regressionsgleichung passt. Als die Schwankung, die der beobachtete Wert $ y_i $ hat

Unter Berücksichtigung der Summe aller Datenpunkte gilt (Gesamtvariation) = (Rückgabevariation) + (Restvariation). Hier ist das Verhältnis der Regressionsvariation zur Gesamtvariation der Bestimmungskoeffizient $ R ^ 2 $. Je größer der Entscheidungsfaktor (näher an 1) ist, desto besser passt die Regressionsgleichung zu den Daten.

TSS = ((y - y.mean()) ** 2).sum()     #Gesamtschwankung
ESS = ((a*x+b - y.mean()) ** 2).sum() #Regressive Fluktuation
RSS = ((y - a*x+b) ** 2).sum()        #Restschwankung
R_2 = ESS / TSS                       #Entscheidungskoeffizient
print(TSS) # 139066190955.65082
print(ESS) # 138362318781.54144
print(RSS) #    731535019.9636117
print(R_2) # 0.9949385816259694

Der Entscheidungsfaktor beträgt 0,995, was zeigt, dass er gut passt. Ich finde es nicht so seltsam, weil die ursprüngliche Tarifberechnung auf einer Methode basiert, die proportional zur Entfernung ist. Es sollte (Gesamtschwankung) = (Rücklaufschwankung) + (Restschwankung) sein, aber es scheint, dass ein Fehler aufgrund von Informationsverlust vorliegt, da Daten mit unterschiedlicher Anzahl von Ziffern in einem Durcheinander behandelt wurden.

Der hier erhaltene Entscheidungskoeffizient ist tatsächlich gleich dem Quadrat des Korrelationskoeffizienten der unabhängigen Variablen und der abhängigen Variablen. Versuchen wir, den (Stichproben-) Korrelationskoeffizienten zu finden und zu bestätigen.

cov_xy = ((x - x.mean()) * (y - y.mean())).sum() / (n - 1) #Probenkovarianz
var_x  = ((x - x.mean()) ** 2).sum() / (n - 1)             #Stichprobenverteilung unabhängiger Variablen
var_y  = ((y - y.mean()) ** 2).sum() / (n - 1)             #Stichprobenverteilung abhängiger Variablen
corr   = cov_xy / np.sqrt(var_x * var_y)                   #Korrelationskoeffizient
print(corr ** 2) # 0.994938581625969

Sicherlich scheint es mit dem früher erhaltenen Entscheidungskoeffizienten übereinzustimmen (er ist aufgrund eines Berechnungsfehlers nicht genau gleich).

Weil es lang geworden ist

Nächstes Mal. Betrachten wir nun den Fall, in dem zwei oder mehr unabhängige Variablen (multivariate) vorhanden sind, und schauen wir uns dann an, wie die Regressionsgleichung statistisch behandelt wird. Weiter → [Statistischer Test 2. Klasse / quasi 1. Klasse] Regressionsanalysetraining mit Python (2) - Qiita

Recommended Posts

[Statistischer Test 2. Klasse / quasi 1. Klasse] Regressives Analysetraining mit Python (2)
[Statistischer Test 2. Klasse / quasi 1. Klasse] Regressives Analysetraining mit Python (1)
Regressionsanalyse mit Python
In Python ② erlernte statistische Wahrscheinlichkeitsverteilung für Testgrad 2
In Python ① erlernte statistische Wahrscheinlichkeitsverteilung für Testgrad 2
Einfache Regressionsanalyse mit Python
Erste einfache Regressionsanalyse in Python
Statistischer Test (Mehrfachtest) in Python: scikit_posthocs
[Statistische Teststufe 2] Diskrete Wahrscheinlichkeitsverteilung
2. Multivariate Analyse in Python 7-3. Entscheidungsbaum [Rückgabebaum]
2. Multivariate Analyse in Python 2-1. Multiple Regressionsanalyse (Scikit-Learn)
2. Multivariate Analyse in Python 1-2. Einfache Regressionsanalyse (Algorithmus)
Assoziationsanalyse in Python
2. Multivariate Analyse in Python 5-3. Logistische Regressionsanalyse (Statistikmodelle)
Algorithmus in Python (Haupturteil)
Python Statistical Techniques-Statistische Analyse gegen Python-
Axialsymmetrische Spannungsanalyse mit Python
Online lineare Regression in Python
Stellen Sie den Python-Test in Jenkins ein
2. Multivariate Analyse in Python 6-2. Ridge-Regression / Lasso-Regression (Scikit-Learn) [Ridge-Regression vs. Lasso-Regression]
2. Multivariate Analyse in Python 2-3. Multiple Regressionsanalyse [COVID-19-Infektionsrate]
Gehirnwellenanalyse mit Python: Python MNE-Tutorial
Schreiben Sie Selentestcode in Python
Planare Skelettanalyse in Python (2) Hotfix
Einfache Implementierung einer Regressionsanalyse mit Keras
Logistische Regressionsanalyse Selbst erstellt mit Python
2. Multivariate Analyse in Python 6-1. Ridge-Regression / Lasso-Regression (Scikit-Learn) [multiple Regression vs. Ridge-Regression]
2. Multivariate Analyse in Python 8-2. K Nachbarschaftsmethode [Gewichtungsmethode] [Rückgabemodell]