本稿はSFC-RG Advent Calendar 2016の4日目である.
はじめに
あなたは研究の中間発表を終えて,今晩何を食べようか考えている.たしかに準備不足ではあったけれど,研究の前提をいまいち解さないファカルティの高飛車な質問にはうんざりしたし,今日くらいはパーッと気分転換したいものだ.そういうわけで,あなたは⊿館を飛び出して焼肉 ざんまい 湘南台店に行くことにした.
組合わせ最適化
さて,着席し,メニューを開いたあなたはしばし考える.限られた予算,限られた時間,限られた胃袋の容量———いったい何を頼めば最も満足できるだろうか?
そんなとき,組合わせ最適化が役に立つんです.騙されたと思って,メニューを必死に転記してみよう:
1 | import numpy as np, pandas as pd |
値段 | 品目 | 満足度 | 焼き時間 | 量 | |
---|---|---|---|---|---|
0 | 720 | カルビ | 15 | 9 | 10 |
1 | 950 | 和牛カルビ | 10 | 8 | 10 |
2 | 850 | 和牛中落ちカルビ | 13 | 5 | 14 |
3 | 720 | ハラミ | 13 | 8 | 15 |
4 | 690 | 厚切りロース | 17 | 5 | 15 |
5 | 950 | ネギ牛タン塩 | 19 | 7 | 16 |
6 | 850 | 牛タン塩 | 13 | 8 | 18 |
7 | 600 | イベリコ豚 | 15 | 5 | 14 |
8 | 550 | カシラ | 12 | 6 | 11 |
9 | 580 | 豚トロ | 14 | 8 | 14 |
10 | 680 | ネギ豚タン塩 | 17 | 8 | 19 |
11 | 580 | 豚タン塩 | 16 | 8 | 18 |
12 | 500 | 厚切りベーコン | 18 | 5 | 11 |
13 | 380 | ウインナー | 18 | 6 | 11 |
14 | 400 | チョリソ | 11 | 6 | 17 |
15 | 550 | ホルモン | 16 | 6 | 19 |
16 | 600 | シロコロホルモン | 17 | 5 | 19 |
17 | 550 | レバー | 17 | 7 | 13 |
18 | 450 | 白レバー | 18 | 9 | 16 |
19 | 550 | ハツ | 11 | 8 | 17 |
20 | 650 | ミノ | 15 | 8 | 12 |
21 | 1280 | お得!! 三種盛り | 19 | 7 | 10 |
22 | 780 | 本日の塩三種盛り | 18 | 9 | 13 |
23 | 780 | 本日の味噌三種盛り | 19 | 7 | 15 |
メニューがpandasのデータフレームになった.取り急ぎ(?)満足度・焼き時間・量は乱数で埋めている.
あなたはこのメニューの中から,最も満足度の高い組合わせを見つけたい.それも,限られた予算,限られた時間,限られた胃袋の容量という条件を満たすような.ここではそのわがままを割当問題として解くことにする.
変数 | $x_i \in \{0, 1\}$ | i番目の料理を選ぶかどうか |
---|---|---|
目的関数 | $\sum_i{満足度_i x_i}$ | $\rightarrow$ 最大 |
制約条件 | $\sum_i{予算_i x_i} \le 12000$ | 予算制限 |
$\sum_i{焼き時間_i x_i} \le 120$ | 時間制限 | |
$150 \le \sum_i{量_i x_i} \le 200$ | 分量制限 |
こういった問題はpulpという整数計画法ライブラリを使って解くことができる:
1 | from pulp import * |
はい.順番はともかくとして,これらを食べれば満足できそうだ.
ここまで考えたところで,あなたは今月の懐具合がよろしくないことを思い出す.なるべく出費を抑えて,それでいてある程度満足できるような品目の組合わせはあるだろうか?
これも同様に割当問題として考えられる.
変数 | $x_i \in \{0, 1\}$ | i番目の料理を選ぶかどうか |
---|---|---|
目的関数 | $\sum_i{予算_i x_i}$ | $\rightarrow$ 最小 |
制約条件 | $\sum_i{満足度_i x_i} \le 200$ | 満足度制限 |
$\sum_i{焼き時間_i x_i} \le 120$ | 時間制限 | |
$150 \le \sum_i{量_i x_i} \le 200$ | 分量制限 |
1 | m = LpProblem(sense = LpMinimize) # 最小化問題 |
200の満足度でいいなら豚ばっか食ってろということらしい.
多腕バンディット問題
いやいやちょっと待った.乱数でお茶を濁しているけど,あらゆる品目の満足度なんて知らないじゃないか.全品目を食べたことがあるならいざ知らず.それに,毎日同じ店で同じ食事をとるわけでもない.焼肉屋にしたって,湘南台には寅屋にえのもとにとあるわけだ.
そういうわけで,あなたはいろいろな店に行き,いろいろな注文をして,なるべくどれを頼んでも満足度の高い食事のとれる店を見つけたいと考えた.しかしここで疑念が生まれる———いまの店でそこそこ満足できるなら,別の店を探さなくてもよいのではないか? しかしいまの店に行き続ける限り,別の店の食事を食べることはできないぞ.しかしそこがハズレだとしたら.さてどうしよう———業界用語でこれを探索と利用のトレードオフ (exploration-exploitation tradeoff) という.
これまでの学習結果を利用 (exploitation) しようとすると,探索 (exploration) が減ってしまい,機会損失が増えてしまう.一方,探索を増やせば,学習した最良の行動とは異なる行動をとることが増えるため,得られる報酬が減ってしまう.学習した最良の行動との差が,探索のコストということになる.— 牧野,et al. 『これからの強化学習』
このトレードオフを解消する試みを多腕バンディット問題という.多腕バンディット問題は,複数のスロットマシンのレバー(腕)を次々と引いていき,最終的に得られる報酬を最大化するというもので,強化学習の一種といえる.各スロットマシンの報酬はそれぞれ一定の確率分布に従っている.言い換えれば,いろいろな店のメニューにある品目を試していき,最終的に得られる満足度を最大化していく,ということになる.もちろん,品目によって得られる満足度に違いはあるが,なるべく何を食べても満足度の高い店を絞り込んでいきたい.
そのためのアルゴリズムのうち,ここでは$\epsilon$-GreedyとUCB1を紹介したい.
$\epsilon$-Greedy
デフォルトで現在最良な選択肢を選ぶが,一定の確率でいま最良と思っていないような選択肢を選びにいく手法.
- $\epsilon - 1$の確率で最適だと思われる選択肢を利用する
- $\epsilon / 2$の確率で最適だと思われる選択肢を探索する
- $\epsilon / 2$の確率で最悪だと思われる選択肢を探索する
$\epsilon$ Greedyはつまり行きつけの店に入り浸るタイプのアルゴリズムだ.
UCB1
それもいいが,実はいまの行きつけよりもっといい店なのに,一度行って微妙だったからといって行かないままになっている店がないだろうか? UCB1は,それぞれの店についてどれくらい知っているかを考慮に入れ,なるべく多くの店のことを知ろうとするアルゴリズムだ.具体的には,各店(腕)についてUCB (Upper Confidence Bound) という値を計算する.
$\overline {x}_{j}+c\sqrt {\dfrac {2\log n} {x_{j}}}$
ただし$\overline {x}_{j}$は$_{j}$番目の店の満足度(報酬)の期待値,$n$はそれまでに店を回った回数の合計,$n_{j}$は$_{j}$番目の店に行った回数,$c$は定数.UCB1は,この値が最大になる店に飛び込んでいく.あなたが好奇心旺盛なら,こちらのアルゴリズムを使って考えたほうがいいだろう.
この手法のメリットとして,ベストでない店に行く回数を確率$1$で$O(\log n)$以内に抑えられる.長々とした証明は論文を参照していただくとして,これは店に行く回数が十分大きい場合の理論限界に到達している.デメリットとしては,探索のためによくない店にあたってしまうことが多いという点が挙げられる.
実験
では,$\epsilon$-GreedyとUCB1が最良の店を選ぶ過程はどうなっているだろうか? 『バンディットアルゴリズムによる最適化手法』のサンプルコードをPython3 + numpy向けに改変して実験.
1 | import pandas as pd |
好奇心旺盛な人は序盤それなりに苦労することがわかる.
おわりに
こうしたナイーブな実装で焼肉の頼み方を最適化したり,店の巡り方を最適化できるかどうかというとまあ実際微妙(たとえば焼肉の各品目から得られる満足度は,限界効用逓減の法則に従ってすり減っていく)だが,日々の意思決定をアルゴリズム的に考えてみる遊びはそれなりにおもしろい.ソーシャルゲームにどう課金するか,というのもこの俎上に載せられる.
『Algorithms to Live By: The Computer Science of Human Decisions』という本はそういう,情報系の人間がよくやる与太話をまじめに考察したものだ———書類はどのキャッシュアルゴリズムに従って並べるべきかとか.先に挙げた探索と利用のトレードオフについても述べられている.YouTubeで著者らの講演を観てほしい.
はい.
参考文献
- 献立を組合せ最適化で考える - Qiita
- 備忘録@Python ORセミナー: Pulp - Qiita
- A/Bテストよりすごい?バンディットアルゴリズムとは一体何者か - Qiita
- コンピュータ囲碁における モンテカルロ法 ~理論編~[PDF]
追記 (2016.12.06)
今回のような設定では多腕バンディット問題というより最適腕識別として考えたほうがよさそう.多腕バンディット問題は累積報酬の最大化が目的だけれど,最適腕識別はどの腕が最良か発見するのが目的.将来の報酬が最大の腕を見つける,ということ.『バンディット問題の理論とアルゴリズム』を読めばいいんだとか.