生成AIと最適化技術を組み合わせたコンポジットAIで献立最適化アプリを作ってみた
こんにちは。NRIデジタルの松永です。
近年、生成AIの開発・利用が急速に進んでいますが、生成AIを単独で活用するだけでなく、他のAI・アルゴリズムと組み合わせることで多様なタスクをこなせるようにする取り組みも行われています。
このような手法はコンポジットAI(Composite AI)と呼ばれており、今後進展することが予想されています。今回は、生成AIと数理最適化を組み合わせて、ユーザの要望に応じてコンビニなどの商品の組合せを求める「献立最適化アプリ」を作ってみましたのでご紹介します。
コンポジットAI
コンポジットAIとは、複数のAI・アルゴリズムを組み合わせた手法、アプリケーションを指します。異なるAIを組み合わせることで、単一のAIでは出来ないタスクを遂行できるようになります。技術の成熟度を表すハイプ・サイクル(AI技術、2023年版)では、コンポジットAIはInnovation Trigger(黎明期)に該当しており、発展途上の段階です。ちなみに、生成AIはPeak of Inflated Expectations(過度な期待のピーク)に該当します。
コンポジットAIの応用例として、ニューラルネットワークにより部品の欠陥を画像で判定し、ルールベースAIにより欠陥の根本原因を突き止めるといったものがあります。ニューラルネットワークによる高精度な欠陥検出と、ルールベースAIによる説明性の担保という双方のメリットを享受することができます。
献立最適化アプリ
ここからは、コンポジットAIを用いて作成したアプリについて説明します。組み合わせる手法は、前で述べた通り生成AIと数理最適化です。数理最適化とは、現実の問題を最適化問題と呼ばれる数式にモデル化し、解を求めることで意思決定を行う技術を表します。数学的に根拠のある解を求めることができる一方、定量的なデータ以外は処理できません。
そこで、人間の曖昧な要望を解釈できる生成AIを組み合わせることで両者の強みを掛け合わせられないか、と考え、組み合わせることとしました。そして、この仮説を検証するために献立最適化アプリを作りました。
ここからは、今回作成した献立最適化アプリについて説明します。このアプリは、コンビニやスーパーで日々の食事を買う人向けに、栄養バランスを考慮しつつユーザの要望に応える献立(食品の組合せ)を提示します。
ユーザが「糖質を抑えてください」「辛い物を食べたい」のような要望・好みを入力すると、その入力を生成AIが解釈して最適化パラメータに変換します。パラメータを用いて最適化モデルを構築、解くことでユーザの要望を満たす解(食品の組合せ)を求めます。解は単なる数値データなので、生成AIを用いて献立を選んだ理由を説明する文章を生成し、ユーザに提示します。この流れをまとめると下図のようになります。

献立を作ってみる
実際に献立を作ってみます。商品データは久留米市オープンデータカタログサイト1)https://data.bodik.jp/dataset/402036_0009100_00005の料理データをもとに作成しました。価格と一部の栄養素データはGPT-4を用いて生成しています。まずは筋トレをしている人向けの献立です。要望を以下のように入力します。
筋トレをしているので、たんぱく質が豊富な献立を2品程度考えてください。
特に揚げ物とスイーツは控えてください。予算は800円です。
出力した献立です。
本日の献立は以下の通りです。
- つくね 1個 : 価格250円, 熱量188kcal
- 広島風お好み焼き(1枚) 1個 : 価格500円, 熱量622kcal
商品の購入には750円かかり、1食あたりのカロリーは810kcalです。
以下に、各商品を選択した根拠を説明します。
- **つくね 1個**
– **選択理由**: つくねはたんぱく質が11.3g含まれており、筋トレをしている方にとって重要なたんぱく質を摂取するのに適しています。また、揚げ物ではないため、要望に合致しています。– **価格**: 250円(税込み)
– **熱量**: 188kcal
– **たんぱく質**: 11.3g
– **脂質**: 8.9g
– **炭水化物**: 10.0g
– **食塩相当量**: 0.7g
- **広島風お好み焼き(1枚) 1個**
– **選択理由**: 広島風お好み焼きはたんぱく質が24.2g含まれており、筋トレをしている方にとって重要なたんぱく質を摂取するのに適しています。また、揚げ物ではなく、スイーツでもないため、要望に合致しています。– **価格**: 500円(税込み)
– **熱量**: 622kcal
– **たんぱく質**: 24.2g
– **脂質**: 24.1g
– **炭水化物**: 72.3g
– **食塩相当量**: 1.0g
この献立は、たんぱく質の合計が35.5gと高く、筋トレをしている方に適した内容となっています。また、揚げ物やスイーツを避けるという要望にも応えています。予算も800円以内に収まっており、750円(税込み)で提供可能です。
本日の献立のサマリー
評価結果と栄養バランスの特徴を以下にまとめます。
- 献立はたんぱく質が35.5gと豊富で、筋トレをしている人に適していますが、脂質が33.0gと高めです。
- 揚げ物とスイーツは含まれておらず、要望に応えています。
- 予算は800円以内に収まっており、価格面でも要望を満たしています。
この献立はたんぱく質が豊富で、筋トレをしている人に適していますが、脂質が高めである点に注意が必要です。
つくね、お好み焼きというたんぱく質が豊富な食材を使った献立が出てきており、ユーザの要望に応えられていることが分かります。また、単に献立を出力するだけではなく、なぜ選んだか、栄養素、予算などの条件にも応えているかについてフィードバックをします。フィードバックにより、ユーザは新たな気付きが得られ、それをもとに次の献立要望をカスタマイズできるので、対話的に献立を作っていくことができます。
次に、お年寄り向けの献立を作ります。要望を以下のように入力します。
お年寄り向けの商品を3品選んでほしいです。
塩分控えめで柔らかい食べ物をお願いします。和菓子を1つ入れてください。
出力した献立です。
本日の献立は以下の通りです。
- 肉じゃが 1個 : 価格400円, 熱量309kcal
- 炊き合わせ 1個 : 価格300円, 熱量92kcal
- 練ようかん(1切) 1個 : 価格150円, 熱量148kcal
商品の購入には850円かかり、1食あたりのカロリーは549kcalです。
<献立>に対する各商品の選択根拠を以下に示します。
- **肉じゃが 1個**
– **選択根拠**: 肉じゃがは柔らかく煮込まれており、お年寄りでも食べやすいです。また、塩分相当量が1.4gと比較的控えめです。- **炊き合わせ 1個**
– **選択根拠**: 炊き合わせは様々な野菜が柔らかく煮込まれており、咀嚼が難しいお年寄りにも適しています。塩分相当量も0.9gと低めです。- **練ようかん(1切) 1個**
– **選択根拠**: 和菓子の要望に応えるために選びました。練ようかんは柔らかく、塩分相当量が0.0gで塩分を気にする必要がありません。以上の選択により、要望に対して柔らかく塩分控えめな商品を提供しつつ、和菓子も含めた献立を構成しました。
本日の献立のサマリー
この献立が要望に応えているかどうかを評価し、栄養バランスの特徴を以下にまとめます。
- **塩分控えめ**: 全体の食塩相当量は2.3gであり、1食あたりの塩分量としては控えめと言えます。特にお年寄り向けとしては適切です。
- **柔らかい食べ物**: 肉じゃがと炊き合わせは柔らかい食材が使われており、練ようかんも柔らかい和菓子です。これらはお年寄りにとって食べやすい選択です。
- **和菓子の追加**: 練ようかんが和菓子として含まれており、要望に応えています。
栄養バランスの特徴:– **たんぱく質**: 16gと適度な量であり、筋肉維持に役立ちます。– **脂質**: 13gと控えめで、脂質の摂取を抑えたいお年寄りに適しています。– **炭水化物**: 87gと十分なエネルギー源を提供しますが、糖質が多めなので糖尿病の方は注意が必要です。全体として、要望に応えた献立であり、栄養バランスもお年寄りに適しています。
柔らかい商品がちゃんと出力されていることが分かります。
一度献立を作ったあとで、「やっぱり変更したい」ということは往々にしてあります。肉じゃがが苦手なので献立変更の要望を入力します。
肉じゃがが苦手なのでメニューから外してください。
すると、献立は以下のようになりました。
本日の献立は以下の通りです。
- クリームシチュー 1個 : 価格450円, 熱量302kcal
- 炊き合わせ 1個 : 価格300円, 熱量92kcal
- 練ようかん(1切) 1個 : 価格150円, 熱量148kcal
商品の購入には900円かかり、1食あたりのカロリーは542kcalです。
(献立の根拠と評価は略)
要望通り、肉じゃがが献立から除かれ、代わりにクリームシチューが入りました。このように、献立の修正を行うこともできます。
どのように生成AIと数理最適化を組み合わせているか?
ここからは、どのように生成AIと数理最適化を組み合わせて献立を求めているか、について説明します。まず、献立を求める部分ですが、以下のような最適化問題を解いています。
- 目的関数:標準的な栄養摂取量からの差分の最小化
- 変数:各商品を献立に採用するか否か
- 制約条件:合計価格の上下限、栄養素摂取量の上下限、必ず選ぶ/選ばない商品、…
この問題を混合整数計画問題として定式化し、最適化ソルバを用いて解くことで、制約条件を満たす最も良い解を求めることができるのですが、この技術を使うためには、最適化問題を構成するすべての要素を定量化する必要があります。
ところが、献立のようなケースでは、ユーザの好みを定量化することが中々難しいです。例えば、「たんぱく質を多くとりたい」という場合に、何グラム取ればよいのかは栄養に詳しい人でないとパッとは分からないでしょう。ユーザに全てのパラメータを入力させるようにすれば、定量化自体はできますが、いちいち多数のパラメータを入力するシステムは使いにくいです。
そこで、生成AIを利用することで、最適化に必要なパラメータを生成します。パラメータには、「脂質摂取量の上限」のような数値パラメータと、「選ばない商品の集合」のような集合パラメータがあります。数値パラメータは、標準的な栄養摂取量をデフォルト値に設定し、ユーザの入力に応じて対応するパラメータを変更します。集合パラメータは、RAGを活用して生成します。RAGとはRetrieval-Augmented Generationの略で、LLMによる回答生成の際に、外部データの検索を組み合わせて回答精度を向上させる技術のことです。生成例を以下に載せます。


また、献立に関してどのような条件を気にするかはユーザによって異なります。この点は、予め制約条件の一覧を設定し、ユーザの入力に応じてパラメータを変化させるとともに、制約条件のON/OFFを設定することで対処します。下図は、ユーザの入力と対応する制約条件の一例になります。

最後に、「商品情報」、「ユーザの入力」、「生成したパラメータ情報」から、生成AIを利用して献立を選んだ解説文を生成します。
ユーザの入力に応じて制約条件を表す数式を一から生成する方式も検討しましたが、数式の作り方次第で最適化問題を解く際の計算時間が大きく変わるため、今回は安定して計算するために事前に登録する方式を取りました。
具体的なプロンプトや数式は記述せず、概要レベルではありますが、今回利用した技術について解説しました。ユーザの曖昧な好み・要望を解釈できるという生成AIの強みと、数学的に根拠のある解を求めることができるという数理最適化の強みを掛け合わせて、ユーザの好みに応じた献立が作れることが分かりました。
おわりに
今回は、生成AIと数理最適化を組み合わせて作った献立最適化アプリを紹介しました。生成AIの活用が急速に進んでいますが、生成AIの得意・不得意も明らかになってきています。今後は、生成AIの不得意なところを補完するコンポジットAIも普及していくと思います。この記事を読んで、コンポジットAIに興味を持って頂けると幸いです。
最後になりますが、今回ご紹介したようにNRIデジタルでは最新技術の活用方法を継続的に検証し、知見を蓄積しています。「最新技術を使ってみたいけどどう使えば分からない」という方がいらっしゃれば、ぜひNRIデジタルにご相談ください。
References