多腕バンディットを Go で実装しようとしてハマったこと

こんにちは、 Wantedly Visit の recommendation squad で  Data Engineer をしている大坪です。今は Data Scientist が作ったモデルのうち「どれをどのくらいの比率で活用するべきか」を自動で解決するために多腕バンディット問題に取り組んでいます。今回はここでハマったことについて書きます。

多腕バンディットとは?

ざっくりいうと「真の期待値が不明である複数のアイテムからどれを活用するべきか」という問題についた名前です。より正確な真の期待値を知るために期待値の低いかもしれないアイテムを使ってみる探索(explore) と、真の期待値が高そうだと思われるものを積極的に使ってみる活用 (exploit) をどのような割合/方策で行うかが重要なポイントです。

動画サービスならどの動画をおすすめするか、Wantedly ならどのシゴトの募集を提示すると良いか、といった問題に活用できます。ただ人気の動画だけをおすすめしていたらこれから大人気になる「金の卵」の動画がいつまで経っても誰にも見られないということが起こってしまい結果的に損をしてしまいます。逆にまだヒットしていない人をガンガン推薦すると質の高くないコンテンツを多く出してしまいこれも損をします。このジレンマを如何にして解消し効率よく最終的な成果を大きくするか?というのが多腕バンディット問題で解くべき課題です。

より正確には下のような詳しいページを参照してください。


それはテストを書いているときだった

多腕バンディットは英語では Multi-armed bandit という表記なので Arm という interface を実装しました。これを活用する package を一つ作成したので同時にテストも書くことにしました。interface なので mockgen を使って mock を作成します。生成されたファイルを bandit_arm.go と名付けました。そこでテストを実行すると作成したはずの mock が存在しないと怒られてしまいます。この時点で察しの良い方は気づいてしまうのではないかと思いますが、自分はこの時点ではわかりませんでした。

試行錯誤の末にわかったことは下の通りです。

  • 別ファイルにコピペすると動くのでファイルの内容に問題はない
  • 名前を変更すると動くことがある

とりあえず名前の変更で逃げることができたので深く追求しませんでしたが謎は残りました。そこでプルリクエストに仕上げた後にもう少し詳しく調べてみました。

ファイル名に問題がある

いくつかのパターンを試してみたところ「_arm.go を suffix に持つファイル名にするとコンパイラから無視される」という主張が正しそうであることがわかりました。ここで公式リファレンスを参照してみると次のように書いてあります。

If a file's name, after stripping the extension and a possible _test suffix, matches any of the following patterns:

*_GOOS
*_GOARCH
*_GOOS_GOARCH

(example: source_windows_amd64.go) where GOOS and GOARCH represent any known operating system and architecture values respectively, then the file is considered to have an implicit build constraint requiring those terms (in addition to any explicit constraints in the file).

つまり _arm が suffix に入っているファイルは ARM architecture のためのファイルであるとみなされ、それ以外の build では無視されるということです。そういえばそういうの見たことあるな...と思い出しました。みなさんも go でバンディット問題を解くときは気をつけてください。

Wantedly, Inc.'s job postings
24 Likes
24 Likes

Weekly ranking

Show other rankings