糞糞糞ネット弁慶

読んだ論文についてメモを書きます.趣味の話は http://repose.hatenablog.com

Sequences of Sets (KDD 2018) 読んだ

KDD 2018 | Sequences of Sets
好きな研究者が何人かいて,タイトルで気になった論文の著者がその人だとちょっとうれしくなる.Cornell University の Jon M. KleinbergGoogle の Ravi KumarStanford の Jure Leskovec は気になって定期的に著者のページを見に行っている.Facebook の Lars Backstrom は久しく論文を書かなくなってしまったので悲しい.
今回の論文は Ravi Kumar が Co-Author に入っている.

集合 (set) の系列 (sequence) についてモデリングする.論文中では

  • ある人物が送信したメールそれぞれの宛先を時系列でソートしたもの
  • Stack exchange において投稿された質問に付与されたタグをユーザごとに集めてソートしたもの
  • センサーから得られた人の接触データ
  • 共著関係

を対象に分析・観察を行い,集合の系列の推定モデル Correlated Repeated Unions (CRU) model を提案している.

データの観察

  • 集合は繰り返す.多くの集合は系列において繰り返し現れるし,全く同じものだけでなく上位集合 (superset) や部分集合 (subset) も現れる
    • 系列を前から見ていった時にある集合 (と完全に同じもの | と全く要素がかぶらない集合 | の部分集合 | 上位集合) ががそれより前に現れた比率を見ると集合が繰り返して現れていることがわかる
  • 集合の要素は相関する.二つ組,三つ組の組み合わせは相関を持って現れる
    • 全集合から全ての二つ組,三つ組を数え上げるとそれらがランダムに出現する個数より多い
  • 古いものより新しいものに類似した集合が出現する
    • ある集合と,それより k 個前に現れた集合との Jaccard 係数の平均を見ると, k を大きくするほど低下する.つまり近ければ近いほど集合間の類似性は高い

CRU モデル

これらを踏まえて集合系列のモデルを提案する.
しかしここまで読むとこのモデル,系列 S_1,\cdots,S_n が観測されている状態で S_k までを用いて S_{k+1} がどのように生成されるかをモデル化している (機械学習的な外挿を行うモデルではなく,物理のように現象を理解するためのモデルのようなニュアンス).本来想定していたのは S_n までが与えられた状態で S_{n+1} を推定するモデルだったのでちょっと肩透かし.
パラメータとして長さ n であるいくつ前の集合を重視してサンプリングするかの w と集合内からサンプリングを行うための p を持つ.また, S_{n+1} の要素数も (なぜか) わかっているとする.こういう仮定のおかげで将来予測ができない.
CRU モデルの論文の説明を Python のコードで書いた.大雑把な言い方としては

  • 過去の系列をさかのぼってどの集合から要素をサンプリングするかを選ぶ
  • 選んだ集合から要素をサンプリングする
  • これが一定の大きさになるまで繰り返す

という動きをする.

# S_i の重み付き抽出に必要
from numpy.random import choice

# 長さ k の 集合の系列 S を受け取って次の繰り返し集合 R を出力するモデル
def CRU(r, w, p, S):
    R = set()
    k = len(S)
    while True:
        if len(R) == r:
            return R

        # S_i を重み w_{k + 1 - i} で抽出
        # w は重みなのでサンプリング用の確率に変換する
        p_s = [w[k + 1 - i] for i in range(k + 1)]
        p_s = [x / sum(p_s) for x in p_s]
        S_i = choice(S, p=p_s)

        # S_i から各要素を確率 p でサンプリング
        T = set()
        for s in S_i:
            if random.random() <= p:
                T.add(s)

        # この時の n は系列の「全長」 (未来の分まで含める)
        if len(R | T) > n:
            while len(R) < n:
                # T から一様に要素をサンプリング
                y = choice(T)
                R.add(y)
                T.remove(y)
        else:
            R = R | T

パラメータ推定

推定したいのはいくつ前の集合を重要視してサンプリングするかのパラメータ w (論文冒頭にて要素内からのサンプリングパラメータ p はグリッドサーチしたと言及がある).尤度の式を作ることができればパラメータの推定はできるはず.しかし集合が生成される尤度とはどういう形でしょうか.僕はすぐには思い浮かばない.
3.2 を真面目に読んでいないけれど,方針としては出力される R の部分集合すべてについてそれが生成される確率を求めてやればいい,という理解でいる.これ以上はこの論文を再実装したくなった時に読み返す.

Learning and Transferring IDs Representation in E-commerce (KDD 2018) 読んだ

KDD 2018 | Learning and Transferring IDs Representation in E-commerce
EC サイトにおける商品 (item) の埋め込み (embedding) を学習する.その際,商品につけられたメタデータをまとめて学習する.

基本方針

ユーザの商品閲覧行動にもとづいて skip-gram を学習する.すなわち,窓幅を C として

\frac{1}{N}\sum_{n=1}^{N}\sum_{-C \leq j \leq C}^{1 \leq n + j \leq N,\ j \neq 0} \log p(\textrm{item}_{n + j} | \textrm{item}_{n})

を学習する.この時

p(\textrm{item}_{j} | \textrm{item}_{i}) = \frac{\exp ({e^{\prime}_{j}}^{T} e_i)}{\sum_{d}^D \exp ({e^{\prime}_{d}}^{T} e_i)}

である.e^{\prime}\, em 次元の商品の埋め込みとして得られる.

商品と属性の埋め込み

ここで,商品には様々な属性が付与されていることを考える.論文では例として

  • ある「商品」(product,例えば iPhone X) は異なる店 (store) にて異なる商品 (item) として扱われている
  • 「商品」にはブランド (brand) が付与されている
  • 「商品」には階層的なカテゴリ構造 (cate-level1, cate-level2, cate-level3) が付与されている

としている.以降, item ID, product ID, store ID, brand ID, cate-lebel1 ID, cate-lebel2 ID, cate-lebel3 ID の 7 種類を考える (これ以上増やすことも可能).また,これを「属性」と呼ぶことにする.

今, K 種類の属性があり,\textrm{IDs}(\textrm{item}_i) = [\textrm{id}_1(\textrm{item}_i), \cdots, \textrm{id}_K(\textrm{item}_K)] とする.また \textrm{id}_1 を item ID とすると,次の式がこの論文の提案手法.

p(\textrm{IDs}(\textrm{item}_j) | \textrm{IDs}(\textrm{item}_i)) = \sigma (\sum_{k = 1}^K (w_{jk} e^{\prime}_{jk})^T(w_{ik} e_{ik})) \prod_{s=1}^S \sigma (-\sum_{k = 1}^K (w_{sk} e^{\prime}_{sk})^T(w_{ik} e_{ik}))

S は negative sampling における負例集合であり, e_{ik} は 商品i における属性 \textrm{ID} k ごとの埋め込み.属性ごとに埋め込みの次元長  m_k は変わる (この時点では全ての埋め込みは異なるものとして扱う).言ってしまえば,商品ごとの全属性の内積の総和を用いて商品の出現確率を計算する.w_{ik} = \frac{1}{V_{ik}} であり V_{ik}i の属性 k を持つ商品の個数.

更に,商品とその属性との関係も学習する.すなわち

p(\textrm{item}_i | \textrm{IDs}(\textrm{item}_i)) = \sigma (\sum_{k=2}^K w_{ik} e_{i1}^T M_k e_{ik})

とする.ここで M_k は商品 i の長さ m_1 の埋め込み e_{i1} を各属性 k の長さm_k 埋め込みに変換するための行列.ここでようやく商品と属性の埋め込みが同じものとして扱えるようになる.\sum のインデックスが k=2 から始まっているのが重要.

最終的な目的関数は

\frac{1}{N}\sum_{n=1}^{N} ( \sum_{-C \leq j \leq C}^{1 \leq n + j \leq N,\ j \neq 0} \log p(\textrm{item}_{n + j} | \textrm{item}_{n}) + \alpha \log p(\textrm{item}_n | \textrm{IDs}(\textrm{item}_n)) - \beta \sum_{k}^K ||M_k||_2)

とする.[tex\alpha]は商品自身の表現に対する重みのハイパーパラメータ,\betaM_k に対する L2 正則化のハイパーパラメータ.

ユーザの埋め込み

複雑な方法はあるけれど計算が簡単なので直近 T 個の商品の埋め込みの平均をユーザの埋め込みとする.

応用

類似商品の提示

あるユーザが直近で閲覧したいくつかの商品について埋め込みが類似する商品を列挙すればいい.

未知の商品に対する計算

未知の商品 i があるが属性が付与されているときにその商品の埋め込みが計算できる.

p(\textrm{item}_i | \textrm{IDs}(\textrm{item}_i)) = \sigma (\sum_{k=2}^K w_{ik} e_{i1}^T M_k e_{ik})

だったことを思い出すと \sigma は単調増加なので

p(\textrm{item}_i | \textrm{IDs}(\textrm{item}_i)) \propto \sum_{k=2}^K w_{ik} e_{i1}^T M_k e_{ik} = e_{i1}^T(\sum_{k=2}^K w_{ik}  M_k e_{ik})

となる.目的関数が十分に最適化されていれば p(\textrm{item}_i | \textrm{IDs}(\textrm{item}_i)) は 1 と考えられるので式変形をすれば

e_{i1} \approx \sum_{k=2}^K w_{ik} e_{ik}^T M_k^T

で値が得られる.

異なるドメインに対する転移

ここの記述が全く理解できていない.

という手続きが説明されているが,そもそもユーザの埋め込みが共有できるということは商品の体系も共通していなければならない.揃っているならばまとめて学習すればいい(ドメインの違いは属性として特徴量に持たせればいい)のではないか.論文中では Taobao を source , Hema を target としているがそもそも EC サイトとしての性質が大きく異なるのに共通で計算できているという話もよくわからない.
「cold-start なユーザに対する推薦」という話だとしても,クラスタにそのユーザを割り振る際に計算するユーザの埋め込みはどのようにして計算できているのか,という話が理解できない(そこが計算できているならばクラスタに割り振る処理は不要ではないか).

とここまで書いたところで 5.3 にて Since new users have ho historical records に気づくが,やはりどうやって新規ユーザの埋め込みを計算したのかが謎.致命的な何かを読み落としているとしか思えない.

Trajectory-driven Influential Billboard Placement (KDD 2018) 読んだ

KDD 2018 | Trajectory-driven Influential Billboard Placement

街頭広告をどのように選ぶかに取り組む。
問題設定としては

  • 緯度経度で構成される軌跡 (trajectory) t=\{p_1, \cdots, p_{|t|}\} の集合
  • 緯度軽度とコストで構成される街頭広告 (billboard)  b の集合
  • 総予算 L

が与えられ、

  • 軌跡 t のいずれかの点が街頭広告 b の半径 \lambda に入った時、確率 pr(b, t) で影響を受ける (influenced)
  • 街頭広告集合 S に対する軌跡 t への影響を 1-\prod_{b \in S} (1-pr(b, t)) とする

とするときに影響が最大になるように広告を選ぶ問題を解く。
方針としては「実データにおける多くの軌跡は短い領域の中に存在する」という観測にもとづき、同じ軌跡になるべくクラスタが被らないように街頭広告をクラスタリングして解く。

DP の話が出てきたので読むのを止めた。
こういう話結構昔からやられてそうだけど最適化の世界はよくわからない。詳しい人に解説してほしい。 (論文中では半径を考慮しなきゃいけないところが既存手法で対応していないらしい)

Customized Regression Model for Airbnb Dynamic Pricing (KDD 2018) 読んだ

KDD 2018 | Customized Regression Model for Airbnb Dynamic Pricing

民泊サービス Airbnb において, host (部屋を提供する人,ホスト) に対して「この値段で部屋を貸すと良い」と価格を提案する機能を実装するための技術.

  • 予約 (booking) が入るかどうかの予測を行う
  • その上で最適な価格を提示する

という二つの方法を取る.
この論文の貢献は以下の二つ.

  • 価格の決定方法を評価する指標を提案していること
  • その指標にもとづき価格を提示するモデルを学習する方法を考えたこと

なぜ需要の推定が難しいか

「価格を決定する」というのは非常に古典的な問題.一般的には需要関数を求めて面積が最大となるような価格 P を提案する.このとき,需要関数は価格のみの関数 F(P)である.
しかし, Airbnb では需要は価格だけではなく,時刻 t およびその物件を識別する ID id によって決まる F(P, t, id) である.それぞれの要因は次のような要素で構成される.

  • 時刻による違い
    • 季節性やイベントによって需要が異なる
    • 現在時刻と予約を予測したい時刻との差が短ければ短いほど予約されにくい (表示期間が短ければ短いほど予約されにくいという話?)
  • 物件による違い
    • すべての部屋がほぼ同じであるホテルとは異なり, Airbnb にある物件はすべて異なっている (一般的な物件に加え,城やツリーハウス,船がある).これだけでも需要が大きく変わってくる.
    • もし似たような物件に絞ったとしても,レビューが良いほうが需要が高いだろう
    • 近隣物件の需要が高まっているのなら,高評価の物件はより高い価格を提示しても利用率を下げることなく予約が入るだろう.

予約推定モデル

まずは予約されるかどうか推定するモデルを構築する.
特徴量には

  • 物件特徴量 : 物件の価格,部屋の種類,収容人数,ベッドルームやバスルームの数,アメニティ,場所,レビュー,過去の利用率,「今すぐ予約」が可能か,など
  • 時間的特徴量 : 季節性 (何月何日か,何曜日か),予約状況 (チェックインからチェックアウトまでの期間など),予測日から推定対象の日付までの差など
  • 需要・供給のダイナミクス : 近隣の予約可能な物件数,検索者数など

モデルは GBM を使う.ひとつの GBM を推定するのではなく,物件の密度に応じて区画を分け,adaptive sampling を行いながら別々の GBM を学習することで AUC がより良い値になった.

このモデルを需要関数代わりに使うとどうなるか

この予約推定モデルを価格の関数としてみなすことで需要関数として扱うことができる.この関数をそのまま使って収益最大化を A/B テストしてみたが失敗した.
この関数を需要関数としてそのまま使うことには以下の三つの問題があった.

  • データがスパースであること : データにおいて価格は大きく変化していない.たとえば 150 ドルの部屋に対して 50 ドル未満や 500 ドルを設定している人はいない.そのため,平均的な価格のデータばかり集まってしまう.
  • 物件がそれぞれユニークすぎること
  • 特徴量の依存性 : 予約推定モデルにおいて用いた特徴量のうち価格と相関を持つものがあるためうまく働かない.

価格提示モデル

最適な価格と提示価格の関係,オフラインでの評価指標

ここからがこの論文の一番おもしろいところ.
そもそも「最適な (optimal)価格」とは一体どういうことでしょうか.いま手元にあるデータには,「ある価格の物件に予約が入ったかどうか」しかわからず,このデータで学習をしてもただの「現状の価格推定モデル」が得られるだけです.「真に最適な価格」は神様しか知りません.
そこで,真に最適な価格 P_o が存在するとして,実際の価格 P とモデルによって提示する価格 P_{s} との関係を考えると以下のように整理できる.

  • もし物件が予約されて P_s < P だった場合,もしホストがモデルに従っていた場合には P_s - P 分だけ損をすることになる.なのので P_o \geq P でなければならない
  • もし物件が予約されずに P_s \geq P だった場合,もっと安ければより予約される確率が高まっただろう.よって P_o < P でなければならない.
  • もし物件が予約されて P_s \geq P だった場合,もしホストがモデルに従っていた場合 (値上げしていた場合) でも予約が入ったかどうかはわからない
  • もし物件が予約されずに P_s < P だった場合,ホストがモデルに従っていればより予約される確率が高かっただろう.しかし安すぎるとホストが損をしてしまう.

これらの関係を踏まえて,prec-recall の 表のように

  • a :  P_s \geq P かつ予約された
  • b :  P_s \geq P かつ予約されなかった
  • c :  P_s < P かつ予約された
  • d :  P_s < P かつ予約されなかった

として次の 5 つの指標を考える.これらの指標はオフラインでのモデルの評価に用いる.

  • Price Decrease Recall (PDR) : d / (b + d), 予約されなかった中で,安く提案できていた割合
  • Price Decrease Precision (PDP) : d / (c + d), 安く提案できていた中で,予約されなかった割合
  • Price Increase Recall (PIR) : a / (a + c), 予約された中で,高く提案できていた割合
  • Price Increase Precision (PIP) : a / (a + b), 高く提案できていた中で,予約された割合
  • Booking Regret (BR) :  \textrm{max}(0, \frac{P - P_{s}}{P}) の全予約での median

Price Decrease は「より安く提案できていたか」すなわち予約確率をより上げられていたかについて, Price Increase は「より高く提案できていたか」すなわちホストがより収益絵を得られたかについて考えている.
BR は提案によって収益が落ちていたであろう度合いを表している.
検証したところ,これらの指標の中での PDR と BR は実ビジネスでの指標と高い相関を持つことがわかった.特に,PDR は booking gain (予約数?)と相関を持ち,低い BR による価格提案はよりホストの収益を増加させていることがわかる.じゃあ PDR と BR だけを見て最適化すればいいかというとそういうわけにもいかない.なぜなら PDR と BR はトレードオフにあるからだ (安い価格を提案すると PDR は改善するが BR は悪化する).

モデル,目的関数

まず特徴量として

  • ホストによって設定された価格 P_i
  • 予約推定モデルによる確率 q_i
  • 予約推定モデルでは捉えきれなかった市場の需要を示す変数

を入れる.
ここで,目的関数として SVR での \epsilon- insensitive loss (ε許容誤差) のように幅を持たせた新しい損失を提案する.何度も言っているように,「最適な価格」というのを我々は知ることができないけれど,ビジネス的な観点から「最適な価格はこの範囲内に入るだろう」ということはわかるのでそれを損失関数に反映する.
目的関数は次の関数の最小化である.
\textrm{argmax}_{\theta} \sum_i (L(P_i, y_i) - f_{\theta}(x_i))^+ + (f_{\theta}(x_i) - U(P_i, y_i))^+
ここで y_i は i が予約されていたかどうかを示す二値変数, f_{\theta} は推定したいモデル,(x)^+ = \textrm{max}(0, x)
L, U はそれぞれ
L(P_i, y_i) = y_i \cdot P_i + (1 - y_i)\cdot c_1 P_i
U(P_i, y_i) = (1 - y_i) \cdot P_i + y_i\cdot c_2 P_i
とする.このとき  c_1 \in (0, 1),\ c_2 > 1 である定数.
これが何を意味しているかというと,

  • 予約されている時は価格の下限を P_i,上限を  c_2 P_i とし,その範囲内であれば損失を 0
  • 予約されていない時は価格の下限を c_1P_i,上限を  cP_i とし,その範囲内であれば損失を 0

という形の非対称な損失を考える.

需要に基づく価格設定

更に価格提示のためのモデルを考える.以下のような仮説を置く.

  • 同じ物件ならば予約確率と価格には相関がある.よって予約確率で価格を変化させる.
  • 予約予測モデルでは捉えられなかった需要の兆候が容易に反映できるようにする
  • 代表的な価格を中心にしてそこからの増加・減少分を学習する

これを踏まえ次のようなモデルを作る.
P_s = P \cdot V
V = 1 + \theta_{1} (q^{\varphi_{H}^{-qD}} - \theta_2),\ D > 0
V = 1 + \theta_{1} (q^{\varphi_{L}^{-(1-q)D}} - \theta_2),\ D \leq 0
P はホストによって設定された代表的な価格,qは予約確率,D は類似した物件で作ったクラスタにおける追加の特徴量から構築した需要の度合いを正規分布で正規化したもの.
\theta_1 は価格の増減をコントロールするパラメータ,theta_2P=P_s を出す時の微調整パラメータ.\theta_1,\ \theta_2が与えられるとこの関数は q に対して単調増加する.1 < \varphi_L < \varphi_H < 2 は定数.

学習

とはいえこれだけだと値が壊れるので
 l_1 \leq \theta_1 \leq \mu_1
 l_2 \leq \theta_2 \leq \mu_2
となるような制約を加える.
また,需要が乏しい物件には
a\theta_1 + b \leq \theta_2,\ (a > 0)
という制約を加える.
あとは SGD で学習.

PDR の話のあたり,「真の値が存在しない時にどういう数字を作れば改善してるかどうか考えられるか」の話が一番おもしろかった.気力が尽きたのでP_s = SV の話のあたりはよくわかってない (例えば additional な demand signal とは何か,とか).

声優統計コーパスのバランス文を男性が読み上げた音声ファイルが公開されました

声優統計コーパスのパラレルコーパスとして,東京大学猿渡研究室によるJSUT (Japanese speech corpus of Saruwatari-lab., University of Tokyo)がありました.
このたび,nico-opendata 音声読み上げデータセットDwango Media Village によって公開されました.
nico-opendata 音声読み上げデータセットDwango Media Village の男性研究員が声優統計コーパスのバランス文 100 文を読み上げた音声ファイルです.上記ページでは統計的声質変換に関するサーベイも記述されています.声質変換についてわかっていなかったので非常に参考になりました.
また,同研究員が音学シンポジウム2018で発表を行った「畳込みニューラルネットワークを用いた音響特徴量変換とスペクトログラム高精細化による声質変換」について,発表内容,ソースコード,および,統計的声質変換を実際に行ったデモ音声が公開されています.

せっかくなのでこれを機に様々な人々が思い思いの音声コーパスを公開する時代になると面白いと思います.

Pixie: A System for Recommending 3+ Billion Items to 200+ Million Users in Real-Time (WebConf 2018) 読んだ

[1711.07601] Pixie: A System for Recommending 3+ Billion Items to 200+ Million Users in Real-Time
Pinterest における推薦の論文.Jure Leskovec が last author に入っているのでとりあえず読む. WWW が WebConf に名前が変わったのが悲しい.

概要

超大規模なサービスである Pinterest においてリアルタイムな推薦を実現する Pixie について説明する.

手法

Pinterest ではユーザは Board の下にそれぞれの pin を保存する.実現したいのは直近のユーザの行動によって得られた pin と重みの集合であるクエリ Q に対して適した pin を推薦したい.
基本的な方針は pin と Board を二部グラフとみなしてそのグラフ上をランダムウォークする.

ランダムウォークの基礎

クエリ が 1 つだけで重みがない場合のランダムウォークについて考えてみると,二部グラフ上の かららスタートして 回二部グラフ上をランダムに渡り歩き,それぞれの pin を訪問回数 順に並び替えて返せばいい.
この手法を次に説明するように発展させていく.

ランダムウォークにバイアスをかける

まずはただランダムに遷移するのではなく,ユーザごとにバイアスをかけることを考える.隣接ノードを uniform に選ぶのではなく,ユーザごとの特徴量に従って遷移するノードを PersonalizedNeighbor(E, U) という関数で選ぶ.この関数についてはこれ以上の説明がないので詳細は不明.

複数のクエリと重みを扱う

クエリとして複数の pin とそれぞれの重みを扱う (重みはその pin に対してユーザがどういう行動をとったか,およびその行動が発生してからの経過時間にもとづいて決まるらしいが詳細な説明無し).
基本的には各クエリごとにランダムウォークを行い,クエリごとの pin の訪問回数 を保存する.
ここで重要なのは,各クエリにおいてランダムウォークの回数 を変えて とすることである.クエリの次数が大きければ大きいほどランダムウォークの回数は多くする.
と思ったらより効率的にするために early stopping を導入する.これは最低 個の pin に最低 回訪問したらランダムウォークを打ち切るというもの.これによって精度はそのままに計算時間が倍の速さになった.
(early stopping するなら重みの形はどうでもいいのだろう)

Multi-hit Booster

ただ足し合わせるのではなく, として複数のクエリから訪問されている pin を重く評価する.

グラフの枝刈り

グラフはそのままだと非常に大きいので枝刈りする.方針としては二つ.

雑多な Board を削除する

pin の説明文に対して LDA を適用して topic distribution を計算して topic vector とする.その後,それぞれの Board に直近で追加された複数の pin の topic vector の entropy を Board の entropy とし,これが大きい Board をグラフから削除する.

人気の pin を削除する

人気の pin を削除する.がただ削除するのではない.その pin の topic vector と Board の vector とのコサイン類似度を取って類似しているもののみ残す.

この枝刈りによってグラフの大きさを 1/6 にし,推薦の類似度を 58% 改善した.

ML Ops Study #2 参加した

ML Ops Study #2 - connpass
申し込んだら当たったので参加した.皆さんみたいにちゃんとした機械学習や深層学習がしてみたかった.

機械学習プロジェクトを頑健にする施策: ワークフロー、仮想化、品質向上、知識移譲 etc

機械学習プロジェクトを頑健にする施策 ML Ops Study #2 // Speaker Deck

  • 機械学習プロダクトは脆い.原因とその対策.
    • 実験スクリプトが動かない
    • 実験スクリプトが理解できない,実験した人がいなくなる
      • ソフトウェアエンジニアリングをちゃんとする
      • ソフトウェアエンジニアが書いてリサーチャーがレビューする
      • コードの整理は実験をした本人がやる
        • この話,金融機関における数理モデル研究から実用化に至るノウハウなどが(もしあるのならば)参考になるのではないかと思った
      • テストもちゃんと書く

質疑で「リサーチャーは Jupyter notebook が精一杯だったりする.リサーチャーがソフトウェアエンジニアの,ソフトウェアエンジニアがリサーチャーの素養がある程度ないと難しいのではないか」みたいな質問があり, Cookpad 社は両方素養がある人ばかりなのでコードレビューも問題無いという返答があった.Jupyter notebook ですらまともに使うことができない低レベルの人間なのでとても参考になった.
Github や Qiita に公開されている機械学習系のコードは品質がひどくて動かない事が多い」という話で自分を除く皆さんが笑顔になっていた.

ドローン点検・測量を機械学習を使って圧倒的に簡単にしました

  • SONYZMP が組んだエアロセンスではドローンによる測量をやっている
  • ドローンの GPS は誤差が酷いのでマーカーを併せて使うことが一般的だが
    • マーカーの正確な位置を手で測量しなきゃならない
    • 画像中のマーカーを手で特定しなきゃならない
  • そこでマーカーを独自開発する
    • 高精度 GPS と高さ計測をマーカー自身で実現
    • その上でドローンから空撮した画像中からマーカーを自動検出 (opencv による候補抽出 + tf 実装の VGG でマーカーかどうか分類) する
      • どうして一つのモデルで全部やらないかの質疑が聞き取れなかった
  • 結果手作業を 60% 削減できた

Kelner: 爆速で構築できる機械学習モデルサーバー

What is Kelner? | Kelner
学習済み機械学習モデルを用いた予測を簡単に REST API として公開するためのフレームワーク
機械学習といっても Keras と Tensorflow にのみ対応しており scikit-learn には未対応.よくわかっていないけれど kelner_model.KelnerModel を継承した SKLearnModel とか実装すればいいのだろうか.

このあたりで追加した頭痛薬が効かなくて帰った.