神戸マラソンランナーのラン分析

先週日曜(11月18日)、神戸マラソンに参加してきました。

それまで私は長くても20km程度の距離までしか走ったことがありませんでした。まあなんとかなるだろうとかなり気軽に参加したのですが、折り返し地点を過ぎたあたりから足が棒になってペースががくんと落ち、後半は歩いたり走ったりを繰り返しながらの完走でした。
タイムはネットで6時間10分、リミット30分前のギリギリゴールでした。次に挑戦するときには、スタミナを切らさず、最後まで足を止めずに走り切りたいですね。

さて、神戸マラソンの全参加者の記録は、神戸マラソン公式Webサイト(https://runnet.jp/p_kobe2018/certificate.html)から取得できるようになっています。これを利用して、参加者のデータを集計し、他の参加者の皆さんはどんなペースで走っていたのか? レースはどのように進行していったのか? 等について分析してみようと思います。
次に走るときに、ペース配分や目標設定の参考にできるかもしれません。


データの取得

まずは、分析のためのデータの取得の準備をします。
今回は、クローラ(自動でWebページにアクセスできるもの)を作成して、公式Webサイトで公開されている参加者のデータを収集します。
マラソン中の全てのランナーのデータは、ゼッケンに取り付けられたGPSで収集されていたもので、全てのランナーのデータをほぼ同じ条件で取得できているので、精度はかなり高そうです。
このデータを、Python(Python 3.6)で作成したプログラムを用いて取得していきます。


※クローラを使用する際の注意
クローラを使用すると、通常私たちがリンクをクリックしてアクセスするよりも短時間でアクセスが集中することになります。
アクセス先のページに過剰な負荷をかけないよう、同時に複数アクセスしない、アクセスする際はアクセス間隔を十分あける等の配慮が必要です。


さて、PythonのクローリングにはBeautiful Soupを使うのが一般的です。今回は、Webページでテーブルとして表示されているものをPythonのDataFrame型で取得するようにしています。
以下に、データの取得のために作成したコードの一部を示しています。

データ取得に使用したコード(一部)

オープンになっているデータであれば、たったこれだけでデータを取得することができます。この後、データの型変換や、欠損値の穴埋めなどの整理を行い、最終的に以下のようなデータを作成しました。

作成したデータ(一部):性別(sex)は男子を0、女子を1とした。記録(gross_time)が00:00:00なのは、記録なし(途中棄権)を示す

ランの記録として使用するのは、スプリットタイム、ラップタイム、ゴールタイム(グロス、ネット)の4種類です。これらは全て上表のスプリットタイムから計算することができます。
いくつも種類がありますが、各タイムの違いをまとめると、下の図のようになります。ゴール地点までのスプリットタイムがグロスタイムになり、0km地点からゴールまでの各ラップタイムの合計が、ネットタイムになります。

スプリットタイム、ラップタイム、ゴールタイム(ネット、グロス)の関係

タイムのデータ以外には、ランナーのIDや性別データを全体量の把握目的で取得していますが、分析には使用していません。また、氏名など、それ以外のデータは分析には不要ですので取得しませんでした。


(マラソン条件の確認)気象条件の確認

タイムの分析に入る前に、基本情報を確認します。
当日の天気、気温、風などの気象条件は、気象庁のデータベース(http://www.jma.go.jp/jma/menu/menureport.html")に1時間ごとの情報が掲載されています。これを、ランナーのデータを取得したのと同様に取得します。
11月18日の神戸の天気は、以下の通りでした。

11月18日マラソン開催時間中の気象条件

当日の神戸市は、最高気温が18℃、海上の橋の上は若干強い風が吹いていましたが、全体的にタイムに影響が出るような風は吹いていなかったと思います。絶好のマラソン日和といって良かったのではないでしょうか。


(マラソン条件の確認)マラソンコース

気象条件の次は、コースの確認です。
マラソンコースは、市役所前を出発して国道2号線を西に進み、明石海峡大橋でUターン、最後はポートアイランドのほぼ中央に位置する市民広場駅前がゴールです。
目立った高低差といえば、JR塩屋駅付近でJR線と2号線が交差するポイントと須磨区の天神橋、そして、35km地点と41km地点のポートアイランドに続くバイパスの出入り口くらいでした。一般的に坂の多いと言われる神戸ですが、バイパスの出入り口の長い坂以外のポイントでは、高低差がタイムに与える影響はそれほど多くなかったのではと思います。

マラソンコース(公式Webサイトより)
マラソンコース断面図(公式Webサイトより)

以上の前提を踏まえて、取得したデータの分析を進めていきます。


参加者の男女比と完走率

今回Webから取得することができたデータは20,393人分でした。これは事前エントリーの人数のようで、この中には当日走った記録が全くないランナーのデータも含まれています。このデータを除外して、最終的に取得したデータ数は20,380人分でした。

参加者の男女比と完走率

ゴールタイム(グロス)が存在するものを完走したデータとみなして集計した結果は上表の通りで、ランナーの男女比はおよそ3:1、完走率は、
823 / 20380 ≒ 96.0%
となりました。

公式Webサイトにも参加者の人数と完走率の記録が出ていますが、出走者数:20,395人、完走者数:19,569人 (完走率95.9%)となっており、エントリーベースの人数と比べても、出走者数、完走者数とも手元のデータとわずかに異なっていました。
データ取得時か集計時、気づかぬうちに何らかの取得エラーが起きていたのかもしれませんが、今回はこのまま分析を進めていきます。


スタート状況

ここからは、男女を分けずに集計していきます。

神戸マラソンでは、およそ20,000人の参加者は、午前9:00と、午前9:15の2回に分かれてスタートしました(ウェーブスタート)。参加者は事前にA-Mのグループに割り振られており、前半のA-Fグループ(第1ウェーブ)が9:00ちょうどでスタートしたのに対し、後半のG-Mグループ(第2ウェーブ)は15分繰り下げて9:15にスタートしました(タイムの計測も9:15からとなる)。

取得したデータの中に、出発してから0km地点通過までの時間がありますので、これを基にスタート地点の通過状況をプロットしてみると、以下のようになります。

横軸に参加者ID、縦軸に0km通過時間をとってプロット。IDが4桁未満のデータはゲストランナーのもので、IDが10000以降が一般ランナーのデータとなる

スタート地点では同じグループのランナーが集まっており、スタート直後各グループが順に0km地点を通過していったことで、図中にはっきりとした四角形が形成されています。後半(およそ21000以降のID)の参加者は、スタート時刻が15分遅れていますので、計測時刻も前半の参加者と15分ずれています。このずれを補正すると以下のようになります。

先ほどの散布図のFグループとGグループの境界と思われる位置(ID:20800)より右側のデータを15分だけ上方に動かすことで、出発時刻が同じランナーが横に並ぶように表した

こちらの方がスタートの状況をより正確に表しています。
後半スタートしたランナーの中に、前半にスタートすることになっていた参加者も若干含まれていたことがわかります。


ゴール状況

スタートの次はゴールの状況をグラフ化してみます。
ゴールタイムの全ランナー平均は4時間52分14秒、中央値は平均時間とほぼ同じ4時間52分24秒でした。
全ランナーのタイムの分布は以下のようになります。

全ランナーのゴールタイムをヒストグラムで示したもの。縦に長い部分は、同時にゴールしたランナーが多いことを示す

ちょうど平均値に近い5時間前後を中心に、ほぼ均等に左右に分散しています。6時間30分あたりから急激に減っていますが、これは制限時間の関係で急いでゴールしたランナーがいたためと思われます。

また、3時間、3時間30分、4時間……のように、30分ごとにゴール人数が突出しているのが見られます。多くのランナーが目標タイムを30分おきに設定し、また実際に目標を達成できていることがグラフからもわかります。
目標タイムは、ランナーの間ではサブ3、サブ3.5、サブ4などと呼ばれています(サブは「以内」の意。サブ3で「3時間以内」となる)。
ゴール人数の突出具合から、目標タイムとして機能しているのは、5時間30分までということがわかります。


ラップタイムの推移

スタートとゴールの状況を確認したので、次はラップタイムの推移を見ていきます。

ラップタイムは5kmおきに算出することが可能です。全ての区間において、測定されたタイムを集計し、順に並べた結果が左の通りです。

マラソン序盤の15kmまでは、どの区間も平均値が30分前後であり、平均値を中心として左右にほぼ均等に分布しています。序盤はペースに大きな変化はなく、ほとんどのランナーが5kmの距離をおよそ15分〜45分で通過しています。

15kmを過ぎてからも、前を走るランナーにはほとんど変化がなく、同じペースを維持して走り続けていることがわかります。
一方、後続のランナーは徐々に遅れはじめ、終盤は時速6km程度の歩きに近いランナーがかなり増えています。

35kmを過ぎると、前半のグループも若干スピードが落ちてきています。35–40kmはちょうど長い上り坂の区間ですので、その影響もあるのかもしれません。このときの全体の平均値は40分(時速8km)程度になっています。


以上の結果をもうすこし見やすくするために、箱ひげ図を用いて再度プロットします。

箱ひげ図:https://bellcurve.jp/statistics/course/5220.html/ より

箱ひげ図は、データの分布を箱とひげの組み合わせで表現したものです。全体の中央値付近の50%が「箱」で表され、最大値から最小値までの範囲が「ひげ」で表されます。

(今回、ひげの長さの最大をはこの長さの1.5倍としてグラフにしています。ひげよりも上下に外れた点は外れ値とみなされたデータを示しています)

各ラップ毎のデータの分布を箱ひげ図で示すと、以下のようになります。
最後の区間は、実際のラップタイムを5kmでの走行タイムに換算しています。

ラップタイムの推移を箱ひげ図で示したもの。最後の区間は5kmでの時間に換算

スタート直後からしばらくは、ランナーのペースの分散は一定で推移しています。10kmのラップタイムの分布が5kmのものよりわずかに下に移動しているように見えますが、混雑が徐々に解消されて自分のペースで走りやすくなったことが若干影響しているのかもしれません。
マラソンの後半では、先頭のペースが17分前後でずっと推移しているのに対し、全体のペースが次第に落ちているのがわかります。
また、40kmからゴール地点までの最後の区間では、逆に全体のペースが大きく上昇しています。ゴール前に多くの人がスパートをかけていると考えられます。長い下り坂があることも影響しているかもしれません。


走行距離

各区間の距離をラップタイムで割ることで、ランナーの走行位置を算出することができます。Matplotlibモジュール内のFuncAnimationモジュールを使用して、分布の時間的変化をアニメーションで示したものが、下図になります。

スプリットタイムからランナーの走行位置を算出し、時間の変化をアニメーションにしたもの

スタート直後から10kmくらいまではみんな元気だったのが、だんだんとペースが落ちているのがよくわかります。とくに35kmの地点は、終盤でランナーの体力が残り少ないのと、大きな登り坂のせいで、長時間ランナーが留まり続けています。


ゴールタイムとペースの関係

最後に、ゴールタイムとペースの関係をプロットします。サブ3やサブ4で走るランナーと、6時間や7時間ペースのランナーとのペースとを比較することで、目標タイムと目標ペースの関係を予想することもできるでしょう。

まずは、サブ4を達成したランナー、サブ4.5を達成したランナー、のようにゴールタイムを 30分ごとに集計します。

サブ4.5、サブ5、サブ5.5でゴールしたランナーが最も多いようです。(6時間以降は人数の関係で一つにまとめています)
これら8つのグループごとに、ランナーの走行ペース(速度)をプロットしていきます。走行ペースは、ラップタイムから換算します。
以下に、sub_3(3時間以内)からsub_7(完走)までのランナーのペースの推移を順にプロットしていきます。

それぞれのグループのペース推移を比較すると、どのグループでもスタートからゴールに至るまでに2km/h程度ペースが落ちていますが、ゴールタイムが早いグループほどペースが落ちるのが遅れています。5時間グループであれば25km地点、6時間グループであれば15km地点で、ペースが急激に落ちていることがわかります。
一方、40kmを通過した最後の2kmでは、どのグループでもペースが大きく上昇しており、ラストスパートをかけていることが伺えます。
また、多くのグループで最初の5kmよりも10km、15kmの区間の方がペースが上がっています。これは、マラソン開始直後の混雑により、多くのランナーが思ったようなペースを出せなかったことが考えられます。
ちなみに、(完走ランナー)グループのちょうど中央にある赤いラインは私の記録です。


まとめ

今回、マラソンのランナーのランの記録をいくつかの観点からグラフ化し、分析していきました。
使用した定量データは、ランナーの通過時間だけでしたが、マラソンコースの状況や、実際に走った時の走りやすさなどの定性的な考察も合わせて考察することで、大会がどのように進行していったか、他のランナーの状況がどうであったかを推測することもできました。
これらの情報は、来年の神戸マラソンに参加した時のベンチマークにもなりますし、今回の考察の結果を頭に入れておけば、距離やコースや気候が異なる他のマラソン大会に参加したときにも参考にすることができます。

私にとってマラソンは初挑戦でしたが、これで終わりとせずに、少しずつタイムを縮めることができるように引き続き練習していきたいと思います。

以上