独学でプログラミングを学んでみた

python初心者がテックブログを書いてみた

今読んでいる技術書について(主にpython関連)

皆さんこんにちは、KHnodeです。

さて、いま読んでいる技術書について紹介したいなと思います。
(4/17現在)

######################################################

独学プログラマー

python実践データ分析100本ノック

すっきりわかるpythonによる機械学習入門

スッキリわかるPythonによる機械学習入門 (スッキリシリーズ)

スッキリわかるPythonによる機械学習入門 (スッキリシリーズ)

  • 作者:須藤秋良
  • 発売日: 2020/10/16
  • メディア: 単行本(ソフトカバー)

kaggleで勝つデータ分析の技術

Kaggleで勝つデータ分析の技術

Kaggleで勝つデータ分析の技術

pythonによる自動処理の教科書

######################################################

今後の読んでみたい本

  • Flask, Jango関係の本

python初学者が競馬予測をしてみたpart4(予想方法について)

こんにちは、KHnodeです。

更新が遅くなって申し訳ありません。
最近、新生活やウマ娘にはまっていて、あんまり勉強できてはいませんが切り替えて頑張っていこうと思います。

前回の続きはこちらから
kashiwapro.hatenablog.com

また、実際に予想してるブログはこちらにありますのでよろしければ見ていただけると幸いです。
keibatech.hatenablog.jp

##################################################################

今回は先に競馬予測方法を紹介して、次週にこれまで実施したデータ加工やモデル精査について書いていこうと思います。

    y_pred = model.predict(pred_df)
    pred_df['確率'] = y_pred
    excel_writer = pd.ExcelWriter('output.xlsx')

    return pred_df.to_excel(excel_writer, 'hogefuga sheet')

"pred_df"は予測したいデータを入れる感じです。
後は確率という新たなカラムを作成して、そこに予測値を入れていきます。

このままto_excelにしてもいいのですが、何故かエラーが頻発したので今回は直接ファイル名を入れず"pd.ExcelWriter('output.xlsx')"にすることでエラーを回避しています。
シート名は適当に入れます。

実際にできたのはこんな感じ

芝ダ 距離 馬場状態 騎手 父馬名 母父馬名 馬番 年齢 性別 人気 オッズ比 確率
1 3 2 206 435 148 1 3 0 6 4 0.130027695

カテゴリー変数にしているため少し見にくいですが、馬番と確率が分かれば大丈夫と思います。(カテゴリー変数を元に戻すなどをして対応した方が見やすいかも)

大体10%前後であれば3着以内に来ると予想しています。

以上予想方法についてですが、まだまだ課題が多くあります。

1つ目は、3着以内に来る確率がまだまだ低いのでせめて20%まで上げればいいなと考えています。

2つ目は、散々ブログ内でも出ていますが前処理が甘い点があります。
これに関しては、色々と本を読んで勉強中なので出来次第紹介していきたいと思います。

更新が遅くなって申し訳ありません。
なるべく頑張って更新できるように頑張ります(努力目標)

今後の予定について

こんにちは、KHnodeです。
現在は競馬予測の機械学習pythonで行っていますが、今後の予定についてお話します。(2021/3/9現在の予定)

火曜日はFLASK関連のことについて書き、金曜日はデータ分析関連のことを書いていこうと思います。

火曜日(FLASK関連)

ガチの初学者なので最初の方は少し不定期更新になってしまうとは思いますが、なるべく早く勉強して投稿できるようにします。
進め方としては、初めに作りたいもののを決めてから作成していく感じです。

金曜日(データ分析)

今のところは3つを考えていて、先にできたものから投稿をしていく感じなので場合によってはそのジャンルが全然投稿されないケースがあると思うのですがその点はご了承ください。

〇競馬の予測を続ける。

〇esports × データ分析
今のところはLoLとapexで考えている。
apiをたたいてみたりしたい。

〇kaggle, signate挑戦してみる。
友人から教えてもらったので腕試し感覚で試してみたい。

こんな感じです。

失踪しないようにゆるーく進めていきますのでよろしくお願いいたします。

ではまた

python初学者が競馬予測をしてみたpart3(part1,2の変更点)

皆さんこんにちは、KHnodeと申します。
第三回です。
前回の記事はこちらから、まだ見ていない人は見ていただけると嬉しいです。
kashiwapro.hatenablog.com

##################################################################

前回まで1競馬予測のコードを書いてきましたが、今回はこの2週間で変更したことを書いていこうと思います。

①目的変数の変更
前の目的変数は確定順位の1,2,3着を0-1変数に直したものを目的変数としていましたが
「オッズが5倍かつ確定順位の1,2,3着を0-1変数に直したもの」に変更しました。
(オッズの倍率は変更有)

変更理由に関しては2つあります。
複勝で賭けるため少しうまみのあるオッズを買いたいから
〇説明にオッズと人気を合わせた特徴量の作成を行いたいから

1つ目の理由は、的中率よりも回収率が重要と筆者は考えているので単勝オッズ1.何倍の複勝を買ってもほぼ元返しになってしまうため、1度負けてしまうと回収不可能になってしまうからです。
2つ目の理由は、説明変数が少なくスコアが68%とかなり低いのでスコア向上のためです。

目的変数のコードはこちらです。(無駄なコードが多い気がします)

  import pandas as pd

    df = pd.read_excel(data)

    d_ranking = lambda x: 1 if x in [1, 2, 3] else 0
    df['確定フラグ'] = df['確定順位'].map(d_ranking)

    oos = lambda x: 1 if x > 5.0 else 0
    df['オッズフラグ'] = df['オッズ'].map(oos)

    df.loc[(df['確定フラグ'] == 1) & (df['オッズフラグ'] == 1), 'メインフラグ'] = "1"
    df.loc[(df['確定フラグ'] == 0) | (df['オッズフラグ'] == 0), 'メインフラグ'] = "0"

    df = df.drop(['確定フラグ', 'オッズフラグ'], axis=1)

②説明変数の変更

〇過去の戦績をのせる。(レース場、オッズ、人気、着順など)
〇特徴量の作成をする。

過去の戦績に関しては思った以上に難航しているので次週にのせれたらと思います(がんばります)
特徴量は今のところはオッズと人気で作成しようと考えています。

ではまた

python初学者が競馬予測をしてみたpart2(モデルの作成編)

皆さんこんにちは、KHnodeです。
今回も「python初学者が競馬予測をしてみた」です。

前回の記事はこちら
kashiwapro.hatenablog.com
まだ見ていない方は見ていただけると幸いです。

それでは早速やっていこうと思います。

##################################################################

モデル作成

訓練用のデータとテスト用のデータを分割します。
これは、機械学習お馴染みの手法なので覚えておくといいと思います。

from sklearn.model_selection import train_test_split

X = df.drop(['フラグ', '日付'], axis=1)
y = df['フラグ']

X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                    test_size=0.31,
                                                    random_state=0)

次にモデルの作成なのですが、今回はLightGBMのoptunaを利用して自動設定にしてみました。

from optuna.integration import lightgbm as lgb

lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test)

params = {
        'objective': 'binary',
        'metric': 'auc'
     }

best_opt = lgb.train(
        params, lgb_train, valid_sets=[lgb_train, lgb_eval],
        verbose_eval=False,
        num_boost_round=10,
        early_stopping_rounds=10,
    )

レーニングしたデータのパラメータと重要度を出力します。

    y_pred = best_opt.predict(X_test)
    df.drop(columns=['フラグ', '日付'], inplace=True)

    importance = pd.DataFrame(best_opt.feature_importance(),
                  index=df.columns, columns=['importance'])
    importance = importance.sort_values(by="importance", ascending=False)

    return best_opt.params, importance

モデル組み込み

次に、予想モデルに組み込みなのですが、先ほど出力したbest_opt.paramsをbest_paramsに入れます。
もちろん下のように

best_params = best_opt.params

こんな感じにして入れるのも一つの方法ですが、これをすると乱数の影響?によって重要度がコロコロ変わってしまい正確な予想ができないのでしていません。

import lightgbm as lgb

    best_params = {
        'objective': 'binary', 'metric': 'auc', 'feature_pre_filter': False, 'lambda_l1': 0.0009216345468743798,
        'lambda_l2': 5.971595511972418e-08, 'num_leaves': 80, 'feature_fraction': 0.5, 'bagging_fraction': 1.0,
        'bagging_freq': 0, 'min_child_samples': 20
    }
    model = lgb.train(
        best_params,
        lgb_train,
        valid_sets=lgb_eval,
        num_boost_round=100,
        early_stopping_rounds=10
    )

とりあえずモデルの組み込みができたので、スコアを見ていくと、
大体68%なのですが、無茶苦茶低いです。

理由なのですが、オッズや人気といった素人が見ても重要だとわかる変数を入れていないという事が挙げられます。
入れてもいいとは思いますが、入れてしまうとかなりオッズや人気によってしまい1番人気にしか予想しなくなるからです。

とは言っても68%はかなり低いので対策を考えていく必要があると思います。

次は、実際にどういう感じで予想していくのかについて書いていこうと思います。