今回の内容
今回は、前回CSV形式で作ったデータの前処理と、新たな特徴量を作っていきます。
前回の記事はこちらから。
前処理と特徴量作成
さて、さっそく前処理と特徴量の作成をしていきます。
先に私がどのように完成したAIを運用しているのかというと、
- 過去8ヶ月分のデータを取得してモデルを作る。
- 月が変わったタイミングで先月のデータを追加、最も古いデータを除いた8ヶ月分のデータで再度学習。
というような形で運用しています。
なので、1ヶ月ごとに以下のファイルを実行しデータをアップデートしています。
選手の個人データを作っていきます。
def make_csv_personal():
import pandas as pd
import os
import numpy as np
csv_rsult_dir = '/Users/tom/boat_pred/data_csv/data_result_csv'
csv_result_file = os.listdir(csv_rsult_dir)
csv_result_file.sort()
csv_result_file.remove('.ipynb_checkpoints')
df_r = []
for i in csv_result_file[-8:]:
d = pd.read_csv(f'/Users/tom/boat_pred/data_csv/data_result_csv/{i}')
df_r.append(d)
df_results = pd.concat(df_r)
df_results = df_results.reset_index(drop=True)
num = df_results['選手登番'].unique()
num.sort()
id = df_results['id'].unique()
## STランク付
re_df = []
for i in id:
o_df = df_results[df_results['id']==i]
o_df = o_df.sort_values('ST')
o_df['STR'] = np.arange(1,7)
o_df.sort_values('艇番', inplace=True)
re_df.append(o_df)
#再生
df_results = pd.concat(re_df)
## 平均ST
lis = []
lis1 = []
lis2 = []
lis3 = []
lis4 = []
lis5 = []
lis6 = []
avest_all = []
avest1 = []
avest2 = []
avest3 = []
avest4 = []
avest5 = []
avest6 = []
for i in num:
st=df_results[df_results['選手登番']==i]['ST'].values
st1 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)]['ST'].values
st2 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)]['ST'].values
st3 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)]['ST'].values
st4 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)]['ST'].values
st5 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)]['ST'].values
st6 = df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)]['ST'].values
lis.append(np.nanmean(st))
lis1.append(np.nanmean(st1))
lis2.append(np.nanmean(st2))
lis3.append(np.nanmean(st3))
lis4.append(np.nanmean(st4))
lis5.append(np.nanmean(st5))
lis6.append(np.nanmean(st6))
# 艇番STR
win = df_results[df_results['選手登番']==i]['STR'].values
avest_all.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)]['STR'].values
avest1.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)]['STR'].values
avest2.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)]['STR'].values
avest3.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)]['STR'].values
avest4.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)]['STR'].values
avest5.append(np.nanmean(win))
#1枠
win = df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)]['STR'].values
avest6.append(np.nanmean(win))
## 連対率
df_results['1着'] = df_results['着順'].apply(lambda x : 0 if x == 1 else 1)
df_results['2連対'] = df_results['着順'].apply(lambda x : 0 if x <= 2 else 1)
df_results['3連対'] = df_results['着順'].apply(lambda x : 0 if x <= 3 else 1)
waku1rentai1 = []
waku1rentai2 = []
waku1rentai3 = []
waku2rentai1 = []
waku2rentai2 = []
waku2rentai3 = []
waku3rentai1 = []
waku3rentai2 = []
waku3rentai3 = []
waku4rentai1 = []
waku4rentai2 = []
waku4rentai3 = []
waku5rentai1 = []
waku5rentai2 = []
waku5rentai3 = []
waku6rentai1 = []
waku6rentai2 = []
waku6rentai3 = []
for i in num:
#1枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)])
winpercent11 = win/total
waku1rentai1.append(winpercent11)
except ZeroDivisionError:
waku1rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)])
winpercent12 = win/total
waku1rentai2.append(winpercent12)
except ZeroDivisionError:
waku1rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==1)])
winpercent13 = win/total
waku1rentai3.append(winpercent13)
except ZeroDivisionError:
waku1rentai3.append(0)
#2枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)])
winpercent21 = win/total
waku2rentai1.append(winpercent21)
except ZeroDivisionError:
waku2rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)])
winpercent22 = win/total
waku2rentai2.append(winpercent22)
except ZeroDivisionError:
waku2rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==2)])
winpercent23 = win/total
waku2rentai3.append(winpercent23)
except ZeroDivisionError:
waku2rentai3.append(0)
#3枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)])
winpercent31 = win/total
waku3rentai1.append(winpercent31)
except ZeroDivisionError:
waku3rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)])
winpercent32 = win/total
waku3rentai2.append(winpercent32)
except ZeroDivisionError:
waku3rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==3)])
winpercent33 = win/total
waku3rentai3.append(winpercent33)
except ZeroDivisionError:
waku3rentai3.append(0)
#4枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)])
winpercent41 = win/total
waku4rentai1.append(winpercent41)
except ZeroDivisionError:
waku4rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)])
winpercent42 = win/total
waku4rentai2.append(winpercent42)
except ZeroDivisionError:
waku4rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==4)])
winpercent43 = win/total
waku4rentai3.append(winpercent43)
except ZeroDivisionError:
waku4rentai3.append(0)
#5枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)])
winpercent51 = win/total
waku5rentai1.append(winpercent51)
except ZeroDivisionError:
waku5rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)])
winpercent52 = win/total
waku5rentai2.append(winpercent52)
except ZeroDivisionError:
waku5rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==5)])
winpercent53 = win/total
waku5rentai3.append(winpercent53)
except ZeroDivisionError:
waku5rentai3.append(0)
#6枠
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)&(df_results['1着']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)])
winpercent61 = win/total
waku6rentai1.append(winpercent61)
except ZeroDivisionError:
waku6rentai1.append(0)
## 2連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)&(df_results['2連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)])
winpercent62 = win/total
waku6rentai2.append(winpercent62)
except ZeroDivisionError:
waku6rentai2.append(0)
## 3連対
try:
win = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)&(df_results['3連対']==0)])
total = len(df_results[(df_results['選手登番']==i)&(df_results['艇番']==6)])
winpercent63 = win/total
waku6rentai3.append(winpercent63)
except ZeroDivisionError:
waku6rentai3.append(0)
st_data = pd.DataFrame({'選手登番':num,
'1枠1着率':waku1rentai1,
'1枠2連対率':waku1rentai2,
'1枠3連対率':waku1rentai3,
'2枠1着率':waku2rentai1,
'2枠2連対率':waku2rentai2,
'2枠3連対率':waku2rentai3,
'3枠1着率':waku3rentai1,
'3枠2連対率':waku3rentai2,
'3枠3連対率':waku3rentai3,
'4枠1着率':waku4rentai1,
'4枠2連対率':waku4rentai2,
'4枠3連対率':waku4rentai3,
'5枠1着率':waku5rentai1,
'5枠2連対率':waku5rentai2,
'5枠3連対率':waku5rentai3,
'6枠1着率':waku6rentai1,
'6枠2連対率':waku6rentai2,
'6枠3連対率':waku6rentai3,
'平均ST順位':avest_all,
'1枠ST順位':avest1,
'2枠ST順位':avest2,
'3枠ST順位':avest3,
'4枠ST順位':avest4,
'5枠ST順位':avest5,
'6枠ST順位':avest6,
'平均ST':lis,
'1枠ST':lis1,
'2枠ST':lis2,
'3枠ST':lis3,
'4枠ST':lis4,
'5枠ST':lis5,
'6枠ST':lis6})
st_data.to_csv('/Users/tom/boat_pred/data_csv/personal_data.csv',index=False)
make_csv_personal()
うーむ。。長い。単調。わかりづらい。
悪いコードのお手本のようだ!
簡単に説明すると’csv_rsult_dir’に1ヶ月分のデータが8つ、8ヶ月分。それをdf_resultsとしてデータフレーム化。”#STランク付”でスタート順位をつける。あとは”#艇番STR”で艇番毎にもスタート順位をつけました。”#連対率”のところで枠別の連対率を計算しto_csvで保存します。
これで選手の平均スタート、枠番別の連対率、スタート順位等、元データをより詳しいデータにすることができました。
それにしてももっとスマートにできないだろうか。さすがにごちゃごちゃしすぎてます。連対率のところでtry~exceptを多用しているのは新人選手の内枠データがなかったり、阿波勝哉選手などは1枠データがないためです。
今回のまとめ
ここまでやって気づいたことはやはり機械学習はデータの収集、前処理の方が大変ということ。例外が次々出てくるしデータの欠損値の処置など、『できたーっ!!!』と達成感に満ち溢れた後に、それまでのプロセスの2倍以上時間をかけて修正していきました。
実のところ、収集したデータは全てをレース結果を集めきれたわけではありません。例えば『今日は3レースで打ち切り』となった開催日のレース場データは、実際に実施された3レース分は取得できていません。理由として、ダウンロード元の出走表データは12レース分あるのに対して、レース結果データが3レース分しかなく、エラーが発生した為です。ここからやり直すのかと心折れて妥協、『そういうのは無視無視』と切り捨てることにしました。
それでも必要な量は満たしていると思うので、今回はこれで次に進みたいと思います。