【B.LEAGUE(B2)】Pythonデータ分析(西宮STORKS編)

今回はプログラミング言語であるPythonを用いて、B.LEAGUE B2所属の 「西宮STORKS」のスタッツをデータ分析してみました。

本ブログでは主に、チームの特徴や勝敗のポイントなどを記載していきます。また、最後には説明用に記載しているレーダーチャートのサンプルコードも記載しています。

ぜひご覧ください。

1. 2020年度B2リーグ順位表

まず、レギュラーシーズンのB2順位表を確認します。

表 B2順位表

西宮STORKSは全体第3位となります。とても好成績を残していますね。この強さはどこにあるのか、スタッツから分析していきます。

Baran

西宮STORKSのスタッツを見ていきましょう!

2. 平均スタッツ

西宮STORKSのスタッツを確認していきます。以下のレーダーグラフはB2リーグの平均値を50とする偏差値方式で表示しています。具体的な数値や、平均値のランクはその都度記載していきます。

「Team」の項目は、本記事の対象チーム(今回は西宮STORKS)の値、「OppTeam」は本記事対象チームの対戦相手の値となります。「OppTeam」の値は小さい方が本記事の対象チームにとって値が高いということになります。(Opp-Rankは本記事対象チームから見た順位です)

まずは基本スタッツを確認します。

図1 基本スタッツ
表1-1 基本スタッツ
表1-2 基本スタッツ(対戦相手)

特筆すべきは、B2リーグ3位のPTS(得点)、B2リーグ1位のFTM(FT成功数)、Opp-TRB、Opp-DRBがB2リーグ2位の少なさになっています。BLKも全体2位ですね。

4 Factorも確認しておきます。

図2 4-Factor
表2-1 4-Factor
表2-2 4-Factor(対戦相手)

4-Factorを見ると、ORB%、TOV%、FT/FGAが全体2,3位と高スタッツです。

3. 得点関連

得点の取得割合を見ていきます。まずはシュートアテンプト数です。

図3 シュートアテンプト数
表3-1 シュートアテンプト数
表3-2 シュートアテンプト数(対戦相手)

STORKSは、FTアテンプト数がリーグ2位の平均22.8回です。また、FGAに対し、IPAの割合が高いため、インサイドで攻めるスタンスに見受けられます。一方、3PA%はリーグ13位ですので、そこまで3Pを打つチームではなさそうです。

一方、Opp-3PA%もB2リーグ3位の少なさから、対戦相手も3Pを打たせない守備を行っているように見受けられます。

また、得点ケースを見てみましょう。

図4 得点ケース
表4-1 得点ケース
表4-2 得点ケース(対戦相手)

得点ケースでは、FTでの得点がリーグ2位なので、ファールをもらうのが得意なチームのようです。

対する対戦相手は、Opp-2P/PTSや、Opp-PitP%が高いので、インサイドの守備に苦労いていたようです。

4. アシスト関連

アシストとシュート%を確認します。

図5 アシストとシュート%
表5-1 アシストとシュート%
表5-2 アシストとシュート%(対戦相手)

アシストとシュート%は総じて、B2リーグ平均を上回っています。

5. リバウンド関連

リバウンドを制するチームはゲームを制するリバウンドスタッツです。

図6 リバウンド
表6-1 リバウンド
表6-2 リバウンド(対戦相手)

リバウンドスタッツはORB%が高く、あ対戦相手もDRBを抑えているようです。

6. 勝敗時のスタッツ比較

ここからはSTROKSの勝敗要因を探っていきますので、勝敗別にスタッツを見直してみます。

特に注目スべきスタッツは以下です。

6-1. 敗戦時はFGA、FTAが減少、3PA、OPAは増加する

図7 勝敗時のシュートアテンプト数
表7 勝敗時のシュートアテンプト数

STORKSは敗戦時にFGAが減少する傾向があり、一方で外側のシュート(3P, OP)のアテンプト数が増加する傾向があり、得点効率が減少していると推察されます。

インサイドが責められなくなると、少しチーム事情が苦しくなったのではと推察されます。

6-2. 敗戦時はシュート%、特にFT%が減少傾向にある

図8 勝敗時のアシストとシュート%
表8 勝敗時のアシストとシュート%

勝利時は総じて偏差値は高いですが、敗戦時は全体的にシュート%が減少しています。これは前述の通り、確率の低い外側のシュート数が増えてしまうことに起因すると推察されます。

また、西宮はFT/PTSが高いチームなので、FT%が減少すると少し後手に踏んでいたのではと推察します。

7. 考察

B2リーグ全体3位あり、インサイドとFTでしっかり得点を稼ぐ安定したチームであったと思われます。インサイドの強さをしっかり出せるかが勝利の鍵と推察します。

Sakura

GO!GO! STORKS!!

8. サンプルコード

以下は、Pythonでのレーダーチャートのコード例です。

df_teamは本記事対象チームの2020年度平均スタッツ、df_oppteamは対戦相手の2020年度平均スタッツとなります。

まず、polar_list関数で、表示したデータを抽出して辞書化します。その後、plot_polar関数でレーダーチャートを表示します。

def poloar_list(df_team, df_oppteam, b_team):
    polar_list1 = ['PTS', '3PM', '2PM', 'FTM', 'AST', 'TOV', 'STL', 'ORB', 'TRB', 'DRB', 'BLK']
    polar_list2 = ['eFG%', 'ORB%', 'TOV%', 'FT/FGA']
    polar_list3 = ['FGA', '3PA', '3PA%', 'OPA', 'OPA%', '2PA', '2PA%', 'IPA', 'IPA%', 'FTA']
    polar_list4 = ['PTS', '3P/PTS', '2P/PTS', 'PfT%', 'PitP%', 'SCP%', 'FBP%', 'FT/PTS']
    polar_list5 = ['AST', 'TOV', 'AST/TOV', 'STL', '3P%', '2P%', 'FG%']
    polar_list6 = ['ORB', 'ORB%', 'Opp_DRB', 'DRB', 'DRB%', 'Opp_ORB', 'TRB', 'TRB%', 'Opp_TRB']

    df_team = df_team.loc["{}".format(b_team)]
    df_oppteam = df_oppteam.loc["{}".format(b_team)]
    df_polar_team = df_team[polar_list1]
    df_polar_oppteam = df_oppteam[polar_list1]
    df_polar_team_4factor = df_team[polar_list2]
    df_polar_oppteam_4factor = df_oppteam[polar_list2]
    df_polar_team_attempt = df_team[polar_list3]
    df_polar_oppteam_attempt = df_oppteam[polar_list3]
    df_polar_team_point = df_team[polar_list4]
    df_polar_oppteam_point = df_oppteam[polar_list4]
    df_polar_team_ast = df_team[polar_list5]
    df_polar_oppteam_ast = df_oppteam[polar_list5]
    df_polar_team_rb = df_team[polar_list6]
    df_polar_oppteam_rb = df_oppteam[polar_list6]
    df_dict = {
                0: ["Team", df_polar_team], 1: ["Oppteam", df_polar_oppteam],
                2: ["Team_4factor", df_polar_team_4factor], 3: ["Oppteam_4factor", df_polar_oppteam_4factor],
                4: ["Team_Attempt", df_polar_team_attempt], 5: ["Oppteam_Attempt", df_polar_oppteam_attempt],
                6: ["Team_point", df_polar_team_point], 7: ["Oppteam_point", df_polar_oppteam_point],
                8: ["Team_AST", df_polar_team_ast], 9: ["Oppteam_AST", df_polar_oppteam_ast],
                10: ["Team_RB", df_polar_team_rb], 11: ["Oppteam_RB ", df_polar_oppteam_rb]
    }
    return df_dict


def plot_polar(df_dict, b_team, N=2):
    sns.set(font_scale=1.0)
    fig, ax = plt.subplots(6, N, figsize=(12, 48), subplot_kw={'projection': 'polar'})
    for i, df in df_dict.items():
        x, y = divmod(i, N)
        labels = df[1].index
        values = list(df[1])
        angles = np.linspace(0, 2 * np.pi, len(labels) + 1, endpoint=True)
        values = np.concatenate((values, [values[0]]))
        ax[x, y].plot(angles, values, 'o-', color="blue", label="Overall: {}".format(round(df[1].mean(), 1)))
        ax[x, y].fill(angles, values, alpha=0.25, color="blue")  

        ax[x, y].set_rlim(20, 80)

        ax[x, y].set_thetalim([-np.pi, np.pi])
        ax[x, y].set_thetagrids(angles[:-1] * 180 / np.pi, labels, fontsize=15)
        ax[x, y].set_theta_zero_location('N')

        ind = 2
        gridlines = ax[x, y].yaxis.get_gridlines()
        gridlines[2].set_color("black")
        gridlines[ind].set_linewidth(1)
        gridlines[ind].set_linestyle("--")
        ax[x, y].set_title("{0}: {1} ".format(df[0], b_team), fontsize=15)
        ax[x, y].legend(bbox_to_anchor=(0.5, -0.18), loc= 'lower center')

    plt.tight_layout()
    plt.show()

こちらの記事を参照させていただきました↓

公式のサンプルはうまくプロットできないし、コードが長くて死ぬ。

シンプルにレーダーチャートを描きたいだけなのに…。

Matplotlibでレーダーチャートを描く(16行)
Baran

以下の記事も書いています。よかったらご覧ください。

Twitterもやってまーす。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT US

Baran-gizagiza
経歴:浪人→理系大学院卒業→大手製造業に就職(技術職)→アメリカ赴任中 仕事は、研究・設計など上流工程の仕事に携わっています。企業勤務を継続しながら、新しいことにチャレンジしたいと思い、ブログを下記はじめました。 このブログでは、趣味である 筋トレ(健康、ダイエット) AIとデータ(高校数学、プログラミング) 読書(主に自己啓発系) を中心に、人生経験やおすすめ情報の発信しています。