2020-07-03

Data validation for machine learning 読んだ

Breck, Eric, et al. "Data validation for machine learning." Conference on Systems and
Machine Learning (SysML). https://mlsys.org/Conferences/2019/doc/2019/167.pdf . 2019.

読み手のコンテキスト

現職で機械学習予測モデルをプロダクトに投入する様になって3年程経った。そうもなると開発時に想定していた訓練データの分布と現状の分布が乖離して、予測の動作不良を引き起すケースがしばしば見られる様になった。明らかな予測の不具合として目立っていなくとも性能が落ちている部分はもっとあるはずで、これに早く気づいて対応したいモチベーションがある。かつ運用専任メンバーはいないので、できるだけ運用は手を抜きたい。

概要

著者らはData Validationシステムを開発した。これはGoogleで稼動中のMLプラットフォーム(TFX)にデプロイされており数百のプロダクトで毎日利用されている。論文の構成はData Validationシステムを構成する3つのコンポーネントであるSingle-batch validation・Inter-batch validation・Model testingと、それぞれが解決できるデータの異常パターンと実装した提案手法の解説。最後にGoogleにおける利用状況と実際のサービスにおける検出例 (ケーススタディ) の紹介。

新規性および貢献

MLコンテキストに適用できるData Validationの手法について提案した。

Data Validationはおなじみの概念 (例えば Databaseの分野では) であるが、ML Pipelineの文脈で既存の手法をそのまま適用する事ができない。例えばデータの生成元とMLパイプラインが分離されているので、流れてくるデータを元にschemaを決める事になる。Databaseの世界では先にschemaを決めるので順序が逆。またカイ二乗検定 (chi-square test)の様な手法はMLパイプラインが扱うスケールのデータでは敏感すぎる。よって既存のData Validationを見直してMLコンテキストにマッチする手法を開発した。

Data ValidationはTFXの設定に基づいて開発されたが、別のシステムでも利用可能な様に提案手法をOSSライブラリとして実装もした。

Single-Batch Validation

一度の訓練に利用される訓練データのvalidation。人々は訓練データに対してstableであり続ける何らかの特性を期待している。そのためexpert domain knowledgeによって与えられるデータの特性からの乖離を異常とみなす。これを検出するためにスキーマ定義によるvalidationを開発した。

例えばあるフィールドの出現しうるカテゴリ値を定義できたりする。


ただしMLモデルは数千の素性を利用するため、人がスキーマ定義をゼロから作るのは現実的ではない。この問題を緩和するのに、スキーマの初期バージョンをデータから作成する機能を用意した。バリデーションエラーとなるデータが見つかった時にはスキーマの変更差分も自動で生成する。

Inter-Batch Validation

Concept-Driftの様な一回分の訓練データだけで判断できないタイプのエラーを検出する仕組み。エラーの例として次のパターンを挙げている。
  • Feature Skew
    • 例えば訓練時の前処理と推論時の前処理の差から生まれる。訓練時の前処理と推論時の前処理では求められる性能特性が異なるので、別のコードが使われる。そのため、片方だけ修正してしまうといった事が発生する。
  • Distribution Skew
    • 時間経過による分布の変化
  • Scoring/Serving Skew
    • 多く配信された広告データはサンプルが多いが、少なく配信された広告はデータ少ない
    • MLシステム自身によって発生させたバイアス
これらのエラーを検知するには各バッチ毎に訓練データセット同士の分布の距離をみれば良い。これは分布間の距離を定量的に求めるメトリクスに依存する。統計的検定やKL-Divergenceは最初の一歩となる、しかし値の解釈や閾値の設定が難しかったりする。統計的検定はサンプルサイズが大きいとsensitiveになりすぎる。よって実際に使っているのは分布pとqの距離を次の式で定義したものである。

i は "each value i" とあるから各カテゴリだろうか (自分の理解があやしい)。カテゴリ値ごとの出現率の差なので非常に理解しやすく調整が容易。

Model Unit Testing

例えば前処理で対数変換をしている時、その前処理コードは暗黙的に訓練・予測データに正の値を期待している事になる。よってこの暗黙的な期待が満たされない時にコードはクラッシュしてしまう。推論時にクラッシュしたらサービスに影響が出てしまう。

このエラーに気づける仕組みとして前述のスキーマ定義を用いた fuzz testing アプローチを採用した。Single-Batch Validationで作成したスキーマ定義を基にデータを生成して学習コードを実行する。こうする事でスキーマ定義に現われていない暗黙の期待を洗い出す事ができる。(クラッシュしたらわかる)

Empirical Validation

デプロイしたValidationの利用状況。表1がわかりやすかった。

感想

正に自分が直面している課題を解決する内容だったので先人に感謝。
データエラーの例が生々しくて良かった。思いあたるフシがありすぎて「推論時と訓練時の前処理が別のコードで動いていて片方だけ直してしまうだと……うっ頭が」という状態で読んだ。しかし他の会社でも同じ事が起きているんだなと若干ほっとした。
次はOSS実装版のTensorflow Data Validationを触ってみようと思います。



このエントリーをはてなブックマークに追加

2020-05-05

『効果検証入門』がアプリケーション開発エンジニアにとって得る物が多い本だった

読みました。アプリケーション開発エンジニア視点で読んで同僚に勧められる素晴しい内容でした。本稿はエンジニア視点のレビューになります。

効果検証入門〜正しい比較のための因果推論/計量経済学の基礎
技術評論社 (2019/1/18)
安井 翔太 (著), 株式会社ホクソエム (監修)
Kindle版/紙版両方あり

目次と構成

序 嘘っぱちの効果とそれを見抜けないデータ分析
1章 セレクションバイアスとRCT
2章 介入効果を測るための回帰分析
3章 傾向スコアを用いた分析
4章 差分の差分法(DID)とCausalImpact
5章 回帰不連続デザイン(RDD)
付録 RとRStudioの基礎
終 因果推論をビジネスにするために

まず効果検証とは何かという導入と共にビジネスの現場でありがちな誤りのある検証について解説があります。この誤りの原因となるセレクションバイアスと理想的な比較方法であるランダム化比較試験が1章です。以後の章はランダム化比較試験ができない状況において効果検証にどう取り組むか主要なアプローチ毎の手法の解説と実践例があります。

1章 セレクションバイアスとRCTより

想定読者は「効果検証を行なう必要のあるエンジニアやデータサイエンティスト」となっているのでバリバリ手を動かしてコードが書ける人が対象なのでしょう。文中の操作は全てRのコードが付いています。私はRがわからないのでPythonで再実装しつつ読み進めました。

どんな視点で読んだか

まず私はプロダクト開発エンジニアで、説明のためのモデルよりも予測のためのモデルを作る事が多く、Rはほぼ使った事がなく普段はPythonを書く人間です。機能リリース後の効果検証は解釈の容易さから主にランダム化比較試験を採用しますが、稀に適切なランダム割り当てができないケースで観察研究に頼る事があります。

良かった点

予測のためのモデル(機械学習)に慣れ親しんだ人間が持つ疑問に答えている

機械学習エンジニアは因果推論・計量経済学で用いられる線形回帰モデルよりも予測と汎化性能を重視したより複雑なモデルを扱います。なので当然「クロスバリデーションしなくていいのか?」とか「対数変換やスケーリングした方が精度が出るのでは?」と思うわけです。この様な予測をメインにしている人が効果検証における線形回帰モデルを見た時の違和感の解説が2章の終りにあります。

正しい比較が何の役に立つのか言及している

正確な効果検証が価値を生むビジネスケースとそうでないケースが挙げられています。因果推論で価値を生めるかどうかはビジネスの構造に依存するというのは実務者が持っておいて損がない心構えでしょう。最終章に
もし因果推論でビジネスに対する価値を発揮したいのであれば、「正しい情報がビジネスの価値になる」という構造を持っている環境へ移るか、もしくはそのような環境を作ることを強くお勧めします。
と記述があります。エンジニアは正に「正しい情報が価値を生む」側でしょう。私の現場では「機能開発すべきかどうかの事前調査」と「リリース後の効果検証」が因果推論が絡むタスクです。事前調査は「変数xyに寄与しているならxを利用した機能開発を検討する」といった物で、これを見誤ると意味の無い機能を作ってしまいます。

説明モデルの作り方の参考としても若手に勧められる

新卒エンジニアが部署に配属される時期ですが、エンジニアはコンピューターサイエンス・機械学習よりのスキルを持つ事が多く。極端な例では「ディープラーニングは判るけど一般化線形モデルは知らない」といった事もあります。ただ実務では効果検証のために線形モデルを利用する事はあるので線形モデルの応用や説明モデルの作り方といった計量経済学寄りの知識も持って欲しい訳です。現場のエンジニアに計量経済学の入口として渡すのもアリかなと思いました。

分析コードの難しさがわかる

私は書籍中のR実装をPythonで書き直しながら読み進めましたが、OLSで線形モデルをフィットして係数を求める所までは簡単に再現ができましたが。そこから先のマッチングやIPWとなると途端に同じ結果を出すのが難しくなりました。本の結果という正解がある状況なので自分の仕込んだバグに気づけましたが、正解が無い状況ではコードがバグっているのか仮説が間違っていて期待通りの結果にならなかったのか見極めが非常に難しい事に気づかされます。バグが無くとも利用するライブラリを変えるとまた結果が変わります。

ただ「傾向スコアマッチングをした時には共変量のバランスを確認する」等の因果推論の手法が機能しているかどうかの確認ポイントと前提とする仮定がしっかり解説されており、各手法は知っていても実際に手を動かした事がない人のガイドになる内容になっています。

疑問が残った点

対数を用いた回帰分析 (2.4.3節) で、目的変数の対数を取った時の係数βが 0.1であれば10%引き上げると解釈できるとあったので手元で実験してみたが上手くいかなかった。xが1増える毎にyが倍(100%増)になるようなデータで係数βを求めても1にならないので、βが小さい時のみこの解釈ができる等の制約がありそう。この現象について教えて頂いたので最後に追記ました。

標準化平均差(Average Standardized Absolute Mean distance: ASAM)の定義がわからなかった。本文では「平均の差をその標準誤差で割った値」とあるが、標準誤差はサンプルサイズが増えた時にゼロに近づくのでASAMが発散してしまう気がした。ASAMを利用している論文はいくつも見つかるが定義そのものの数式がなかなか見つからない。平均の差を全標本の標準偏差で割った値が正解?

本だけでわからなかった点ですが、formula定義に出てくる I(re74^2) の I() が何かわからなかったのでRのドキュメントを調べました。混乱を避けるためのただの括弧みたいですね。

まとめ

以前からお世話になっている安井さんが実務者向けの因果推論の本を上梓されたとの事で非常に興味があったのですが、期待を裏切らない内容でした。安井さんは5年程前に予測性能に重きを置く機械学習と説明に重きを置くための因果推論・計量経済学の違いを教えてくれた方であり、それで自分の視野が一気に広がった経緯があります。なので若干バイアスのかかったレビューになっている事はご容赦ください。

因果推論は以前から興味があったもののRCT以外はほぼ使った事がなかったので、実務で利用する際の手順や注意点は非常に参考になりました。あとRが凄いので分析業務は素直にRを使おうという気持ちになりました。

追記

係数を解釈する時に利用している近似はマクローリン展開だから、ゼロから離れると二次以降の項が無視できなくなってズレが大きくなると教えてもらいました。プロットするとこうなります。


このエントリーをはてなブックマークに追加

2020-03-01

ウィルス感染検査とFalse-Positive Paradox

最近のニュースでウィルス感染症の検査と聞いてまっさきに思い浮かんだのが、母集団の感染率より検査の偽陽性確率が高い時に人間の直感から離れた結果になるパラドックスの話。統計学の教科書にも練習問題として出てくる印象があります。

問題

ウィルス感染検査で陽性となった時に被験者が感染している確率を求めよ。

母集団の感染率は0.1%。検査の性能は感度99%・特異度99%、つまり感染している人は99%の確率で陽性となり、感染していない人は99%の確率で陰性となるものとする。

計算

  • 感染しているか否かを y ∈ {0, 1}
  • 検査結果を x ∈ {0, 1} で陽性が1とする
ベイズの定理
 より、検査結果が陽性だった時に感染している確率は
ここで
  • P[y = 1] = 0.001
    • 感染率
  • P[x = 1|y = 1] = 0.99
    • 感度
  • P[x = 1} = 0.001 * 0.99 + (1 - 0.99)(1 - 0.001)
    • 真陽性率 + 偽陽性率
であるから、検査で陽性が出た時に感染している確率 P[y = 1 | x = 1] = 9% となる。

メモ

元々の発生確率が低い場合、人間の直感に反して検査精度よりも小さな値となるため検査結果の解釈は慎重を要する。これは1%の偽陽性によって陽性判定数が増えるからである。健康診断で「要精密検査」という結果が出たが、精密検査の結果何も異常が見つからないケースが同じ。だれもが偽陽性を考慮して結果の解釈ができるわけではないので、例の様な状況において手当たり次第検査を受けさせると混乱が広がる事も想像できる。

文献[1]はFalse-Positive Paradoxにより自動判定を共なうテロリスト検出システムは無実の人々を分析するのに費やされるコストが増える事を指摘している。文献[2]には近い例がいくつか載っている。

おかしな所があったら教えてください。

参考文献

[1] Parra-Arnau, Javier, and Claude Castelluccia. "Dataveillance and the False-Positive Paradox." (2018). https://pdfs.semanticscholar.org/00af/50c635aeebd651d52c5c5e9633201988ee8f.pdf

[2] Wikipedia contributors. (2020, February 17). Base rate fallacy. In Wikipedia, The Free Encyclopedia. Retrieved 02:33, March 1, 2020, from https://en.wikipedia.org/w/index.php?title=Base_rate_fallacy&oldid=941255359

このエントリーをはてなブックマークに追加

2019-12-18

JAZZとコントラバスが少しだけわかってきた

こんにちはhagino3000です。この記事はpyspa Advent Calendar 2019の17日目です。

今年は新しい挑戦としてコントラバスとJAZZを始めました。コントラバスはオーケストラの右端で弾かれる大きな楽器です、和製英語でウッドベースと呼ばれたりもします。JAZZは全く聴いてこなかったので完全に未知の領域です。この分野は素人なのです、本当に。

普段は職場でゲーム音楽のバンドアンサンブルを演っているのですが、Super Mario Odyssayの都市の国のテーマのウォーキングベースを弾きたくなったのがきっかけでした。新しい楽器を始めるのは20年ぶりなのもあり、練習や普段の取り組み方について改めて考え直しました。ソフトウェアエンジニアとしての訓練方法と似た部分もあり、多くの気付きがありました。

楽器スクールに通う

ビギナー段階において人から習う事の効率の良さは業務で身に染みています。自宅の近所にコントラバスでJAZZが習えるスクールがあったので決めました。レッスンでは課題曲のベースフレーズ作成が宿題として出されて、対面レッスンでそれを弾いてフレーズ及び演奏について指導を受けています。枯葉やBlue Bossaといった曲からスタートしました。

ソロフレーズ作成は自由度が高いので、左手のポジション範囲とピッチの制約が課されると捗ります。オルタードテンション(♭9, #9, #11, ♭13)も最初は無しでコードトーンのみで作りました。やはり自由度の高いタスクは難しいです。

スクールは常にコンフォートゾーンの外側になるような負荷が与えられる所が気にいっています。

JAZZが少しだけわかった

今までは「楽譜を暗譜してその通りに弾く」もしくは「楽譜を見ながらそのまま弾く」だったのが、他のパートと合わせた時にどちらも上手くいきません。正解は「コード進行を覚えてアドリブで弾く」なのでしょう。フレーズ作成とは別にコード進行だけ見て弾く練習もやるようにしました。iReal Proが非常に便利です。

レッスンでは一音一音「何故ここでこの音を選んだのか、どの音に向かっているのか」と質問されるので、自分が何の音を弾いているのか意識するようになりました。ただ、進行上は使える筈の#11thが自分の耳には外して聴こえたりするので理論と感覚の乖離がまだあるなと。

レッスン課題曲について様々な人の演奏を聴くように指導されるのでYouTubeとSpotifyをヘビーに使っています。スタンダードナンバーは多くの人にカバーされているから聴き比べが面白い。JAZZのプレイヤーに関する知識ゼロでしたがMichel Camiloのパーカッションとの絡み方やEddie Higginsのキャッチーさに惹かれています。難しいのはMiles Davisです、原曲成分が全く聴きとれなかったりする。やっぱりJAZZはわからない。

多くのプレイヤーの演奏を聴く事に関してはymotongpoo氏がSlack channelに延々と貼り続けてくれた事もあり非常に助かりました。

ブルースそしてBack to the Future

JAZZはブルースの影響を受けているのでブルースも練習しました。3コードのブルース進行。好きな映画で言うとバック・トゥ・ザ・フューチャー1でマーティが「This is a blues riff in 'B', watch me for the changes, and try and keep up, okay?」と指示するだけでバンドがチャックベリーのJohnny B. Goodeを演れてしまうシーンがあるのですが、謎が解けました。確かにコードは3つ、I・IV・Vしか使わないから弾けるんですね。


練習のスタイルを変えた

学生時代とは違ってがむしゃらに長時間練習する事が不可能になりました。自分が練習するだけでなく自分の子供の指導をする立場にもなったので効率の良い練習方法を知る必要が出てきました。ソフトウェアエンジニアに「達人プログラマー」や「エンジニアの知的生産術」といった本がある様に、演奏家向けにも同様の文献が存在します。「成功する音楽家の新習慣」という本が日々の練習方法にはじまり、本番への望み方、肉体の故障を防ぐ方法まで幅広いトピックを扱っています。
ここから実践しているのが「細かく規則正しく練習する」事です。ランチの予定が無い日は昼休みに職場の楽器エリアで練習しています。

教本は「シマンドル」長く参照されているクラシックな物を選びました。アルコ(弓弾き)前提の本ですが、ピチカート(指弾き)でも譜面は再現できます。好みの問題でしょうが、技術書の選び方に通じる物があります。

参考にしている2冊

テクノロジーの進歩を享受する

フレーズ作成の際にコード進行はiReal Proで即座に参照できるし、ソロフレーズであれば例えば「2-5-1リック」でGoogle検索すると参考になる定番フレーズが山の様にヒットします。YousicianのBassコースは音ゲーの様に五線譜が流れてくるので譜読みの練習ができます。知の高速道路が整備されている事を改めて実感しました。

楽譜と音源作成にはmusescoreを使っています。musescoreはスタンダードナンバーであれば公開されたスコアが大抵見つかるので、それを元に編集するとベースフレーズ打ちこみ用スコアがさくっと作れます。

自宅練習時の床の振動防止はロードバイクのローラー台用の防振材を流用しています。コントラバスは床に突き刺して部屋を鳴らす楽器なのでサイレント楽器といえども床が振動して他の部屋に音が伝わるからです。練習後の筋肉のケアにはマッサージガン。腕が故障すると年単位で動かせなくなるのが人生経験としてあるので入念に。使える物はとにかく使っていくスタイル。

まとめ

未知のジャンルに触れる事で音楽の幅を広げる良い機会となりました。あとは練習あるのみ。社外の演奏会にも出ていけると良いですね。


このエントリーをはてなブックマークに追加

2019-12-15

AtCoderはじめました

AtCoderというか蟻本の輪読会が社内で始まったのでこっそり若者に混じっている。

モチベーション

グラフアルゴリズムの概観とその実装の感覚を叩きこんでおきたいのがある。最近はGraph Embedding等のグラフを用いた手法によく出会うが自分の中に基礎が無いのでなかなか理解できた気にならない。自分のブログを漁ると10年前に最短経路問題をJavaScriptで解いているので、その手の活動を再開したとも言える。

進捗

以下のページを参考に、本の内容に対応するAtCoderの問題を解きつつ

まずはAtCoder過去問の4つをSubmit


テストコードが書けないコードは許しがたいのでclassにしてあるが、書いている内に depth_first_search は dfs と書きたくなるし if __name__ == "__main__": のお決まりの一文すら書くのが面倒くさくなってきた。人間は変わってしまうのか。

現状苦痛なのはコードを提出した後にRuntime Errorという結果だけが得られて、その時の入力が何だったかわからない点。仕事なら「ログを仕込んで次回に備えよう」となるがそうはいかない。比較的新しいコンテストは入力がDropboxに置いてあって安心した。

書いたコードを残すGitHubリポジトリ
https://github.com/hagino3000/study-programming-contest-challenge-book
進捗メモ
https://scrapbox.io/tnishibayashi/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%96%E3%83%83%E3%82%AF%E7%AC%AC2%E7%89%88

このエントリーをはてなブックマークに追加