PR

番外編: 血統から産駒の適正距離や馬場を知る

Python
この記事は約33分で読めます。
スポンサーリンク

番外編: 血統と成長度の関係

前回の重賞クラスと血統の関係では、血統による成長度合いが見られなかった。
そのため、番外編として重賞クラスだけでなく全体の出走情報を分析し、
血統ごとに成長度合いが変わってくるのか確認する

前回の内容

血統から競走馬の成長度合いを分析する方法
競馬予想AIの制作過程をサイトにのこしているものです。今回は血統データ24年分を調べて分かったその競走馬が早くから活躍するかそうでないかを知る方法を共有します。
スポンサーリンク

2-0.下準備¶

ソースの一部は有料のものを使ってます。
同じように分析したい方は、以下の記事から入手ください。

競馬予想AI 統合分析プログラムの記事

2-0-1.必要そうなものをインポート¶

In [1]:
import random
from wordcloud import WordCloud
import seaborn as sns
import japanize_matplotlib

import matplotlib.pyplot as plt
import re

from typing import Literal
import pathlib


import warnings
import sys
import pandas as pd
sys.path.append("..")

from src.core.db.controller import execSQL, getTableList, getDataFrame  # noqa
from src.data_manager.preprocess_tools import DataPreProcessor  # noqa
from src.data_manager.data_loader import DataLoader  # noqa


warnings.filterwarnings("ignore")
# 接続先DB (このnotebookの場所が「notebook」フォルダにあるので一つ上の階層に戻ってDBファイルパスを生成)
root = pathlib.Path(".").absolute().parent
dbpath = root / "data" / "keibadata.db"


# 血統情報が入っているテーブルは「horseblood」という接頭辞がついたテーブルなので、その一覧を取得
horseblood_list = [tbl for tbl in getTableList(dbpath) if "horseblood" in tbl]
horseblood_list.sort(key=lambda x: int(x[-4:]))
horseblood_list
# DBから取得:concatでhorseblood_listにあるテーブル情報のDataFrameをすべて結合する
dfblood = pd.concat(
    [getDataFrame(tbl, dbpath) for tbl in horseblood_list], ignore_index=True)

start_year = 2000
end_year = 2023

data_loader = DataLoader(start_year, end_year, dbpath=dbpath)
dataPreP = DataPreProcessor()
df = data_loader.load_racedata()
df = dataPreP.exec_pipeline(df)


def add_blood_info_to_df(df: pd.DataFrame, mode: Literal["s", "ss", "sb", "b", "bs", "bb", "sss", "ssb", "sbs", "sbb", "bss", "bsb", "bbs", "bbb"]):
    index_map = {
        "s": (0, "stallion", "gen1"), "ss": (0, "sStallion", "gen2"), "sb": (8, "sBreed", "gen2"),
        "sss": (0, "s2Stallion", "gen3"), "ssb": (4, "s2Breed", "gen3"), "sbs": (8, "sbStallion", "gen3"), "sbb": (12, "sbBreed", "gen3"),
        "b": (16, "breed", "gen1"), "bs": (16, "bStallion", "gen2"), "bb": (24, "bBreed", "gen2"),
        "bss": (16, "bsStallion", "gen3"), "bsb": (20, "bsBreed", "gen3"), "bbs": (24, "b2Stallion", "gen3"), "bbb": (28, "b2Breed", "gen3"),
    }
    idx, prefix, genCol = index_map[mode]
    idf = dfblood.iloc[idx::32].reset_index(drop=True)
    idf[genCol] = idf[genCol].str.split("\n", expand=True)[
        0].str.replace("\n", "")
    df[f"{prefix}Id"] = df["horseId"].map(
        idf.set_index("horseId")[f"{genCol}ID"])
    df[f"{prefix}Name"] = df["horseId"].map(idf.set_index("horseId")[genCol])
    return df, idf[["horseId", genCol, f"{genCol}ID"]].rename(columns={genCol: "GenName", f"{genCol}ID": "GenID"})


df, dfstallion = add_blood_info_to_df(df, "s")
df, dfbStallion = add_blood_info_to_df(df, "bs")

listed_racename_list = [rname.replace("(L)", "") for rname in df[df["raceName"].str.contains(
    r"\(L\)", regex=True)]["raceName"].unique()]

listed_racename_list = df[df["raceName"].str.contains(
    "|".join(listed_racename_list))]["raceName"].unique().tolist()

listed_mapping = {rname: 5 for rname in listed_racename_list}


# それぞれのマッピングを作っておく
def map_race_grade(data: str):
    if re.search(r"\(G1\)", data) or re.search(r"\(GI\)", data):
        return 8

    if re.search(r"\(G2\)", data) or re.search(r"\(GII\)", data):
        return 7

    if re.search(r"\(G3\)", data) or re.search(r"\(GIII\)", data):
        return 6

    return None


grade_mapping_dict = {
    '4歳未勝利': 0, '4歳新馬': 0, '4歳以上500万下': 1, '4歳500万下': 1, '4歳以上900万下': 2, '4歳以上オープン': 4,
    '4歳以上1600万下': 3, '4歳オープン': 4, '4歳未出走': 0, '5歳以上オープン': 4, '4歳900万下': 2, '3歳新馬': 0,
    '3歳未勝利': 0, '3歳オープン': 4, '3歳500万下': 1, '3歳未出走': 0, '3歳以上オープン': 4, '3歳900万下': 2,
    '2歳新馬': 0, '3歳以上500万下': 1, '3歳以上1000万下': 2, '2歳未勝利': 0, '2歳オープン': 4, '3歳以上1600万下': 3,
    '2歳500万下': 1, '4歳以上1000万下': 2, '3歳1000万下': 2, '3歳以上1勝クラス': 1, '3歳以上2勝クラス': 2,
    '3歳以上3勝クラス': 3, '2歳1勝クラス': 1, '3歳1勝クラス': 1, '4歳以上1勝クラス': 1, '4歳以上2勝クラス': 2,
    '4歳以上3勝クラス': 3
}


# クラスをグレードに置き換える
idf = df["raceName"].map(map_race_grade)
idf = idf[~idf.isna()]
idf2 = df[~df.index.isin(idf.index)]["raceName"].map(listed_mapping)
idf2 = idf2[~idf2.isna()]

df["raceGrade"] = pd.concat([idf, idf2, df[~df.index.isin(idf.index.tolist(
)+idf2.index.tolist())]["raceDetail"].map(grade_mapping_dict)]).astype(int)
2024-07-31 20:21:40.604 | INFO     | src.data_manager.data_loader:load_racedata:23 - Get Year Range: 2000 -> 2023.
2024-07-31 20:21:40.605 | INFO     | src.data_manager.data_loader:load_racedata:24 - Loading Race Info ...
2024-07-31 20:21:41.339 | INFO     | src.data_manager.data_loader:load_racedata:26 - Loading Race Data ...
2024-07-31 20:21:56.843 | INFO     | src.data_manager.data_loader:load_racedata:28 - Merging Race Info and Race Data ...
2024-07-31 20:21:59.120 | INFO     | src.data_manager.preprocess_tools:__0_check_use_save_checkpoints:35 - Start PreProcess #0 ...
2024-07-31 20:21:59.124 | INFO     | src.data_manager.preprocess_tools:__1_exec_all_sub_prep1:38 - Start PreProcess #1 ...
2024-07-31 20:22:05.736 | INFO     | src.data_manager.preprocess_tools:__2_exec_all_sub_prep2:40 - Start PreProcess #2 ...
2024-07-31 20:22:19.078 | INFO     | src.data_manager.preprocess_tools:__3_convert_type_str_to_number:42 - Start PreProcess #3 ...
2024-07-31 20:22:23.077 | INFO     | src.data_manager.preprocess_tools:__4_drop_or_fillin_none_data:44 - Start PreProcess #4 ...
2024-07-31 20:22:26.861 | INFO     | src.data_manager.preprocess_tools:__5_exec_all_sub_prep5:46 - Start PreProcess #5 ...
2024-07-31 20:22:50.972 | INFO     | src.data_manager.preprocess_tools:__6_convert_label_to_rate_info:48 - Start PreProcess #6 ...
2024-07-31 20:23:02.670 | INFO     | src.data_manager.preprocess_tools:__7_convert_distance_to_smile:50 - Start PreProcess #7 ...
2024-07-31 20:23:02.925 | INFO     | src.data_manager.preprocess_tools:__8_category_encoding:52 - Start PreProcess #8 ...
2024-07-31 20:23:07.998 | INFO     | src.data_manager.preprocess_tools:__9_convert_raceClass_to_grade:54 - Start PreProcess #9 ...
スポンサーリンク

1. 分析方針: 成長度合いを調べるための評価方法¶

前提
馬主としては勝てる競走馬が欲しいわけなので、
なかなか勝てない競走馬を中央競馬で出走させ続けるわけにはいかないと考える。
そのため、一度も勝てない競走馬は分析の対象外とする
仮定
1勝以上した競走馬のみに絞って、
2勝するまでの出走回数の長さで血統に違いが出てくるのでは?

1-1.1998年以降生まれで1勝以上している競走馬のみに絞る¶

In [2]:
df["birthY"] = df["horseId"].str[:4].astype(int)
df["birthY"].sort_values().unique()
Out[2]:
array([1986, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
       2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
       2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021])
In [3]:
filter_raceId_list = df[df["birthY"].isin(
    list(range(1998, 2024)))]["raceId"].unique()
dfG = df[df["raceId"].isin(filter_raceId_list)]
dfG["year"] = dfG["raceDate"].dt.year

1勝以上している競走馬のみに絞り込む

In [4]:
dfG["win"] = dfG["label"].isin([1]).astype(int)

Ghorse_list = dfG[~dfG["win"].isin([0]) & dfG["birthY"].isin(
    list(range(1998, 2024)))]["horseId"].unique()



dfG = dfG[dfG["horseId"].isin(Ghorse_list)]

1-2.軽く集計する¶

In [5]:
dfG.groupby("horseId")["horseId"].value_counts().describe().to_frame().T
Out[5]:
count mean std min 25% 50% 75% max
count 35093.0 19.011712 11.163041 1.0 11.0 17.0 25.0 100.0

集計結果から、1勝以上している競走馬は平均して19レース強走っており、
中央値から半数以上の競走馬は17レース以上出走していることが分かる。

スポンサーリンク

2.2勝するまでの出走回数と血統の関係を見る¶

In [6]:
# 関数を使いまわす
def count_raceNum_for_G(target: list[int], firstwin=list(range(1, 9)), mode=True, dfG=None):
    group_df = dfG.groupby("horseId")[["label", "raceGrade"]].filter(
        lambda group: group[group["raceGrade"].isin(target)]["label"].isin([1]).any())
    dfG1 = dfG.loc[group_df.index][["horseId", "birthY", "raceGrade", "label"]]

    dfG1 = dfG1[dfG1["birthY"].isin(list(range(1998, 2024)))]
    dfG1["win"] = (dfG1["label"].isin([1]) &
                   dfG1["raceGrade"].isin(firstwin)).astype(int)
    dfG1["win"] = dfG1.groupby("horseId")["win"].cumsum()
    win_horseId_list = []
    dfG2 = dfG1[dfG1["win"].isin([0])]
    if 0 in target:
        win_horseId_list = list(
            set(dfG1["horseId"].unique()) - set(dfG2["horseId"].unique()))
    dfG_cnt = dfG2.groupby("horseId")["horseId"].count()
    dfG_cnt = pd.concat([dfG_cnt, pd.Series(0, index=win_horseId_list)])
    if mode:
        return dfG_cnt.describe()
    return dfG_cnt

2-1.2勝目するまでの出走回数を出す¶

In [7]:
dfW2des = count_raceNum_for_G(list(range(9)), dfG=dfG)
dfW2des
Out[7]:
count    35093.000000
mean        10.733936
std          7.453142
min          0.000000
25%          5.000000
50%          9.000000
75%         14.000000
max         84.000000
dtype: float64

結果から最小で1レースで2勝目を揚げているもの(つまり値が0のもの)は恐らく新馬戦を地方競馬で勝ったからだと思われるので除外して良い

In [8]:
# 2勝するまでの出走回数が0のものを除外
dfW2 = count_raceNum_for_G(list(range(9)), dfG=dfG, mode=False)
dfW2 = dfW2[~dfW2.isin([0])]
dfW2.describe()
Out[8]:
count    35027.000000
mean        10.754161
std          7.445568
min          1.000000
25%          5.000000
50%          9.000000
75%         14.000000
max         84.000000
dtype: float64

面白いことに、2勝目するまでの平均出走回数は11レース弱であり、
中央値からおおよそ9走以内に2勝する競走馬がいる。
しかし、最大値が84走もあることから、1着にならずとも長く競走馬を続けている場合もあるようだ

2-2.1勝以上している競走馬が2勝するまでの種牡馬産駒の平均出走回数を調べる¶

In [9]:
pickup = 15
threash = 0.25
dflist = []
multiColumns = []
# 2019年以降に出走したことのある競走馬のみに絞る
dfG2 = dfG[dfG["horseId"].isin(dfG[dfG["raceDate"].dt.year.isin(
    list(range(2019, 2024)))]["horseId"].unique())]
for g, idfG in dfG2.groupby(["field", "dist_cat"]):
    # field, dist_catごとに出走したことのある競走馬に対して、
    dfG_cnt = count_raceNum_for_G(
        list(range(9)), mode=False, dfG=idfG).rename(f"Grace")
    upperhorse = dfG_cnt[dfG_cnt.quantile(threash) >= dfG_cnt].index.tolist()
    lowerhorse = dfG_cnt[dfG_cnt.quantile(1-threash) < dfG_cnt].index.tolist()
    if len(upperhorse) == 0:
        upperhorse = dfG_cnt[dfG_cnt.isin([dfG_cnt.min()])].index.tolist()
    if len(lowerhorse) == 0:
        lowerhorse = dfG_cnt[dfG_cnt.isin([dfG_cnt.max()])].index.tolist()

    dfGhigh25 = dfG2[dfG2["horseId"].isin(upperhorse)]
    dfGlow25 = dfG2[dfG2["horseId"].isin(lowerhorse)]

    # 種牡馬
    dftarget = dfstallion
    dflist += [dftarget[dftarget["horseId"].isin(dfGhigh25["horseId"].unique())]["GenName"].value_counts().sort_values(
        ascending=False).head(pickup).reset_index().apply(lambda x: ", ".join([str(x) for x in x.tolist()]), axis=1)]
    dflist += [dftarget[dftarget["horseId"].isin(dfGlow25["horseId"].unique())]["GenName"].value_counts().sort_values(
        ascending=False).head(pickup).reset_index().apply(lambda x: ", ".join([str(x) for x in x.tolist()]), axis=1)]

    multiColumns += [[g[0], f"high{int(threash*100)}%", g[1]],
                     [g[0], f"low{int(threash*100)}%", g[1]]]
threash_col = [f"high{int(threash*100)}%", f"low{int(threash*100)}%"]
idfgen = pd.concat(dflist, axis=1).rename(
    index=lambda idx: f"{1+idx}位").fillna("")
idfgen.columns = pd.MultiIndex.from_tuples(multiColumns)
idfgen = idfgen.T.sort_index(key=lambda x: [({"ダ": 0, "芝": 1, f"high{int(threash*100)}%": 0} | {
                             k: n for n, k in enumerate("SMILE")}).get(ix, 1) for ix in x])
idfgen[idfgen.columns[:5]]
Out[9]:
1位 2位 3位 4位 5位
high25% S ヘニーヒューズ, 45 ロードカナロア, 35 キンシャサノキセキ, 24 ダイワメジャー, 18 パイロ, 17
M キングカメハメハ, 53 ハーツクライ, 49 ロードカナロア, 44 ヘニーヒューズ, 43 オルフェーヴル, 39
I キングカメハメハ, 13 ディープインパクト, 9 ゴールドアリュール, 7 ハーツクライ, 6 ルーラーシップ, 5
L キングカメハメハ, 4 キズナ, 3 スクリーンヒーロー, 2 ハービンジャー, 2 ディープインパクト, 2
low25% S サウスヴィグラス, 31 ヘニーヒューズ, 22 キンシャサノキセキ, 20 メイショウボーラー, 18 ゴールドアリュール, 17
M ヘニーヒューズ, 45 ゴールドアリュール, 36 シニスターミニスター, 34 ルーラーシップ, 29 クロフネ, 29
I キングカメハメハ, 4 ハーツクライ, 3 キズナ, 3 ベルシャザール, 3 ダイワメジャー, 3
L ヴァーミリアン, 2 キングカメハメハ, 2 ヴィクトワールピサ, 2 オルフェーヴル, 2 ディープインパクト, 2
high25% S ロードカナロア, 48 ディープインパクト, 26 ダイワメジャー, 25 ルーラーシップ, 11 キンシャサノキセキ, 11
M ディープインパクト, 118 ハーツクライ, 46 ロードカナロア, 46 ハービンジャー, 36 エピファネイア, 35
I ディープインパクト, 106 ハーツクライ, 53 ハービンジャー, 37 キングカメハメハ, 33 ルーラーシップ, 28
L ディープインパクト, 59 ハーツクライ, 25 ルーラーシップ, 20 ハービンジャー, 20 キングカメハメハ, 15
E ディープインパクト, 6 ルーラーシップ, 2 ドゥラメンテ, 2 タイキシャトル, 1 アドマイヤドン, 1
low25% S ダイワメジャー, 22 キンシャサノキセキ, 20 ロードカナロア, 19 ディープブリランテ, 9 マツリダゴッホ, 9
M ディープインパクト, 62 ハーツクライ, 35 ダイワメジャー, 32 ロードカナロア, 30 ハービンジャー, 27
I ディープインパクト, 41 ハーツクライ, 35 ハービンジャー, 31 ルーラーシップ, 22 ステイゴールド, 16
L ディープインパクト, 21 ハービンジャー, 11 ステイゴールド, 10 ゴールドシップ, 10 ハーツクライ, 9
E オルフェーヴル, 3 ディープインパクト, 1 スウェプトオーヴァーボード, 1 キングカメハメハ, 1 ワークフォース, 1

結果から、芝は全く違いがない。ディープインパクトの影響がデカすぎる
その一方で、ダートで見ると早熟グループではキングカメハメハがかなり目立つ結果になっており、
スプリント距離ではヘニーヒューズが最も多い
しかし、大器晩成グループでみると、キングカメハメハの影響は少なく特徴的なのがマイル距離で
ヘニーヒューズがトップとなっている。
単純にヘニーヒューズ産駒は超短距離タイプであり、少しでも距離が長くなると脚が持たないスタミナに課題のある種牡馬なのだと分かる

みんな大好きワードクラウドでも出してみましょう

In [10]:
colormap = "RdYlBu"
# linux系なら以下あたりにフォントファイルがあるかも?調べてもらう方が早いと思います。
# font_path="/usr/share/fonts/truetype/fonts-japanese-gothic.ttf"

# Windowsの人は以下あたりにあるかと
font_path = "C:/Windows/Fonts/meiryo.ttc"

for field in ["ダ", "芝"]:
    idfg = idfgen.loc[field]
    ncols = len(idfg.loc[idfg.index[0][0]])
    nrows = len(threash_col)
    plt.figure(figsize=(27, 9))
    cnt = 1
    for row, idx in enumerate(threash_col, start=1):
        for cidx in "SMILE"[:ncols]:
            word_list = []
            for word in idfg.loc[(idx, cidx)].tolist():
                if word == "":
                    break
                word_list += [word.split(", ")[0]]*int(word.split(", ")[1])
            if len(word_list) == 0:
                break
            random.shuffle(word_list)
            plt.subplot(nrows, ncols, cnt)
            wordcloud = WordCloud(
                background_color="gray",
                width=800,
                height=800,
                font_path=font_path,
                colormap=colormap,
            ).generate(" ".join(word_list))
            plt.imshow(wordcloud, interpolation="bilinear")
            plt.title(", ".join([field, idx, cidx]))
            plt.axis("off")
            cnt += 1
    plt.show()

詳細は述べません、感じてください。

2-3.1勝以上している競走馬が2勝するまでの母父産駒の平均出走回数を調べる¶

In [11]:
pickup = 15
threash = 0.25
dflist = []
multiColumns = []
# 2019年以降に出走したことのある競走馬のみに絞る
dfG2 = dfG[dfG["horseId"].isin(dfG[dfG["raceDate"].dt.year.isin(
    list(range(2019, 2024)))]["horseId"].unique())]
for g, idfG in dfG2.groupby(["field", "dist_cat"]):
    # field, dist_catごとに出走したことのある競走馬に対して、
    dfG_cnt = count_raceNum_for_G(
        list(range(9)), mode=False, dfG=idfG).rename(f"Grace")
    upperhorse = dfG_cnt[dfG_cnt.quantile(threash) >= dfG_cnt].index.tolist()
    lowerhorse = dfG_cnt[dfG_cnt.quantile(1-threash) < dfG_cnt].index.tolist()
    if len(upperhorse) == 0:
        upperhorse = dfG_cnt[dfG_cnt.isin([dfG_cnt.min()])].index.tolist()
    if len(lowerhorse) == 0:
        lowerhorse = dfG_cnt[dfG_cnt.isin([dfG_cnt.max()])].index.tolist()

    dfGhigh25 = dfG2[dfG2["horseId"].isin(upperhorse)]
    dfGlow25 = dfG2[dfG2["horseId"].isin(lowerhorse)]

    # 母父
    dftarget = dfbStallion
    dflist += [dftarget[dftarget["horseId"].isin(dfGhigh25["horseId"].unique())]["GenName"].value_counts().sort_values(
        ascending=False).head(pickup).reset_index().apply(lambda x: ", ".join([str(x) for x in x.tolist()]), axis=1)]
    dflist += [dftarget[dftarget["horseId"].isin(dfGlow25["horseId"].unique())]["GenName"].value_counts().sort_values(
        ascending=False).head(pickup).reset_index().apply(lambda x: ", ".join([str(x) for x in x.tolist()]), axis=1)]

    multiColumns += [[g[0], f"high{int(threash*100)}%", g[1]],
                     [g[0], f"low{int(threash*100)}%", g[1]]]
threash_col = [f"high{int(threash*100)}%", f"low{int(threash*100)}%"]
idfgen = pd.concat(dflist, axis=1).rename(
    index=lambda idx: f"{1+idx}位").fillna("")
idfgen.columns = pd.MultiIndex.from_tuples(multiColumns)
idfgen = idfgen.T.sort_index(key=lambda x: [({"ダ": 0, "芝": 1, f"high{int(threash*100)}%": 0} | {
                             k: n for n, k in enumerate("SMILE")}).get(ix, 1) for ix in x])
idfgen[idfgen.columns[:5]]
Out[11]:
1位 2位 3位 4位 5位
high25% S フレンチデピュティ, 21 フジキセキ, 21 キングカメハメハ, 20 アグネスタキオン, 19 サンデーサイレンス, 18
M キングカメハメハ, 57 シンボリクリスエス, 52 フレンチデピュティ, 51 クロフネ, 49 サンデーサイレンス, 43
I サンデーサイレンス, 7 キングカメハメハ, 6 クロフネ, 6 ネオユニヴァース, 5 ハーツクライ, 5
L キングカメハメハ, 5 ジャングルポケット, 3 Unbridled’s Song, 2 クロフネ, 2 ネオユニヴァース, 2
low25% S クロフネ, 20 フジキセキ, 19 フレンチデピュティ, 17 アグネスタキオン, 13 シンボリクリスエス, 13
M アグネスタキオン, 38 クロフネ, 37 キングカメハメハ, 36 サンデーサイレンス, 34 フレンチデピュティ, 33
I フレンチデピュティ, 4 アドマイヤベガ, 4 キングカメハメハ, 4 スペシャルウィーク, 4 サンデーサイレンス, 3
L ブライアンズタイム, 2 タニノギムレット, 2 サンデーサイレンス, 2 サクラバクシンオー, 1 ディープインパクト, 1
high25% S ディープインパクト, 25 サクラバクシンオー, 15 サンデーサイレンス, 15 スペシャルウィーク, 15 タイキシャトル, 14
M キングカメハメハ, 57 ディープインパクト, 48 サンデーサイレンス, 34 アグネスタキオン, 24 シンボリクリスエス, 19
I キングカメハメハ, 36 サンデーサイレンス, 33 ディープインパクト, 26 クロフネ, 20 シンボリクリスエス, 19
L サンデーサイレンス, 24 キングカメハメハ, 16 ディープインパクト, 15 シンボリクリスエス, 13 クロフネ, 12
E ディープインパクト, 2 ストリートセンス, 1 Machiavellian, 1 Kingmambo, 1 Monsun, 1
low25% S ダンスインザダーク, 13 フジキセキ, 12 クロフネ, 12 キングカメハメハ, 10 サクラバクシンオー, 10
M サンデーサイレンス, 32 ディープインパクト, 32 アグネスタキオン, 27 ダンスインザダーク, 22 ブライアンズタイム, 21
I キングカメハメハ, 22 ディープインパクト, 18 アグネスタキオン, 17 サンデーサイレンス, 17 ダンスインザダーク, 15
L サンデーサイレンス, 8 ダンスインザダーク, 7 ディープインパクト, 6 アグネスタキオン, 5 キングカメハメハ, 4
E ブライアンズタイム, 1 Caerleon, 1 ダンスインザダーク, 1 トニービン, 1 Motivator, 1

逆に母父でみると、重賞クラスの時と違い大きな特徴がみられない
敢えて見つけるならダートの下位25%グループのスプリントとマイル距離でみると、クロフネが該当している。
逆に見てみるとダートの上位25%グループでみると、距離区分「I」と「L」にクロフネが3位と4位にいることから、
短距離よりも長距離が得意な血統なのだろうと見て取れる

また、芝で見るとどちらのグループにもサンデーサイレンスやディープインパクトが入っている。
こうなってくると、母母父側も確認する必要があるのかもしれないが、
そこまでの分析は蛇足だと判断し、芝では母父で見ると大きな特徴がないと判断する。

In [12]:
for field in ["ダ", "芝"]:
    idfg = idfgen.loc[field]
    ncols = len(idfg.loc[idfg.index[0][0]])
    nrows = len(threash_col)
    plt.figure(figsize=(27, 9))
    cnt = 1
    for row, idx in enumerate(threash_col, start=1):
        for cidx in "SMILE"[:ncols]:
            word_list = []
            for word in idfg.loc[(idx, cidx)].tolist():
                if word == "":
                    break
                word_list += [word.split(", ")[0]]*int(word.split(", ")[1])
            if len(word_list) == 0:
                break
            random.shuffle(word_list)
            plt.subplot(nrows, ncols, cnt)
            wordcloud = WordCloud(
                background_color="gray",
                width=800,
                height=800,
                font_path=font_path,
                colormap=colormap,
            ).generate(" ".join(word_list))
            plt.imshow(wordcloud, interpolation="bilinear")
            plt.title(", ".join([field, idx, cidx]))
            plt.axis("off")
            cnt += 1
    plt.show()
スポンサーリンク

3.まとめ¶

逆に2勝するまでの出走回数で分析をしてみたところ、種牡馬の方で特にダートで特徴がみられた。
ダートと芝では活躍してきた競走馬が違いすぎるのだろうと思われ、
素人の私でも芝で活躍してきた競走馬の名前は聞いたことがあるのが多いので、
日本語の競馬ではダートよりも芝の方が人気が高いのかもしれない。

コメント

タイトルとURLをコピーしました