より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

MotoGPライダーの中でスタートがうまいのは誰だ

MotoGPライダーのダニ・ペドロサが引退しました。

日テレの番組ではコメンテーターであるチュートリアル福田がダニ・ペドロサのファンであり、何かと番組中に彼について語ってくれます。

番組中にチュートリアル福田が

出たか! 伝家の宝刀スタートダッシュ

と言っていた記憶があります。

以前、オーバーテイクについて本ブログで勝手に分析してましたが、スタートグリッドから1周目については含めてませんでした。

というのもスタートダッシュの時点で、順位の入れ替わりは激しいため、走行中で起きたオーバーテイクなのか微妙です。

今回はそのスタートダッシュに注目したいと思います。

スタートダッシュは当たり前のようにやっていますが、マルケスがエンストして大慌てマシンを移動させてエンジンをかけたというシーンが2018年もありました。

お気に入りの選手がフロントローを取ったのにいつの間にか順位が下がっていたということもしばしば。

スタートグリッドから1周目で順位はどれほど変わっているか、またスタートダッシュが上手な選手について分析したいと思います。

算出方法

  • 2012年〜2018年のレース(再開になった2ラウンド目は除く)
  • 単純にスタートグリッドと1周目の順位を比較して、順位の上下を見る。6位から3位になっていれば+3です。

ポールポジションを取ってしまうと下がるかそのまましかないので、トップライダーよりクラッチロウやジャックミラーの中位のライダーの方が高くなりそうな気も。

結果

以下のようになりました。

f:id:rimever:20190108065441p:plain

ペドロサに期待していたのですが、平均は0近い値なので、そこまで得意という結果にはなってません。

個人的に、ロッシは不利なのでは?と思ってました。

年齢の問題です。どうしても歳をとると反射神経が鈍ると言われています。

ただ、ロッシを見ていて、スタートで出遅れる印象はあまりありませんでした。

そもそも、反射神経が鈍るのであれば、MotoGPマシンなんて操縦できないものです。

結果として平均では3位につけており、好位置にあります。

ドヴィツィオーゾとロレンソも優れてますが、逆にマルケスは0を下回る結果になっています。意外。

一番気になるのは最下位になったビニャーレスです。

私はMotoGP観戦歴がさほど長くないのもあって、彼の良かったレースを見たことがないのですが、彼はスタートダッシュが苦手というか皆と混ざって走るのが苦手なのではないかと思えてきます。

ジャック・ミラー

トップはジャック・ミラーとなりました。

ジャック・ミラーは策士っぽいイメージ。

皆、ウェットレース宣言されてからピットに引き上げてタイヤを交換に行ったのに彼だけは既にウェットタイヤを装着済み。

jp.motorsport.com

(性格も悪いという噂も。だからかも、とか勝手に想像したり)

ちょいちょいレース前半でトップを走っている時もありますね。でも、逃げ切れずに順位を落としていく感じ。

まだ若いライダーですし、これからが楽しみですね。

メモリを拡張すれば、ビルド時間は短縮されるか

職場でデスクトップPCを与えてもらい、メモリ増設により8GBから16GBにパワーアップしました。

パワーアップしたことにより、Visual Studioでのビルドが速くなった感じです。

ビルドに時間がかかって困っていた

ビルドに7分かかっていた巨大なソリューションが、2分で処理されるようになりました。

時間のかかるビルドをどう解消するかはチームの課題でした。

IncrediBuildという製品も試してはみましたが、チームのソリューションは解決せず。

解消される仮説は三つあったように思います。

  1. PCのスペックを上げる
  2. プロジェクトが多すぎる。統合する
  3. モジュール化してdll参照にする

が、どれも実証できず、プロジェクトは終わりました。

検証

「PCのスペックを上げる」が一番、現実的な解消方法だったと思います。

職場で検証したいと頃でしたが、自宅にてPararells Desktopの仮想環境を用いてチャレンジしたいと思います。

TeamCityというビルドサーバーがあるので、ビルドサーバーのジョブで計測しようと思います。

f:id:rimever:20190106165138p:plain

細かいログが出力されるので分析しやすいというのが主な理由です。

  • 仮想環境でメモリを調整する
  • 1回だけだとばらつきがわからないので、3回ずつ。
  • systeminfoコマンドを用いて、ビルドログにPC情報を出力しておく(イージーな計測ミスを防ぐため)

f:id:rimever:20190105204840p:plain
Pararells Desktopの設定画面

どれくらいのジョブ?

色々あってGitHubに入れてないので具体的には伝わらないですが、

f:id:rimever:20190106164047p:plain

  • プロジェクトは20程度のソリューション
  • 言語はC#
  • コードは25万行

測定結果

ジョブ自体は4,5分かかるのですが、単位は秒です。

メモリ 1回目 2回目 3回目
4GB 54 58 61
6GB 40 47 46
8GB 45 43 43

f:id:rimever:20190106173017p:plain

8GBメモリがあまり良いところを見せてくれませんでした。

メモリは、「テーブルの広さ」と比喩されたりします。すでに十分な作業領域が確保されているから、大きくしても意味はないということでしょう。

大きなソリューションだったら良いのかもしれませんね。

これは計測用のジョブですが、本番のジョブだとSonarQubeのためのビルドですので3分以上かかります。

それで行きたかったのですが、そしたら4GBだとハングしたため、計測できるようなジョブにしました。

単純にメモリサイズに応じて反比例した時間になるわけではないですが、メモリサイズが大きければ安心して実行できます。

メモリの拡張もハードや費用の制約上で簡単に出来るわけでは無いですし、各プロジェクトで検証しないと参考にならないようです。

まとめ

  • メモリが大きくなれば、ビルド時間は解消される場合もある
  • 効果の程度は各プロジェクトで計測しないとわからない

MotoGPでアツいコースはどれだ?

MotoGPといえば、オーバーテイク(追い抜く)です。

4輪と2輪のどちらが速いという以前に、F1のような4輪と比べて車幅が狭いため、オーバーテイクが頻繁に行われるのがMotoGPを観ていて面白いです。

そのオーバーテイクに注目し、オーバーテイクが頻繁に行われるコースはどれかを私なりに分析してみようと思います。

MotoGPの歴史も長く、レギュレーションも変わりますし、全てを分析するには、私は業界人ではないので限界があります。

ですので、条件を絞ることにしました。

条件

私が勝手に考えたルールなので、鵜呑みにしないでください。

1000ccとなった2012年以降〜

毎年レギュレーションが変わるのがモータースポーツの世界ですが、1000ccとなった2012年からが区切りがいいと判断して、2012年以降のレースを対象とすることにします。

表彰台となる3位以内

中上選手の順位が上がってきましたよ

と日本のライダーについては解説も触れてはくれますが、映像になるのは上位だけです。

私としてはテレビ観戦していてアツいレースとしたいので、表彰台となる3位以内でラップごとに順位が変わる回数をカウントすることにします。

算出方法

※1周目 A B C と表記しますが、これは1周目は1位からA,B,Cの順と表現しています。

Case.1

1周目 A B C

2周目 A B D

この場合は、3位のCとDが入れ替わっているので1と計算します。

Case.2

1周目 A C B

2周目 B C A

この場合は、1位と3位の順位が入れ替わっています。

1位が入れ替わった場合は3と計算しますので、3位の変更と合わせて4とします。

ちなみに2位が入れ替わったとしても1と計算します。トップが変わる方が2位と3位が入れ替わるより大きなイベントとして考えたいがためのルールです。

つまり、1周で1位と2位と3位の全てが入れ替わった場合は、3+1+1=5となり、一番アツい展開です。

補足

1周の間に何回も順位が入れ替わるケースがあるため、実際のレースとは差異が出るのですがデータの都合上、これで勘弁してください。

また、コースごとに距離が違う分、何周走るか異なってきます。

よって、トータルの追い越し回数と、参考値として、トータルの追い越し回数/ラップ数を出すことにします。

分析

ランキング

対象期間で、アツかったレースは以下。

f:id:rimever:20190107073756p:plain

2017年のオーストラリア GPは私もテレビで見ました。

www.monsterenergy.com

ヤマハ寄りの記事ですが。7,8人のライダーが競うというレース。

サテライトのザルコがスタート直後から荒々しいプッシュで、レースを盛り上げてましたね。

マルケスでなくロッシが勝っていれば、私としては言うことはなかったですが。

コースごとの分析

コースごとに箱ひげ図にしたところ以下のようになりました。

f:id:rimever:20190107073940p:plain

タイトルの答えにあったコースを選ぶとしたら、オーストラリアかオランダだと思います。

オーストラリアの方がコンスタントに先のわからないレースをしていると読めるのですが、オランダも捨てがたいです。

最近では、開幕戦が行われるカタールもなかなか盛り上がりますね。開催順序も分析データに含めた方がよかったかも。

シーズンごと

シーズンごとの分析もしてみました。

f:id:rimever:20190107074002p:plain

シーズンごとで開催地もいくつか変わることもあるとはいえ、結構違いますね。

各チームのマシンの成熟度やライダーの力量によるところもあるのでしょう。

2017は特に面白いシーズンだったようです。私がMotoGPを見るようになったのもこの年からです。

2019年はどうなる? 主観で予測

2018年のマルケスは、他を寄せ付けない走りだった印象です。

アルゼンチンGPで19位から5位まで駆け上がる破天荒なレースを思い出します。(ただし、ペナルティで18位)

kininarubikenews.com

ロッシとアレイシ・エスパルガロに激突しており、押しのけてまでかと唖然したものの、逆にあの走りが彼と他のライダーの違いを痛感させられたシーンでした。

皆、並んでいて少しずつ差をつめて順位が変わるのがMotoGPのレースと思っていたのに、マルケスはここまで繰り上がってしまえるのかと。

普通のライダーがあんな走りをしたら転倒して自滅でしょう。

でも完走してしまった。

そこに怖いくらいの執念と、図抜けた実力があるように私は感じました。(なぜ私がマルケスを好きになれないのだろうか気付かされたレースでもあります)

なので、来年は客観的には、チャンピオンであるマルケスがさらに勝ち続けて動きがあまりないシーズンになってしまうのかなーと感じています。

とはいえ、昨年はロッシとビニャーレスが、マシンについて云々と不満を言っていた記憶があるので、ヤマハ勢のマシンが納得いく出来となって、今年もアツいレースが繰り広げられて欲しいところですね。

ザルコのKTM移籍や日本人ライダーの中上、ホンダに移籍したロレンソなど、見所は今年も沢山です。

ベストラップで見るMotoGP

MotoGPとは、オートバイで行われるモータースポーツです。

MotoGPオーバーテイクが多く、私はバイクの免許を持ってませんが好んでテレビ観戦してます。

MotoGPについて何か分析したいなということで、コースごとのベストラップを整理してみることにしました。

コース ライダー レコード スピード ラップ
カタール 2018 ヨハン・ザルコ 1'53.680 170.3 Km/h 5380m
アルゼンチン 2014 マルク・マルケス 1'37.683 177.1 Km/h 4806m
アメリカズ 2015 マルク・マルケス 2'02.135 162.4 Km/h 5513m
スペイン 2018 カル・クラッチロー 1'37.653 163.0 Km/h 4423m
フランス 2018 ヨハン・ザルコ 1'31.185 165.2 Km/h 4185m
イタリア 2018 ヴァレンティーノ・ロッシ 1'46.208 177.7 Km/h 5245m
カタルニア 2018 ホルヘ・ロレンソ 1'38.680 168.8 Km/h 4627m
オランダ 2015 ヴァレンティーノ・ロッシ 1'32.627 176.5 Km/h 4542m
ドイツ 2018 マルク・マルケス 1'20.270 164.6 Km/h 3671m
チェコ 2016 マルク・マルケス 1'54.596 169.7 Km/h 5403m
オーストラリア 2016 アンドレア・イアンノーネ 1'23.142 186.9 Km/h 4318m
イギリス 2017 マルク・マルケス 1'59.941 177.0 Km/h 5900m
サンマリノ 2018 ホルヘ・ロレンソ 1'31.629 166.0 Km/h 4226m
アラゴン 2015 マルク・マルケス 1'46.635 171.4 Km/h 5077m
タイ 2018 マルク・マルケス 1'30.031 182.0 Km/h 4554m
日本 2015 ホルヘ・ロレンソ 1'43.790 166.5 Km/h 4801m
オーストラリア 2013 ホルヘ・ロレンソ 1'27.899 182.1 Km/h 4448m
マレーシア 2015 ダニ・ペドロサ 1'59.053 167.6 Km/h 5543m
バレンシア 2016 ホルヘ・ロレンソ 1'29.401 161.2 Km/h 4005m

テレビで観ると、素人にはどれも同じようにしか見えないのですが、やはりコースの距離もタイムも違いますね。

f:id:rimever:20190103191017p:plain

距離が長ければタイムが長くなるのは自然。

一番短いのがドイツ。一番長いのがイギリスとなりました。

線分は回帰分析を行った結果なのですが、やや大きく外れたのはオーストラリアでしょうか。

平均時速も180km/hと高速コースで、抜きどころが多いのかもしれませんね。

マルケスの万能ぶりは言わずもがな。チャンピオンですから。

ポールポジションから1位で逃げ切るのを得意とするロレンソもベストラップを多く残しており、彼は短いコースが多くなってますね。

ドゥカティでは苦しみ、やっと2018年で結果を出し始めていましたが、それがどうなるのか。

主観で語るホルヘ・ロレンソ

データ、関係なく、ホルヘ・ロレンソについて主観だけで勝手に語ってしまいます。

2017年からMotoGPを観戦し始めた私からすると、ホルヘ・ロレンソは、「かつての王者」という印象でした。

チャンピオンになったことがあるため名前は取り上げられるも、パッとせず。

ドゥカティのチームメイトであるドヴィツィオーゾが優勝争いをしている点が、その印象をさらに増してました。

ところが、2018年ではいくつかのレースでロレンソらしい走りを見せてくれました。

ぶっちぎりの1位で最終ラップには自分のファンの席に指を立てるパフォーマンスを見せてからの、ファンからするとおなじみの旗を地面に突き立てるパフォーマンスなんてのもありました。

ロレンソが取るレースは、私からするとオーバーテイクがなく面白くないのが本音。

しかし、下記の記事と写真を見て振り返ってみると、ドゥカティでパッとしないところから、本来の走りを見せるまでに至った過程は、大きなオーバーテイクなのかなと感じました。

jp.motorsport.com

この歓喜の瞬間は写真がよく表してますし、それまでの苦しみが記事を読んでいると、シーズンの走りを見た側からすると伝わってきます。

マルケスとロレンソが、2019年はレプソル・ホンダでチームメイトとなります。

ロレンソが勝つレースはオーバーテイクは期待できないので、彼がベストラップを叩き出すことを楽しみにしましょう。

f1-gate.com

おそらく、来年も日テレで放映されると思いますので、少しでも興味を持たれた方は録画してみて片手間でもいいので見てください。

www.ntv.co.jp

pandas.DataFrame.groupbyした結果に対して、平均値でソートして箱ひげ図で表示したい

https://gist.github.com/rimever/90d1933ed481b044a94299f09c773685

pandas.DataFrameはgroupby関数で指定のカラムでグルーピングすることが出来るのですが、もどかしいことがありました。

  1. groupbyでグルーピング
  2. 箱ひげ図で表示してみる

というのは私がよくやるパターンなのですが、

f:id:rimever:20190108210702p:plain

このようになり、値の平均値でソートされて欲しいとモヤモヤすることがありました。

上記の図だと、3種類でいいのですが、これが多くなると見づらくなって来ます。

f:id:rimever:20181120214449p:plain

ここまで来ると、ややこしくなって来ます。

グループごとの平均値でソートした状態で並ぶといいのになと思って、毎回方法を探しては見つからず諦めていたのですが、やっとわかったのでその方法を紹介します。

from sklearn.datasets import load_iris
import pandas as pd
import matplotlib.pyplot as plt

iris_bunch = load_iris()
df = pd.DataFrame(iris_bunch.data, columns=iris_bunch.feature_names)
df['target'] = pd.Series(pd.Categorical.from_codes(iris_bunch.target, categories=iris_bunch.target_names))

group_label = 'target'
target_label = 'sepal width (cm)'

grouped = df.groupby(group_label)
agg = df.groupby(group_label).agg('mean').sort_values(target_label)

Y = []
labels = []
for index in agg.index.values:
    labels.append(index)
    Y.append(grouped.get_group(index)[target_label])
    
fig,ax = plt.subplots()
ax.boxplot(Y,labels=labels,vert=False)
plt.xlabel(target_label)
plt.ylabel(group_label)
plt.grid(True)
plt.show()

f:id:rimever:20190108212011p:plain

このようにソートされて表示されます。

agg関数で集約した値を用いて、グルーピングされた内容から必要な順に取得しています。

Gistにも挙げておきます。

DataFrameをGroupByした結果に対して、平均値でソートしたい場合 · GitHub

TeamCity 2018.2へのアップデート。リリースノートもチェック

TeamCityとはJenkinsと同じ類のビルドサーバーアプリケーションのことです。

最近、Jupyter Notebook(Python)ばかりやっていたので、ほとんど稼働していないのですが。

年も明けたことでしたし、ずっとこけ続けていたTeam Cityのジョブの見直しを行い、2018.2にアップデートをしました。

アップデート自体は、サーバーアプリケーション上でUpdateを選択すればOK。

ビルドエージェント側については、Connectionがおかしかったので勝手に再インストールが必要と解釈して、アンインストール+インストールしましたが、そんな手順不要だったかもしれないです。

リリースノート

リリースノートは下記。

What's New in TeamCity 2018.2 - TeamCity 2018.x Documentation - Confluence

その中で、私の主観でピックアップします。

より簡単にプラグインのインストールできる

画像と私の稚拙な英語力で判断する限り、TeamCityのサーバーアプリを再起動せずにプラグインを有効に出来るようです。

これは何気にすごいことだと思います。

職場のJenkinsはこれがネックでなかなか再起動しづらいです。

動作を保証するのが、結構苦労しそうな気も。

NuGetフィードの改善

TeamCityをNuGetサーバーとして使えること自体、知りませんでした。

NuGetサーバー API v3をサポートしたとのこと。

テスト実行の詳細追加(Support for test run additional details)

和訳すると試運転などとなってしまいましたが。

テスト実行が失敗した時に詳細が確認できるとのこと。

サイトのイメージ画像を見てもいまいちわからないのですが、テストが失敗した時の楽しみにすることにします。(それじゃ、ダメか)

テスト失敗のコミッター調査

テストの失敗内容から、失敗を引き起こしたコミッターを突き止めるとのこと。

これは、もうビルド警察TeamCityですね。

私のプライベートプロジェクトは私一人だけなので、そんなことせずとも犯人はわかるのですが。

さいごに

無料で使わせてもらってるのにUpdateさせていただき、JetBrainsには感謝してます。

日本で私くらいなのかなと思ってましたが、流石にそんなことないですね。

仕事で利用されている会社さんもあります。

Jupyter Notebookでアニメーション。Azure NotebooksでもGoogle Colaboratoryでも。

現在、下記の記事で勉強中なのですが、Jupyter Notebookでアニメーションすることができるようです。

book.mynavi.jp

こんなこともできるのかと驚き、調子に乗ってツイートしてしまいました。

twitter.com

引用元は以下の記事のようです。

Embedding Matplotlib Animations in Jupyter Notebooks | Louis Tiao

アニメーション自体は、matplotlibのAPIとして提供されているので、こちらを使っているようです。

animation — Matplotlib 3.0.2 documentation

ただJupyter Notebookで表示させるポイントとしては、アニメーションをto_jshtml関数を用いてIPython.displayモジュールのHTMLで表示させる点ですね。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro', animated=True)
plt.close()


def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)

#サンプルコードではplt.show()だけど
#plt.show()

# HTMLで
HTML(ani.to_jshtml())

下記のような画面になります。

f:id:rimever:20181231154040p:plain

Jupyter Notebookの仲間では

Jupyter Lab

こちらではうまく動きませんでした。ローカルでもAzure Notebooks上のJupyterLabでも同様です。

以下のように表示がおかしくなりました。

f:id:rimever:20181231155027p:plain

Azure Notebooks

Azure Notebooksでは可能です。

Google Colaboratory

Google Colaboratoryでも可能です。

私の手元でも動作確認出来たのですが、下記のブログでも紹介されています。

yaju3d.hatenablog.jp

ただ、保存に失敗したのは私だけ?

Datalore

Dataloreだとダメでした。

plt.close()のコードを削除することで、それっぽいのは表示されたのですが、再生ボタンが表示できませんし、アニメーションもされません。

f:id:rimever:20181231160734p:plain
再生ボタンが