おまぬけ活動日誌

最近のツッコまれどころ

この日誌から Google してもらう


2009年12月20日(Sun) なんだか涼しいよ [長年日記]

[Ruby][RubyAdventJP] Rubyでデータを解析する

この記事はRuby Advent Calendar jp: 2009の12月20日分です。 この日誌が不調のためtumblrに掲載していましたが、復活したのでこちらにも転載します。 昨日はAaronさんによる 初めてのC extensionの書き方でした。 明日はtakano32さんによるRubyを256倍わかりやすくデバッグする方法です。


ホノルルマラソン走ってきました。 今年は脈拍計を導入したりして 自分の体がどこでへたったか記録したりして楽しんでました。 今年は、全員分のデータが公開されているのをみつけたので、 皆さんのタイムも見てみることにしました。

全員分のデータは下記のような形式で公開されています。 Chip Timeというのはスタートを過ぎてからゴールまでの正味の時間です。 号砲が鳴ってからゴールまでのGun Timeと違って、 号砲が鳴ってから走者がスタートまで辿りつくまでの時間が省かれています。 たくさんの走者が走る大会だとこの時間がバカにならないみたいですね。

----- -------- ----- --------- ----- --------------------------...
      Chip     Pace  Gun
Place Time     /mi   Time        #   Name
----- -------- ----- --------- ----- --------------------------...
    1 02:12:14  5:03 02:12:14      1 Ivuti, Patrick
    2 02:13:10  5:05 02:13:10      3 Chelimo Kipkorir, Nicholas
    :

今日はこれをつかって、完走した人の所要時間がどう分布してるか見てみます。

まずデータを読み込み、 ある所要時間の範囲に入る走者の数を数えて、テキストファイルとして出力します。

データを読むためにはhonolulu.rbというライブラリを作りました。 ハイフンの並び具合から各カラムの位置と幅を想像して(get_column_positions)、 カラムの名前を得て(get_column_names)、 それぞれの走者のデータをHashとして読みこんでいきます(get_datum)。 「%H:%M:%S」という形式の文字列から秒数を得たり、 逆の操作をすることも多いので、これらのメソッドもついでに定義しておきます。

distribution.rbというスクリプトで、 読んだデータを集計します。

$ ruby distribution.rb honolulu.htm > distribution2009.dat

下記のようなファイルが得られました。

#middle-chip-time(sec) count(/sec)
02:10:00.0 0.00416666666666667
02:30:00.0 0.0116666666666667
02:50:00.0 0.0466666666666667
03:10:00.0 0.1475
  :

集計したデータの表示は、…Rubyでやれるとかっこいいのですが お手軽にgnuplotでやってしまいましょう。

じゃん。こういうスクリプトでプロットができました→JALホノルルマラソン2009の完走者の所要時間分布

ちなみに単純に計算した所要時間の平均は5時間54分57秒、標準偏差は1時間29分49秒でした。 実際の分布は、正規分布よりも、 所要時間の長い側に分布が広いように見えますね。


こういうわけでRubtは日々のデータ解析にも使われてます。 こういう用途に使うときは実際のデータを食べさせながらコードを書いていって、 欲しい結果が得られたときにコード書きも終わってしまいます。 自動テストの無いレガシーコードがどんどーんできちゃうのが問題ですね。 テストがあっても、 honolulu.rb の80-82行目のような、ハイフンの並び具合と一部のデータの不整合をみつけるのは難しいのですが。 それはそれとして、今年もマラソンを楽しませていただきました。 地元の皆さん、同僚と家族のみんな、ありがとう。 皆さんもよい休日をお過しください :)


作り手とその取り巻きだけが楽しんでる間は本物じゃない。その中身が理解できない人々の生活を変えてこそ本物だ


zunda <zunda at freeshell.org>