技術資料:強化学習を用いたパーソナライズ献立推薦システム 

目次 

1. 目的 

食に対する個人の嗜好は、「珍しいものが食べたい」「調理が簡単なものが良い」など、非常に多様かつ動的である。従来の推薦システムは、栄養バランスやコストといった静的な指標に基づいて献立を提案するものが主であった。本研究では、ユーザーからのフィードバック(満足度評価)を元に、強化学習(多腕バンディットアルゴリズム)を用いて「ユーザーがどのようなタイプの献立を好むか」という提案戦略を学習し、その戦略に基づいて多目的最適化(遺伝的アルゴリズム)が献立を生成する、パーソナライズされた動的な献立推薦システムのコアエンジンを構築・検証することを目的とする。

2. システム概要 

本システムは、強化学習エージェント(バンディット)と多目的最適化エンジン(遺伝的アルゴリズム)を連携させた、クローズドループのシミュレーション環境である。全体の処理フローは以下の通り。 1. 戦略決定: `bandit_logic.py` が過去の学習記録 `mab_feedback.csv` を参照し、今回最適化すべきUX戦略(腕)を決定する。 2. 献立生成: `2献立作成(GraphicalRecipes).py` が、決定された戦略に基づき多目的最適化を実行し、献立候補群(パレート解)を生成する。 3. 評価: `run_experiment.py` が生成された献立の一つをランダムに選択し、`virtual_user.py` に渡して評価させる。 4. フィードバック: `virtual_user.py` は自身の隠れた好みに基づいて満足度(報酬)を計算し、返す。 5. 学習記録: `run_experiment.py` は、(1)で選択された戦略と、(4)で得られた報酬のペアを `mab_feedback.csv` に追記する。 6. 上記1~5を規定回数繰り返し、学習を行う。

3. 実際の人間が利用する場合の想定フロー 

現在のシステムは、`virtual_user.py` を用いた自動シミュレーション環境だが、これを実際のサービスとして人間が利用する場合、以下のようなフローが想定される。 1. ユーザーのログイン: ユーザーがシステムにログインする。ユーザーごとに過去の評価履歴が管理される。 2. 戦略決定: `bandit_logic.py` が、そのユーザーの過去の評価履歴(`mab_feedback.csv`に相当)を読み込み、「今日のあなたへのおすすめ方針」として最適な腕(例:腕3「調理しやすさ重視」)を選択する。 3. 献立生成: `2献立作成(GraphicalRecipes).py` が、選択された戦略に基づいて、複数の優れた献立候補(パレート解)を生成する。 4. 献立の提示: `server1(GraphicalRecipes).py`が起動したWebアプリケーションが、生成された複数の献立候補をユーザーに提示する。ユーザーは気分や状況に合わせて、その中から一つを選ぶ。 5. 調理と食事: ユーザーは選んだ献立を実際に調理し、食事をする。 6. 満足度の評価: 後日、ユーザーはWebアプリケーション上で、前回の献立に対する総合的な満足度を1~5の星などで評価する。 7. フィードバックの記録: `server1(GraphicalRecipes).py`は、そのユーザーの評価(報酬)を、「どの戦略で提案したか」という情報と紐づけて、そのユーザーの学習データとして記録する。

4. 使用するファイル全部 

扱うデータ用途ファイル名ファイルの場所
システム制御シミュレーション全体の制御、各モジュールの呼び出し、結果の記録run_experiment.py(ルート)
システム制御多目的最適化による献立生成、GUIによる手動設定2献立作成(GraphicalRecipes).py(ルート)
Webサーバー生成された献立をブラウザで表示するためのWebサーバー機能server1(GraphicalRecipes).py(ルート)
システム制御UCB1バンディットアルゴリズムによる戦略決定bandit_logic.py(ルート)
システム制御仮想ユーザーによる献立評価と報酬計算virtual_user.py(ルート)
入力データ各レシピの栄養素・コスト・UXスコアの格納recipe_noX.csv(./data/hyouka/)
設定データ手動実行時のユーザー情報やアレルギー設定を保存menu_creation_settings.json(ルート)
出力データ(学習ログ)強化学習の試行ごとの結果(腕、報酬)を記録mab_feedback.csv(ルート)
出力データ(献立)生成された献立候補群の詳細情報をJSON形式で保存all_details.json(./static/)
出力データ(グラフ)遺伝的アルゴリズムのパレート解の分布を可視化palate.png(ルート)


5. システムの実行方法 

5.1. 事前準備 

1.必要なライブラリをインストールする.

2.(任意・初回のみ)ユーザー設定ファイルを作成する.

5.2. 目的別の実行フロー 

本システムには、大きく分けて2つの実行モードがある。

【A】シミュレーション実験を実行する場合(開発者・研究者向け)

【B】献立推薦システムを実際に利用する場合(一般ユーザー向け)

6. 主要プログラムの全コードと詳細解説 

6.1. `run_experiment.py` 

6.2. `2献立作成(GraphicalRecipes).py` 

6.3. `server1(GraphicalRecipes).py` 

@app.route('/')
def index():
    # ... (省略) ...

@app.route('/details')
def details():
    # ... (省略) ...

@app.route('/save_survey', methods=['POST'])
def save_survey():
    try:
        form_data = request.form
        
        # 1. フォームから総合満足度(報酬)を取得
        reward = form_data.get('overall_satisfaction')

        # 2. どの戦略(腕)が使われたかをファイルから取得
        try:
            with open('last_chosen_arm.txt', 'r', encoding='utf-8') as f:
                chosen_arm = f.read().strip()
        except FileNotFoundError:
            chosen_arm = -1

        # 3. 報酬と腕の情報を mab_feedback.csv に追記
        if reward and chosen_arm != -1:
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            # ... (mab_feedback.csvへの追記処理) ...
            print(f"MABフィードバックを保存しました: arm={chosen_arm}, reward={reward}")
        
        # 4. レシピごとの詳細なアンケート結果を別途保存
        # ... (フォームからq1, q2..の回答を解析し、整形して別ファイルに保存する処理) ...

        return "<h3>アンケートへのご協力、ありがとうございました!</h3>"
    
    except Exception as e:
        return f"サーバー内部でエラーが発生しました: {e}", 500

if __name__ == '__main__':
    app.run(debug=True, port=5000)

6.4. `bandit_logic.py` 

6.5. `virtual_user.py` 

11. 実験結果 

200回のシミュレーションを実行した結果、各腕の選択回数は以下のようになった。

#ref(): File not found: "final_arm_selection_chart.png" at page "辻さん卒論"

(ここに、最終的な腕の選択回数の集計結果のグラフ画像を挿入)

#ref(): File not found: "final_arm_selection_table.png" at page "辻さん卒論"

(ここに、最終的な腕の選択回数の集計結果の表画像を挿入)

この結果から、本システムは仮想ユーザーの最も重要な好みである「調理しやすさ(腕3)」を最適戦略として正しく学習し、最も多く選択(42.0%)したことが確認できる。同時に、他の戦略も継続的に探索しており、活用と探索のバランスが機能していることが示された。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS