季節の変わり目は気温の変化が激しく、ご体調を崩している方が多いと思います。
そこで思い出されるのは、某CMのこのようなフレーズです。
“きみの元気は僕の元気さ ファイト!
いのちのよろこびに Yes it’s
goo-d goo-d Mor-nin’
だってこんなにFine Day〜”
by Emi『みんな元気!』
さて、このCMはとても心に残り、
私もこのCMソングを何気なく口ずさんでしまうのですが、
いつも疑問に思うことがあります。
そう、もうお気づきかと思いますが、
「きみの元気は僕の元気」の「きみ」とは誰かということです。
自分の元気の源が「きみ」なる存在に依存しているのですから、
可及的速やかに、この存在を突き止めなければなりません。
社会通念上の観点からいくつかの候補を上げることができると思います。
家族、恋人、友人、クライアント、などでしょうか。
主観的な問題ですので、自らが納得できれば問題ないのですが、
上記いずれも異なる、いや、そもそも友人なんていない、
友人という存在を考えるだけで「僕の元気」は損なわれる、
と、私だけでなくみなさんもお考えかと思います。
前置きが長くなりましたが、
本稿ではRを用いたWebスクレイピングを中心に、
半自動的に「僕の元気」に影響を与える「きみ」の存在を探索していきます。
本稿では、あくまで私のケースにて、いくつか定義を決めていきます。
まずは、基点となる「僕の元気」の定義です。
私は毎週コンスタントにランニングしているものの、
走る距離は、その時々の体調や精神状態に依存しますので、
まさに「僕の元気」としてうってつけのデータかと思います。
ちなみにNike+による私のランニングデータは下記のようなものとなります。
※月別のランニング距離(km)
次に、対象となる「きみ」の候補です。
(もちろん、家族や友人や、恋人ではありません。)
私は横浜Fマリノスのファンですので、彼らの活躍は、「僕の元気」に影響を与えそうです。
主要な選手の時系列の得点推移を取得してみましょう。
スポーツ選手の成績は公式サイトほか、wikipediaに掲載されております。
今回は横浜Fマリノス公式ページを参照することとします。
Rでweb上のページからデータを取得する方法はいくつかありますが、
ページ内に(いくつかの)table要素があり、そのn番目のtableを取得する手順は下記となります。
1 2 |
url1 <- getURL("****") table1<-readHTMLTable(url1,which=n,header=TRUE) |
例えば、公式ページの齋藤学選手のページからJリーグでの年別成績の表(1番目の表)を取得する手順は
下記となります。
1 2 3 4 |
library(RCurl) library(XML) url1 <- getURL("http://www.f-marinos.com/club/player/data/2015/11") table_saito<-readHTMLTable(url1,which=1,header=TRUE) |
(Rでの”table_saito”の表示)
1 リーグ戦 カップ戦 天皇杯 ACL
2 2008年 横浜F・マリノス 37 7/0 0/0 1/0 –
3 2009年 横浜F・マリノス 19 11/0 3/0 0/0 –
4 2010年 横浜F・マリノス 19 5/0 5/1 0/0 –
5 2011年 愛媛FC(J2) 27 36/14 – 2/0 –
6 2012年 横浜F・マリノス 11 29/6 5/2 3/0 –
7 2013年 横浜F・マリノス 11 28/4 7/2 4/2 –
8 2014年 横浜F・マリノス 11 31/4 1/0 2/0 5/3
9 通算 J1 111/14 21/5 10/2 5/3
10 J2 36/14 – 2/0 –
この中で必要なのは、2〜8行目と、1列目と4列目ですので、まず必要な列のみ取得し、
上記表記のうち、”/”前が試合数、”/”後が得点数ですので、”/”以降のみを取得します。
Rのcbind関数を用いると、複数のデータフレームをまとめることができます。
1 2 3 4 5 |
table_saito2 <- table_saito[2:8,c(1,4)] goals<-str_split(string = table_saito$V4,pattern = "/") goalMatrix<-data.frame(Reduce(rbind,goals)) goalMatrix2<-goalMatrix[2:8,] saito_goal<-cbind(as.character(table_saito2$V1),as.character(goalMatrix2$X2)) |
(Rでの”saito_goal”の表示)
[,1] [,2]
[1,] “2008年” “0”
[2,] “2009年” “0”
[3,] “2010年” “0”
[4,] “2011年” “14”
[5,] “2012年” “6”
[6,] “2013年” “4”
[7,] “2014年” “4”
一見、複雑に見えますが、一度Rscriptとして保存しておけば、
ものの5秒で楽にデータフレームを作成することができました。
しかも候補を追加することは容易い作業です。
同様の作業を、中村選手、兵藤選手にも行い、
cbind関数でつなげると下記のようなデータフレームを生成することができます。
※列名などを適宜変更
year | saito | nakamura | hyodo | |
1 | 2008年 | 0 | 0 | 2 |
2 | 2009年 | 0 | 0 | 1 |
3 | 2010年 | 0 | 5 | 6 |
4 | 2011年 | 14 | 4 | 6 |
5 | 2012年 | 6 | 6 | 4 |
6 | 2013年 | 4 | 10 | 7 |
7 | 2014年 | 4 | 3 | 3 |
8 | 2015年 | 6 | 3 | 0 |
※今回はJリーグのデータのみ集計(斎藤選手は一部J2リーグのデータ含む)
※2015年データ(10/3時点)を手動でrbindで追加
それ以外に何が必要でしょうか。
私は、「よつばと!」が好きですので、よつばと関連のイベントやコミック発売によって元気になることは自明です。
つまり”よつばの元気は僕の元気”かもしれません。
ちなみに下記が「よつばと」の検索数推移のようでして、こちらを今回は用いることにします。
※下記データを直接Rから読み込むことは困難なため、一度csvファイルをダウンロードし、上記データと統合します。
あと、私は、茄子が好きですので、茄子の生産量が「僕の元気」に影響しているかもしれません。
いれましょう。
農林水産省のページにデータが公開されております。
http://www.maff.go.jp/j/tokei/sokuhou/yasai_syunka_14/index.html
しかし残念ながらこちらは年度別のエクセルファイルとなり時系列推移は画像としてのみしか見つかりませんでした。
webスクレイピングで楽に追加できるなら、と勢い余って茄子と申し上げましたが、
まさかこんなどうでもいい変数で手集計するはめになるとは遺憾です。
しかし、こういったジレンマもデータ分析でよくあるシーンかと思います。
さて、上記によって得られたデータセットが下記です。
このままでも良いのですが、単位が異なることと検索数が相対値のため、全て正規化しておきました。
year | my_run | saito | nakamura | hyodo | yotsuba | nasu |
2008 | 0.32 | 0 | 0 | 0.29 | 0.99 | 1 |
2009 | 0.67 | 0 | 0 | 0.14 | 0.83 | 0.95 |
2010 | 0.55 | 0 | 0.5 | 0.86 | 0.82 | 0.9 |
2011 | 0.33 | 1 | 0.4 | 0.86 | 0.87 | 0.88 |
2012 | 0.13 | 0.43 | 0.6 | 0.57 | 0.72 | 0.89 |
2013 | 0.96 | 0.29 | 1 | 1 | 1 | 0.88 |
2014 | 1 | 0.29 | 0.3 | 0.43 | 0.79 | 0.88 |
2015 | 0.61 | 0.43 | 0.3 | 0 | 0.05 | 0.88 |
まずは「僕の元気」と「きみ」候補の各推移を見てみましょう。
Rで上記のようなデータフレームで時系列推移を一覧表示させるには、一度melt関数で、
year,variable,valueという形式に変換します。
1 2 3 4 5 |
library(reshape2) temp <- melt(my_fuel, + id="year", + measure=c("my_run","saito_goal","nakamura_goal","hyodo_goal","yotsuba","nasu")) ggplot(temp,aes(x=year,y=value,colour=variable,group=variable)) + geom_line() |
ちなみにそれぞれの変数とランニングデータの相関は下記の通りです。
saito_goal | -0.24 |
nakamura_goal | 0.22 |
hyodo_goal | 0.04 |
yotsuba | 0.03 |
nasu | -0.29 |
中村選手のゴールとの相関が、ややあるでしょうか。
線形回帰してみましょう。
Rでは、いくつかの線形回帰のモデル候補をAICで評価しながら自動で探索してくれます。
1 2 3 |
nullModel<-lm(my_run~1,data=my_fuel) fullModel<-lm(my_run~saito_goal+nakamura_goal+hyodo_goal+yotsuba+nasu,data=my_fuel) myStep<-step(nullModel,scope=list(lower=nullModel,upper=fullModel),direction="both") |
結果は下記の通りです。
Start: AIC=-17.93
my_run ~ 1
Df Sum of Sq RSS AIC
+ nasu 1 0.057324 0.60536 -16.651
+ saito_goal 1 0.039579 0.62311 -16.420
+ nakamura_goal 1 0.032973 0.62971 -16.335
+ hyodo_goal 1 0.001442 0.66125 -15.945
+ yotsuba 1 0.000486 0.66220 -15.933
今回検討した変数を何も加えないものが最もAICで評価が良くなりました。至極まっとうですね。
では「きみの元気は僕の元気」の「きみ」とは誰なのでしょうか。
他の何者でもないのでしょうか。
そう、「僕の元気」は「昨日の僕の元気」に影響を受けているかもしれず、
「きみ」とは「過去の僕自身」という哲学的な問いかもしれません。
自己相関を調べてみましょう。
※自己相関を調べるにあたり、「my_run」という新たなデータセットを用意しました。
これまで見ていた年別のデータから下記のような月別のkmランニングデータに分解しております。
year | month | km |
2008 | 8 | 21.22 |
2008 | 9 | 5.05 |
2008 | 10 | 12.29 |
2008 | 11 | 26.63 |
2008 | 12 | 0 |
2009 | 1 | 0 |
2009 | 2 | 5.05 |
2009 | 3 | 25.87 |
2009 | 4 | 5.03 |
2009 | 5 | 20.93 |
… | … | … |
1 2 3 4 5 |
acf(my_fuel$my_run) pacf(my_fuel$my_run) require(forecast) my_arima<-auto.arima(x=my_run$km) my_arima |
「偏自己相関」
※偏自己相関とは、自己相関から推移律を除いたものです。
今日の私の元気が、昨日の私の元気に影響を受けているとすると、
昨日の私は、一昨日の私の元気に影響を受けており、
今日の私は、一昨日の私の元気に間接的に影響を受けている、という関節的な影響を除外したもの。
「ARMAモデルの結果(※1時点前の自分に影響を受けているという結果)」
Series: my_run$km
ARIMA(1,0,1) with non-zero mean
Coefficients:
ar1 ma1 intercept
0.8897 -0.6788 10.6697
s.e. 0.0728 0.1120 2.5297
sigma^2 estimated as 74.53: log likelihood=-311.15
AIC=630.31 AICc=630.8 BIC=640.17
ar1 ma1 intercept
0.8897335 -0.6788146 10.6696562
いかがでしたでしょうか。
これで全ての謎が解けたと言いたいところですが、
冒頭で述べた『みんな元気!』の歌の2番には次のフレーズが続きます。
“あの子も笑っている Yes it’s
goo-d goo-d Smi-lin'”
“あの子”なる新たな存在も唐突に出てきますが、
あの子の元気は僕の元気とは一切語られていません。ここに何か深い意味がある気がしてなりません。