名古屋の駅乗者数で単回帰分析
目的とか
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')
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')
割と頒布図に沿っているように見えるが、駅数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なので、適当にやった割にはいい数字が出た。