名古屋の駅乗者数で単回帰分析

目的とか

pythonの練習 兼 回帰分析の練習 兼 趣味の一環。 名古屋の鉄道駅の乗車数で単回帰分析をやってみました。

ファイル置き場とか

コードはここ。 https://github.com/takinou/station_sim/blob/master/1_simple_linear_regression.ipynb

元データは名古屋市が公開してくれている統計なごやweb版を利用しています。 オープンソースは幸せ。http://www.city.nagoya.jp/somu/page/0000068179.html そのまま使うとpythonで読み込めないので、以下のような形式に修正しています。

駅名, 年, その年の乗車数, 使える路線名1, 使える路線名2, ... , 利用可能な路線数

加工した後の乗車数データはこちら。 https://github.com/takinou/station_sim/blob/master/datas/Nagoya_Station_data.csv


まずはデータについて

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

Nagoya_Station_data = pd.read_csv("./datas/Nagoya_Station_data.csv")

こんな感じのデータです。 ここでは地下鉄 大曽根を記しています。地下鉄の名城線(meijo)と名港線(meiko)が使えるのでフラグを立て、利用線数(lines)は2です。 JR大曽根と、名鉄大曽根は別の行で定義しています。

名鉄は本当は名古屋本線常滑線犬山線、など分けなければいけないかなと思ったのですが、そうすると名古屋駅金山駅など、何線利用という定義にするべきかわからなくなった為、どこも1線としています。

year station_no station_name josha_num ward_office meijo meiko kamiida higashiyama tsurumai sakuradori aonami tokaido chuo kansai meitetsu kintetsu lines
0 1991 0 大曽根 4785428.0 0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2
1 1992 0 大曽根 4660204.0 0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2
2 1993 0 大曽根 4592223.0 0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2
3 1994 0 大曽根 4669642.0 0 1.0 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2

地下鉄、JRなどをgroupbyで合算する

今のままだと地下鉄千種駅と、JR千種駅とかが別々になっているので、groupbyで合算する

datas = Nagoya_Station_data.groupby(['station_name','year'])[['josha_num','lines']].sum()

#こんな感じになります
                   josha_num  lines
station_name year                  
いりなか         1991  3632472.0      1
             1992  3549946.0      1
             1993  3572420.0      1
             2013  2614891.0      1
             2014  2589814.0      1
             2015  2613444.0      1
ささしまライブ      2004   119622.0      1
             2005   882339.0      1
             2006   194865.0      1
             2007   195160.0      1
             2008   170932.0      1
黒川           2011  4723563.0      2
             2012  4845255.0      2
             2013  4943361.0      2
             2014  4939585.0      2
             2015  5069276.0      2
ナゴヤドーム前矢田  1991        0.0      0
             1992        0.0      0
             1993        0.0      0
             1994        0.0      0

利用路線数、年間乗車数をプロットしてみる

直感通り、利用路線数が多いと乗車数多い

datas.plot(x='lines',y='josha_num', kind='scatter')

Unknown.jpg

linesの8と9は名古屋駅あおなみ線ができる前とできた後 内訳は、 1.東山線 2.桜通線 3.近鉄線 4.名鉄線 (数え方がしんどいので、名古屋本線に1本化) 5.JR東海道線 6.JR中央線 7.JR関西線 8.新幹線 9.あおなみ線

相関係数を測ってみる

np.corrcoef(datas['lines'], datas['josha_num'])

array([[1.        , 0.82618746],
       [0.82618746, 1.        ]])

0.82なので、かなり高い。

単回帰分析にかける

X=datas.lines.values

#Xと同じ長さの列を作成して、1埋めする
A = np.vstack([X, np.ones(len(X))]).T

Y = datas.josha_num.values

#傾きa, 切片bを求める
a,b = np.linalg.lstsq(A,Y,rcond=None)[0]

print(a,b)
16512584.716035834 -15260790.749897148

係数 16512584.716035834 切片 -15260790.749897148

回帰直線とplotを比較してみる

#推定Yのplot
X2 = np.arange(0, 10, 0.01)
plt.plot(X2, a*X2 + b)

plt.plot(X,Y,'ro')

Unknown.png

割と頒布図に沿っているように見えるが、駅数8,9(名古屋駅)のところに大きな乖離が見える。。。

決定係数を手計算する

#残差計算
child = ((datas['josha_num'] - (datas['lines']*a + b))**2).sum()

#分母の計算
mother = ((datas['josha_num'] - datas['josha_num'].mean())**2).sum()

#決定係数
R = 1 - child / mother
0.6825857266199629

決定係数が0.68なので、適当にやった割にはいい数字が出た。