def factory_analyze_race_result_df(self, raceuma_result_df, dict_path): """ レースの因子を計算。それぞれ以下の意味 # fa1: 数値大:底力指数 # fa2: 数値大:末脚指数 # fa3: 数値大:スタミナ指数 # fa4: 両方向:レースタイプ # fa5: 数値大:高速スピード指数 """ dict_folder = dict_path + 'dict/jra_common/' fa_dict_name = "fa_raceuma_result_df" fa = mu.load_dict(fa_dict_name, dict_folder) fa_list = [ '1着算入賞金', 'ラップ差4ハロン', 'ラップ差3ハロン', 'ラップ差2ハロン', 'ラップ差1ハロン', 'TRACK_BIAS_ZENGO', 'TRACK_BIAS_UCHISOTO', 'ハロン数', '芝', '外', '重', '軽', '1ハロン平均_mean', 'IDM結果_mean', 'テン指数結果_mean', '上がり指数結果_mean', 'ペース指数結果_mean', '追走力_mean', '追上力_mean', '後傾指数_mean', '1ハロン平均_std', '上がり指数結果_std', 'ペース指数結果_std' ] df_data_org = raceuma_result_df[fa_list] sc_dict_name = "fa_sc_raceuma_result_df" scaler = mu.load_dict(sc_dict_name, dict_folder) df_data = pd.DataFrame(scaler.transform(df_data_org), columns=df_data_org.columns) fa_df = pd.DataFrame(fa.transform(df_data.fillna(0)), columns=["fa_1", "fa_2", "fa_3", "fa_4", "fa_5"]) raceuma_result_df = pd.concat([raceuma_result_df, fa_df], axis=1) return raceuma_result_df
def get_analyzed_result_df(cls, base_df): analyzed_df = mu.load_dict("analyzed_df", cls.dict_folder) for target in cls.analyze_target: for cls_val_type in cls.class_list: filterd_analyze_df = analyzed_df[[target, cls_val_type, "平均差"]].dropna() base_df = pd.merge(base_df, filterd_analyze_df, on=[target, cls_val_type], how='left').fillna({"平均差":0}).rename(columns={"平均差": "平均差_" + target + cls_val_type}) return base_df
def bk_factory_analyze_raceuma_result_df(self, input_raceuma_df, dict_folder): """ RaceUmaの因子分析を行うためのデータを取得 """ fa_list = [ '芝ダ障害コード', '右左', '内外', '種別', '条件', '記号', '重量', "頭数", "着順", '馬場状態', "タイム", "確定単勝オッズ", "コース取り", "上昇度コード", "馬体コード", "気配コード", "レースペース", "馬ペース", "1(2)着タイム差", "前3Fタイム", "後3Fタイム", "確定複勝オッズ下", "10時単勝オッズ", "10時複勝オッズ", "コーナー順位1", "コーナー順位2", "コーナー順位3", "コーナー順位4", "前3F先頭差", "後3F先頭差", "天候コード", "コース", "レース脚質", "4角コース取り", "確定単勝人気順位", "素点", "素点", "馬場差", "ペース", "出遅", "位置取", "前不利", "中不利", "後不利", "レース", "クラスコード", "レースペース流れ", "馬ペース流れ", "グレード" ] X = input_raceuma_df[fa_list].fillna(0) str_list = X.select_dtypes(include=object).columns.tolist() X[str_list] = X[str_list].astype(int) X.iloc[0] = X.iloc[0] + 0.000001 dict_name = "fa_raceuma_result_df" filename = dict_folder + dict_name + '.pkl' if os.path.exists(filename): fa = mu.load_dict(dict_name, dict_folder) else: fa = PCA(n_components=5) #fa = FactorAnalyzer(n_factors=5, rotation='promax', impute='drop') fa.fit(X) mu.save_dict(fa, dict_name, dict_folder) fa_np = fa.transform(X) fa_df = pd.DataFrame(fa_np, columns=["fa_1", "fa_2", "fa_3", "fa_4", "fa_5"]) X_fact = pd.concat([input_raceuma_df.drop(fa_list, axis=1), fa_df], axis=1) return X_fact
def factory_analyze_raceuma_result_df(self, race_df, input_raceuma_df, dict_folder): """ RaceUmaの因子分析を行うためのデータを取得 """ print("factory_analyze_raceuma_result_df") temp_df = pd.merge(input_raceuma_df, race_df, on="競走コード") X = temp_df[[ '競走コード', '馬番', '枠番', 'タイム指数', '単勝オッズ', '先行率', 'ペース偏差値', '距離増減', '斤量比', '追込率', '平均タイム', "距離", "頭数", "非根幹", "上り係数", "逃げ勝ち", "内勝ち", "外勝ち", "短縮勝ち", "延長勝ち", "人気勝ち", "1番人気", "3角先頭", "4角先頭", "上がり最速", "上がりタイム", "連闘", "休み明け", "大差負け", "展開脚質", "展開脚色" ]] mmsc_columns = ["頭数", "展開脚質", "展開脚色", "上がりタイム"] mmsc_dict_name = "sc_fa_race_mmsc" stdsc_columns = ["距離"] stdsc_dict_name = "sc_fa_race_stdsc" X = mu.scale_df_for_fa(X, mmsc_columns, mmsc_dict_name, stdsc_columns, stdsc_dict_name, dict_folder) X_fact = X.drop(["競走コード", "馬番"], axis=1).astype({ '非根幹': int, '逃げ勝ち': int, '内勝ち': int, '外勝ち': int, '短縮勝ち': int, '延長勝ち': int, '人気勝ち': int, '1番人気': int, '3角先頭': int, '4角先頭': int, '上がり最速': int, '休み明け': int, '連闘': int, '大差負け': int }) X_fact = X_fact.replace(np.inf, np.nan).fillna(X_fact.median()).fillna(0) X_fact.iloc[0] = X_fact.iloc[0] + 0.000001 dict_name = "fa_raceuma_result_df" filename = dict_folder + dict_name + '.pkl' if os.path.exists(filename): fa = mu.load_dict(dict_name, dict_folder) else: fa = FactorAnalyzer(n_factors=5, rotation='promax', impute='drop') fa.fit(X_fact) mu.save_dict(fa, dict_name, dict_folder) fa_np = fa.transform(X_fact) fa_df = pd.DataFrame(fa_np, columns=["fa_1", "fa_2", "fa_3", "fa_4", "fa_5"]) fa_df = pd.concat([X[["競走コード", "馬番"]], fa_df], axis=1) X_fact = pd.merge(input_raceuma_df, fa_df, on=["競走コード", "馬番"]) return X_fact
def choose_upper_n_count(self, df, column_name, n, dict_folder): """ 指定したカラム名の上位N出現以外をその他にまとめる :param df: :param column_name: :param n: :return: df """ dict_name = "choose_upper_" + str(n) + "_" + column_name file_name = dict_folder + dict_name + ".pkl" if os.path.exists(file_name): temp_df = mu.load_dict(dict_name, dict_folder) else: temp_df = df[column_name].value_counts().iloc[:n].index mu.save_dict(temp_df, dict_name, dict_folder) df.loc[:, column_name] = df[column_name].apply( lambda x: x if x in temp_df else 'その他') return df
def _target_encoding(self, sr, label, dict_name, fit, y): """ srに対してtarget encodingした結果を返す。fitがTrueの場合はエンコーディングする。ただし、すでに辞書がある場合はそれを使う。 :param series sr: エンコード対象のSeries :param str label: エンコードするラベル名 :param str dict_name: エンコード辞書名 :param bool fit: エンコード実施 or 実施済み辞書から変換 :param series y: 目的変数のSeries :return: """ # print("---- target encoding: " + label) tr = ce.TargetEncoder(cols=label) dict_file = self.dict_folder + '/' + dict_name + '.pkl' if fit and not os.path.exists(dict_file): tr = tr.fit(sr, y) mu.save_dict(tr, dict_name, self.dict_folder) else: tr = mu.load_dict(dict_name, self.dict_folder) sr_tr = tr.transform(sr) return sr_tr
def factory_analyze_raceuma_result_df(self, race_df, input_raceuma_df, dict_folder): """ RaceUmaの因子分析を行うためのデータを取得 """ print("-- check! this is BaseTransform class: " + sys._getframe().f_code.co_name) temp_df = pd.merge(input_raceuma_df, race_df, on="競走コード") X = temp_df[[ '競走コード', '馬番', 'タイム指数', '単勝オッズ', '先行率', 'ペース偏差値', '距離増減', '斤量比', '追込率', '平均タイム', "距離", "頭数", "非根幹", "上り係数", "逃げ勝ち", "内勝ち", "外勝ち", "短縮勝ち", "延長勝ち", "人気勝ち" ]] mmsc_columns = ["頭数"] mmsc_dict_name = "sc_fa_race_mmsc" stdsc_columns = ["距離"] stdsc_dict_name = "sc_fa_race_stdsc" X = mu.scale_df_for_fa(X, mmsc_columns, mmsc_dict_name, stdsc_columns, stdsc_dict_name, dict_folder) X_fact = X.drop(["競走コード", "馬番"], axis=1) X_fact = X_fact.replace(np.inf, np.nan).fillna(X_fact.median()).fillna(0) X_fact.iloc[0] = X_fact.iloc[0] + 0.000001 dict_name = "fa_raceuma_result_df" filename = dict_folder + dict_name + '.pkl' if os.path.exists(filename): fa = mu.load_dict(dict_name, dict_folder) else: fa = FactorAnalyzer(n_factors=3, rotation='promax', impute='drop') fa.fit(X_fact) mu.save_dict(fa, dict_name, dict_folder) fa_np = fa.transform(X_fact) fa_df = pd.DataFrame(fa_np, columns=["fa_1", "fa_2", "fa_3"]) fa_df = pd.concat([X[["競走コード", "馬番"]], fa_df], axis=1) X_fact = pd.merge(input_raceuma_df, fa_df, on=["競走コード", "馬番"]) return X_fact
def cluster_raceuma_result_df(self, raceuma_result_df, dict_path): """ 出走結果をクラスタリング。それぞれ以下の意味 # 激走: 4:前目の位置につけて能力以上の激走 # 好走:1:後方から上がり上位で能力通り好走 7:前目の位置につけて能力通り好走 # ふつう:0:なだれ込み能力通りの凡走 5:前目の位置につけて上りの足が上がり能力通りの凡走 6:後方から足を使うも能力通り凡走 # 凡走(下位):2:前目の位置から上りの足が上がって能力以下の凡走 # 大凡走 3:後方追走いいとこなしで能力以下の大凡走 # 障害、出走取消等→8 """ dict_folder = dict_path + 'dict/jra_common/' fa_dict_name = "cluster_raceuma_result" cluster = mu.load_dict(fa_dict_name, dict_folder) fa_list = [ "RACE_KEY", "UMABAN", "IDM", "RAP_TYPE", "着順", "確定単勝人気順位", "IDM結果", "コーナー順位2", "コーナー順位3", "コーナー順位4", "タイム", "距離", "芝ダ障害コード", "後3Fタイム", "テン指数結果順位", "上がり指数結果順位", "頭数", "前3F先頭差", "後3F先頭差", "異常区分" ] temp_df = raceuma_result_df.query( "異常区分 not in ('1','2') and 芝ダ障害コード != '3' and 頭数 != 0") df = temp_df[fa_list].copy() df.loc[:, "追走力"] = df.apply( lambda x: x["コーナー順位2"] - x["コーナー順位4"] if x["コーナー順位2"] != 0 else x["コーナー順位3"] - x["コーナー順位4"], axis=1) df.loc[:, "追上力"] = df.apply(lambda x: x["コーナー順位4"] - x["着順"], axis=1) df.loc[:, "1ハロン平均"] = df.apply(lambda x: x["タイム"] / x["距離"] * 200, axis=1) df.loc[:, "後傾指数"] = df.apply(lambda x: x["1ハロン平均"] * 3 / x["後3Fタイム"] if x["後3Fタイム"] != 0 else 1, axis=1) df.loc[:, "馬番"] = df["UMABAN"].astype(int) / df["頭数"] df.loc[:, "IDM差"] = df["IDM結果"] - df["IDM"] df.loc[:, "コーナー順位4"] = df["コーナー順位4"] / df["頭数"] df.loc[:, "CHAKU_RATE"] = df["着順"] / df["頭数"] df.loc[:, "確定単勝人気順位"] = df["確定単勝人気順位"] / df["頭数"] df.loc[:, "テン指数結果順位"] = df["テン指数結果順位"] / df["頭数"] df.loc[:, "上がり指数結果順位"] = df["上がり指数結果順位"] / df["頭数"] df.loc[:, "上り最速"] = df["上がり指数結果順位"].apply(lambda x: 1 if x == 1 else 0) df.loc[:, "逃げ"] = df["テン指数結果順位"].apply(lambda x: 1 if x == 1 else 0) df.loc[:, "勝ち"] = df["着順"].apply(lambda x: 1 if x == 1 else 0) df.loc[:, "連対"] = df["着順"].apply(lambda x: 1 if x in (1, 2) else 0) df.loc[:, "3着内"] = df["着順"].apply(lambda x: 1 if x in (1, 2, 3) else 0) df.loc[:, "掲示板前後"] = df["着順"].apply(lambda x: 1 if x in (4, 5, 6) else 0) df.loc[:, "着外"] = df["CHAKU_RATE"].apply(lambda x: 1 if x >= 0.4 else 0) df.loc[:, "凡走"] = df.apply( lambda x: 1 if x["CHAKU_RATE"] >= 0.6 and x["確定単勝人気順位"] <= 0.3 else 0, axis=1) df.loc[:, "激走"] = df.apply( lambda x: 1 if x["CHAKU_RATE"] <= 0.3 and x["確定単勝人気順位"] >= 0.7 else 0, axis=1) df.loc[:, "異常"] = df["異常区分"].apply(lambda x: 1 if x != '0' else 0) numerical_feats = df.dtypes[df.dtypes != "object"].index km_df = df[numerical_feats].drop([ "タイム", "後3Fタイム", "頭数", 'IDM結果', "IDM", "1ハロン平均", 'コーナー順位2', 'コーナー順位3', '距離' ], axis=1) # print(km_df.columns) # Index(['着順', '確定単勝人気順位', 'コーナー順位4', 'テン指数結果順位', '上がり指数結果順位', '前3F先頭差', # '後3F先頭差', '追走力', '追上力', '後傾指数', '馬番', 'IDM差', 'CHAKU_RATE', '上り最速', # '逃げ', '勝ち', '連対', '3着内', '掲示板前後', '着外', '凡走', '激走', '異常'], pred = cluster.predict(km_df) temp_df.loc[:, "ru_cluster"] = pred other_df = raceuma_result_df.query( "異常区分 in ('1','2') or 芝ダ障害コード == '3'") other_df.loc[:, "ru_cluster"] = 8 return_df = pd.concat([temp_df, other_df]) return return_df