Slide 1

Slide 1 text

技術書典 5 のサークル配置最適化 白金鉱業 Meetup Vol.4 @shuhei_fujiwara 2018-11-29 1

Slide 2

Slide 2 text

自己紹介 藤原秀平 (FUJIWARA Shuhei) Twitter: @shuhei_fujiwara ▶ 技術書典運営スタッフ ▶ 株式会社メルペイ ▶ TensorFlow User Group Tokyo Organizer ▶ Google Developer Expert (Machine Learning) 2

Slide 3

Slide 3 text

技術書典知っていますか!? ▶ 技術書の同人誌即売会 ▶ 技術書典 5 は来場者数 1 万人を突破!! ▶ 次回開催は 2019 年 4 月 3

Slide 4

Slide 4 text

技術書典サークル自動配置の話 Blog: https://blog.techbookfest.org/2018/08/20/seat-optimization/ ▶ ざっくり概要を面白おかしく 技術季報: https://techbookfest.org/journal/4 ▶ 論文 like な感じで抜け漏れなく 今回のスライド ▶ 実際の試行錯誤を時系列で赤裸々に ▶ 地獄の 1 週間だ! 4

Slide 5

Slide 5 text

解決したい課題 ▶ 約 500 サークルがそれぞれどこの席に座るかを決めたい こ40 こ01 け78 け41 け38 け39 け40 け01 く20 く01 き40 き01 か80 か41 か40 か01 お40 お01 え40 え01 う78 う41 う40 う03 う01 い30 い01 あ01 あ20 催事スペース 荷物作業スペース スポンサーブース 運営ブース 出⼝ ⼊⼝ ▶ 人手でやるのは相当厳しい規模 ▶ 技術書典 4 は約 250 サークルでとりあえず雑に並べるだけで丸 2 日 ▶ そこからさらに調整が入る 5

Slide 6

Slide 6 text

得られた成果 ▶ 叩き台の作成が自動化されて 5 分で終わるようになった! ▶ 丸 2 日掛かっていた作業が 5 分ですよ! ▶ サークル数が倍になったのにですよ! ▶ 浮いた数日分を微調整に全投入して配置のクオリティが上がった ▶ あんま楽になってなくない...? ▶ 決して叩き台の質が低かったわけじゃないんですよ...! 6

Slide 7

Slide 7 text

どういう配置だと嬉しい? 最初の要件: 「似たジャンルのサークルは近くにいてほしい」 ▶ サークルの類似度を定義する必要がありそう ▶ これは頑張ればなんとか...? ▶ 何をもってして近くと定義すれば良いか ▶ これ厳しくない...? 7

Slide 8

Slide 8 text

サークル間類似度を定義する まずは手作業でサークルにこんな感じの tag を付ける tag 1 tag 2 tag 3 · · · circle 1 数学 機械学習 R · · · circle 2 機械学習 数学 . . . . . . . . . . . . circle m Android IoT Kotlin · · · ▶ 元々手作業での配置のために似たようなことをしていたのを流用 ▶ Tag 集合同士の類似度なら上手いこと定義できそう ▶ ただし tag はかなり雑につけられていることを想定したい 8

Slide 9

Slide 9 text

類似度の定義 Tag によるスコアの定義 r(t) := 1 log[Tag t を持つサークルの総数] サークル間類似度の定義 Ci , Cj をサークル i, j を表す tag 集合として s(Ci , Cj) := max t∈Ci∩Cj r(t) ▶ 珍しい tag が優遇されるように傾斜をつけた ▶ Tag が多いサークルが有利にならないよう最大だけを見る 9

Slide 10

Slide 10 text

各席同士の近さは定義するべきか? 真面目にやると泥沼っぽい予感がするのでやりたくない... ▶ 隣と背中合わせはどっちがどれくらい近いの? ▶ 通路を挟んで向かい合わせは近いの? ▶ 会場や机の並べ方を変更したら全部吹っ飛ぶし... こ40 こ01 け78 け41 け38 け39 け40 け01 く20 く01 き40 き01 か80 か41 か40 か01 お40 お01 え40 え01 う78 う41 う40 う03 う01 い30 い01 あ01 あ20 催事スペース 荷物作業スペース スポンサーブース 運営ブース 出⼝ ⼊⼝ 10

Slide 11

Slide 11 text

サークルを部分集合に分割する方針で舵を切る circle block circle A あ circle B う circle C う circle D あ . . . . . . size: 3 size: 3 size: 3 size: 3 A B C D E F G H I J K L A D I B C E F J K G H L サークル A~L を部分集合に分割 size: 3 size: 3 size: 3 size: 3 ▶ こんな感じの表が自動でできれば十分なのでは? ▶ 同一ブロック内の細かい配置は人間が調整すれば良いんじゃない? 11

Slide 12

Slide 12 text

サークル分割問題 Table 1: xij block 1 block 2 block 3 · · · block N circle 1 1 0 0 · · · 0 circle 2 0 0 1 · · · 0 circle 3 0 0 1 · · · 0 . . . . . . . . . . . . ... . . . circle M 0 1 0 · · · 0 min x m ∑ i m ∑ j n ∑ k sij xik xjk s.t. xik ∈ {0, 1} n ∑ k xik = 1 m ∑ i xik ≤ ck ▶ 同一ブロック内のサークル間類似度の総和を最大化 ▶ ブロック k には任意のサイズ ck を与えることができる 12

Slide 13

Slide 13 text

サークル分割問題を解く この規模なら整数計画問題のソルバーに突っ込めばいけるんじゃないの? ▶ 目的関数が 2 次の整数計画は解き切るのが厳しいけれど 補助変数を導入すれば線形に落とせる ▶ やってみたら必要な補助変数が思ったより多くてダメ ▶ 2 分割を再帰的にやるとかも考えたけど厳しい ▶ 100 サークルを 2 分割くらいが限界っぽい 13

Slide 14

Slide 14 text

サークル分割問題を解く 連続緩和して適当に丸めれば良くない? ▶ 基本的にサークルを細かくちぎるほど得をしてしまうので全然ダメ ▶ xi1 = xi2 = · · · xin = 1/n みたいな酷い緩和解が平気で出てくる 14

Slide 15

Slide 15 text

サークル分割問題を解く 最終的に簡単なヒューリスティクスに着地 1. ランダムに実行可能解を生成 2. ランダムに 2 ブロックを選択 3. 各ブロックからランダムに 1 サークルずつ選択 4. 目的関数値が改善するならばサークルの座席交換を実行 5. 2–4 を適当な回数繰り返す 15

Slide 16

Slide 16 text

この時点でプロトタイプを作業者に共有 実際に作業者が集まって問題点を洗い出してみた ▶ ブロック間の距離や類似度は考慮されていない ▶ Android ブロックが離れたところに 2 つできてしまう、といったことが起こる ▶ やっぱりブロック内の並び順も欲しいなという欲が出てくる ▶ まずはブロック内の並び順はランダムにしてみた 16

Slide 17

Slide 17 text

ブロック間の調整 A D I B C E G H L F J K あ01--あ03 い01--い03 う01--う03 え01--え03 ブロックの位置を人手で入れ替える A D I B C E G H L F J K あ01--あ03 い01--い03 う01--う03 え01--え03 ▶ 同じサイズのブロック同士は位置を交換することができる ▶ ブロックのサイズをできる限り揃えて人間による調整の余地を残す ▶ 元々の「あ」〜「こ」のブロックをもう少し細かく分割 17

Slide 18

Slide 18 text

ブロック内の調整 元々は人手でやるつもりだったんだけど夜なべして頑張った ▶ 同一ブロックに類似サークルが集まっているのは購入者が 買い逃し無く回るために大事 ▶ 隣同士のサークルは会話をする仲間なので別の意味で大事! 配置発表 3 日前の会話 「やっぱりブロック内の並び順欲しくない?」 「次回までには欲しいですね」 「明日までに欲しくない?」 18

Slide 19

Slide 19 text

ブロック内のサークル順列問題 (突貫工事だ!) ▶ 同一ブロック内のサークルは一直線上に 並ぶと仮定 ▶ 隣同士の類似度の総和を最大化を ブロックごとに解く ▶ アルゴリズムはサークル分割問題と同じで 座席交換の繰り返し ▶ 時間の都合上こうなったけどもっと良い方法が ありそう 1 3 2 4 s12 s23 s34 s12 s13 s24 要するに完全グラフ上で最長ハミルトン路を求める問題 19

Slide 20

Slide 20 text

やったか...!? やったぜ! ▶ 残り 2 日くらい使って人手による調整 ▶ 自動生成した叩き台の質はまあまあ高かったのでもうちょいサボることも できたんだけど、つい拘っちゃうのが人間の性なんですよ...! ▶ 調整の過程で今回モデルに含められなかった制約を洗い出す ▶ 次回に反映させるぞ! 20

Slide 21

Slide 21 text

要件を振り返ってみる 結局こういうことだったんだなぁ 1. 似たジャンルのサークルが近いエリアに集まって欲しい ▶ 参加者が効率よくサークルを回れるように ▶ 潜在的な購買層にリーチできる可能性が高まる ▶ 偶々好みの本を見つけて購入してくれると双方幸せ 2. 特に隣同士のサークルは類似度が高いことが望ましい ▶ サークル参加者同士で交流して欲しい 3. 特に珍しいジャンルのサークルは優先度が高い 21

Slide 22

Slide 22 text

今後の課題 ▶ 最適化アルゴリズムはまだまだ改善できる ▶ 位置交換するサークルの選び方など ▶ 今回考慮していない制約を追加する ▶ 頒布部数や壁サークル ▶ 難しいけど人の流れを考慮できるとすごく良い 22