0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【生成AIアプリ100チャレンジ】(22)競馬予想アプリ

Last updated at Posted at 2024-05-28

icon_jra_ai.png

開発環境

Server lightSail
Language Python3.11
Framework Django
DB sqlite3

ローカル環境ではPythonのvenvを使用。エディタはvs codeです。

目的

競馬予想アプリです。競馬サイトから出走馬データをスクレイピングして予想させてみようという試みです。最初、スクレイピングして予想という処理にしたのですが、サーバにchromeをインストールして、スクレイピングさせたら、どうやってもサーバタイムアウトになってしまうので断念。
 スクレイピングは別アプリにして、後ほど、スピーディーに必要なデータだけを取得できるようにリファクタリングすることにする。とりあえずデータを取得したCSVファイルをアウトプットする機能だけは実装できているので、そのデータを予想に使用しようと思います。
 まだまだ荒削りなので、プロンプトの改修、モデルの追加などを随時していきバージョンアップさせていきたいと思います。10個の予想を出してもらって100円ずつ1000円使って、いつの日か黒字になればいいなって考えています。まずは競馬からですが、株価予測などもしていきたいって思っています。

コード

qiita.rb

try:
    OPENAI_API_KEY = os.environ['OPENAI_API_KEY']
except KeyError:
    return HttpResponse("APIキーが設定されていません。", status=500)
chat_results = ""
if request.method == "POST":
    form = ChatForm(request.POST, request.FILES)
    if form.is_valid():
        # レース場の情報
        rase = form.cleaned_data['rase']
        if 'date' in form.cleaned_data and form.cleaned_data['date'] is not None:
            date = form.cleaned_data['date']
            date = date.strftime('%Y年%-m月%-d日')
        else:
            date = ''

        distance = form.cleaned_data['location']
        course = form.cleaned_data['course']
        orientation = form.cleaned_data['orientation']
        place = form.cleaned_data['place']
        weather = form.cleaned_data['weather']
        condition = form.cleaned_data['condition']
        betting = form.cleaned_data['betting']

        csv_file = request.FILES['csv_file']
        data_set = csv_file.read()
        result = chardet.detect(data_set)
        encoding = result['encoding']
        data_set = data_set.decode(encoding)
        io_string = io.StringIO(data_set)
        races_info = pd.read_csv(io_string)
        # フィルタリング条件を指定
        race_number = form.cleaned_data['race_number']
        location = form.cleaned_data['location']
        horses_info = races_info[
            (races_info['date'] == date) & 
            (races_info['round'] == race_number) & 
            (races_info['location'].str.contains(location))
        ]
        horse_names = races_info['horse'].tolist()
        # フィルタリング結果をコンソールに出力
        try:
            client = OpenAI(
                api_key = OPENAI_API_KEY,
            )
            result = client.chat.completions.create(
                model="gpt-4o",
                messages=[
                    {
                        "role": "system",
                        "role": "system",
                        "content": f"""
                        あなたは競馬予想の専門家です。ユーザーが提供する詳細なレース情報および出走馬のデータを基に、最適な予想を提供してください。
                        {date}に開催される{rase}の結果を予想してください。
                        過去の{rase}の情報は下記サイトで調べてください。
                        https://dir.netkeiba.com/
                        競馬場は{place}になります。距離は{distance}、コースの種類は{course}です。コースの回りは{orientation}です。
                        天候は{weather}で、馬場の状態は{condition}になります。
                        馬券の種類は{betting}です。馬券の種類あわせた{betting}の予想のみ出力してください。
                        出走馬の情報を下記に記載します。
                        {races_info}
                        なお、下記のリストの情報は合わせて検索してください。
                        検索用馬名リスト: {horse_names}
                        検索用サイト:https://dir.netkeiba.com/
                        馬券の種類は{betting}です。馬券の種類あわせた{betting}の予想の組み合わせを10パターンを出力してください。
                        当選確率が高いと思われる順に並べてください。
                        その場合、馬名と馬番で表示してください。解説も予想の後にしてください。
                        例
                        馬券の種類
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        馬番-馬番-馬番
                        ーーーーーーーーーーーーーー
                        解説
                        """
                    }
                ],
            )
            result = result.choices[0].message.content
            chat_results = result.replace("\n", "<br>")

        except Exception as e:
            return HttpResponse(f"API呼び出し中にエラーが発生しました: {str(e)}", status=500)
    else:
        return HttpResponse("フォームのデータが無効です。", status=400)
else:
    form = ChatForm()

各フレームワークの課題に合わせて出力されます。

アプリ画面

スクリーンショット 2024-05-28 20.04.09.png

感想

早速、日本ダービーで予想をしてもらいましたが、9番人気のダノンデサイルを当てることは難しかった。徐々にデータを増やしていって的中率を上げていきたい。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?