Change Detection using Directional Statisticsを読んだ

方向データに対する変化点検出の論文を読んだところ、面白かったのでメモを残しておきます(論文スライド)。IJCAI2016の論文です。

異常検知は重要な領域であるにも関わらず、まだまだ枯れていなくて論文読んでて面白いものが多いですね。

問題設定

  • 多次元かつノイズの多い時系列データに対して変化点検出を行いたい
  • 実データでは、ある変数にのみノイズが乗るというより、相乗的にノイズが乗ることが多いが、そのノイズを誤検知したくない
    • 例: 同じモーターで複数のベルトコンベアが操作されているので、一緒にセンサーのノイズが乗る

確率分布の選択

  • 複数の変数に同時にノイズが乗る場合、ベクトルのノルムは大きくなるが、方向は同じ
    • こういうのは変化点ではないので無視したい
    • 1次元の時系列だけではノイズかどうか判断できる材料が少ないので、多次元を見る意味は大きい
  • こういう場合に有効なのがvon Mises-Fisher分布
    • イメージとしては超球上のガウス分布
    • ノルムの大きさは1に正規化されているので、ベクトルの方向のみを取り扱うことができる
  • 参考: 異常検知本の読書メモ Part 2(方向データの異常検知と部分空間法による変化検出) - yasuhisa’s blog

異常検知の方法

以下が基本的な考え方。

  • 学習期間とテスト期間をそれぞれvon Mises-Fisher分布でモデル化
  • 代表的な方向は一つではないので、いくつかのパターン分のモデルを作る
    • それぞれが同じものでは意味がないので、平均方向パラメータがそれぞれ直交するように制約を入れる
  • それぞれの確率分布の距離をKLダイバージェンスで取り、それを異常度とする

目的関数

  • データ毎の重み付き対数尤度 + スパースになるような正則化項
  • 学習データxは正規化されていないので、正規化済みのベクトルをz、xの元々のノルムをbとする
  • ノイズが入ったようなデータであれば重みを0にすることで、学習への影響が取り除かれるようにしたい
    • 正規化項でL1ノルムも入っているので、sparseになるようにしている
  • 平均方向ベクトルからのばらつき度合い(分散)を表わすようなパラメータΚは実は目的関数にはあまり大きな影響を与えないので、今回は定数として取り扱う
    • いい感じにΚを推定する方法もあるようだ

複数のパターンに対応できるようにする

  • システムの内部状態が一つであれば、単純な重み付き尤度の最大化でよい
    • しかし、現実はそうではない
  • 代表的な方向u_1, u_2, \cdots, u_mというm個のパターンでデータの動きがカバーできるようにしよう
    • それぞれで同じ解を出されても困るので、u_iu_jがそれぞれ直交するような制約を持たせる
  • iterative sequentialなアルゴリズムでuとwは求めることができる
    • Lassoのような形に落ち着く
    • 結構綺麗で、実装もしやすそう

異常度としてのKLダイバージェンス

  • 学習とテストの期間の長さは当然異なるので、代表的なパターンをいくつ取るかもそれぞれ異なる
    • 学習用のパターン数をm、テスト用のパターン数をrとする
  • パターン数が異なるので、線形結合で代表的なパターンを作り、KLダイバージェンスで距離を考える
    • 学習データで得られた平均方向ベクトルu_1, u_2, \cdots, u_mを束ねた行列UはM * m次元。m次元の正規化されたベクトル\mathbf{f}と線形結合
    • テストデータで得られた平均方向ベクトルv_1, v_2, \cdots, v_rを束ねた行列UはM * r次元。r次元の正規化されたベクトル\mathbf{g}と線形結合
  • KLダイバージェンスが最小になるような線形結合(\mathbf{f}\mathbf{g})の結果を使う
    • 線形結合のベクトル\mathbf{f}\mathbf{g}も正規化されているという条件を使うと、SVDの問題に落ちる
    • 異常度は最大特異値が手に入れば、簡単に計算できる
  • SDVで必要な計算オーダーはO(min(m, r)^3)なので無視できるようなオーダー
    • パターン数は現実はかなり少なくて問題ない(多くても10とかそんなもん?)

実験: Failure detection of ore belt conveyors

  • センサーによって得られた10次元の指標から変化点検出をする
  • 約40%に対応するデータの重みが0になっており、ノイズに対応するデータはモデルから自動的に除去された
  • PCAやホテリングのT2法、部分空間法(?)を使った方法よりもよいパフォーマンスを得た

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

Sparse Gaussian Markov Random Field Mixtures for Anomaly Detectionを読んだ

異常検知の一環で外れ値検知をやっていると「どの事例が外れ値か分かるだけじゃなくて、どの次元がおかしくなったかも教えて欲しい。次元数が100とかあると、どの次元がおかしい動きをしているか人手で見るのは大変」というのをちらほら聞きます。Gaussian Markov Random Field (GMRF)を使うと、どの次元の動きがおかしくなったかも異常検知の枠組みで捉えることができる場合があります。

しかし、この方法は使える状況が限定的で、システムの状態が複数ある(例: 昼と夜で負荷が違うなど)場合にはうまく機能しません。システムに複数の状態が存在することは実データでは珍しくないので、そういった状況にも対応できる方法を探していたところ、ぴったりの論文があったので読みました(ICMD 2016)。GMRFの混合分布に拡張する内容です。

混合モデルをやるときに難しいのは「混合数Kをいくつにするか?」という問題ですが、この論文では関連度自動決定の枠組みを利用することでモデルに混合数を決定させています(大きめのKを最初に与え、不必要なクラスタを潰す)。提案手法は2ステップからなっており、どちらのステップでも変分ベイズでパラメータ推定を行ないます。

  • ステップ1: GMRFのパラメータ(混合比率、平均パラメータ、分散共分散パラメータ)を求める
  • ステップ2: ステップ1で求めたGMRFのパラメータを所与とし、変数毎の重みパラメータgを求める

実データの実験(offshore iol production)でも、PCAやauto-encoderなど既存の方法よりもよい性能を出していました。オイルマネーで5000兆円欲しい!

以下、論文読み会用のメモです。提案手法の前提となるGaussian Markov Random Field/疎構造学習についても前半で簡単に紹介します。

Gaussian Markov Random Field/疎構造学習による異常検知

「どこかの変数の動きがおかしい」をどう表現するか?

  • 多変量の変数間の依存関係の崩れ、として表現する
    • 一変数だけ見ていても異常かどうかは分からない
  • 依存関係を対マルコフネットワーク(pairwise Markov network)で表わす
    • グラフィカル Lasso を用いた異常検知の12ページ
    • pairwiseなので3変数以上の相関は考えない(高次は表現も計算も大変…)
    • 変数間に関係があればネットワークにエッジがあり、関係なければエッジがない

直接相関と間接相関

  • 変数間の関係を表わす際に、直接相関と間接相関の区別をすることは重要
  • 間接相関
    • p(x_1, x_2)
    • いわゆる疑似相関
    • 身長が高ければ算数の能力も高い、ように見える
    • 教会の数と殺人事件数に関係があるように見える
    • 都市の人口数といった仲介している変数を条件付けして考えなければならない
  • 直接相関
    • p(x_1, x_2 | x_3, \cdots, x_M)
    • これを本来見たい!
    • 偏相関係数

直接相関を見るのに都合のよいツール => ガウス分布

  • 我々は直接相関を見たいので、条件付き確率p(x_1, x_2 | x_3, \cdots, x_M)も簡単になるような同時分布p(x_1, \cdots, x_M)を選びたい
  • 補足: 多変量正規分布での条件付き確率
    • PRML_2.3.1~2.3.3
    • 16ページを睨むと、Gaussian Markov random fields(GMRF)の気持ちが分かってくる

モデル化とパラメータ推定

  • データは事前に各次元で平均0、分散1に正規化しておく
  • 同時分布をp(\mathbf{x}) = N(\mathbf{x} | \mathbf{0}, \Lambda^{-1})とする
    • 精度行列\Lambdaが推定すべきパラメータ
  • 直接相関が分かるように、精度行列\Lambdaの事前分布としてラプラス分布を置く
    • ラプラス分布を事前分布として置くと、ノイズがあるようなものは0に潰してスパースにする効果がある
    • ちょっとノイズが乗っただけでも検知されると嫌なので、0に潰す
  • 精度行列の要素\Lambda_{i, j}=0のとき、x_ix_jは条件付き独立
  • 事後分布を最大にするような\LambdaをMAP推定

Gaussian Markov Random Fieldを外れ値検知として使うには?

  • ある変数についての負の対数尤度を異常度a_iと定義
  • 多次元ガウス分布なので、変数毎の異常度は簡単に計算できる
    • a_i(\mathbf{x}) = \frac{1}{2} \log \frac{2 \pi}{\Lambda_{i, i}} + \frac{1}{2 \Lambda_{i, i}} (\sum_{j=1}^M \Lambda_{i, j} x_j)^2
    • 多峰性があると容易ではなくなる

(余談)変化検知

  • スパース推定の枠組みで変化検知もできる
  • 個別に推定しても差分はスパースにならないので、直接差分を推定する必要がある
    • 密度比でやるのが自然
    • 今回紹介したい論文には関係ないのでは飛ばす

混合モデルを用いた多峰性への対応

  • やっと紹介したい論文の内容…
  • システムの状態が一つの場合、単一のMRF上のスパース推定でよい
  • しかし、定常でもシステムの状態は複数取る場合がある
    • 例: 昼間と夜間、平日と休日、歩いてるとき/走ってるとき/乗り物に乗っているとき
    • 論文の6.1. Synthetic data: illustrationなどが分かりやすい
  • Principled variable-wise scoringMixture extension of sparse structure learningを一つのモデルで両立しているのが新規性
  • 異常度a_i(\mathbf{x}) = - \log p(x_i | \mathbf{x}_{- i})はこれまでと同じで、pのモデル化が異なる
  • K個のMRF(条件付き確率)の重み付き和を考えることで状態が複数あっても大丈夫なようにする
    • 論文中の(3)式
    • 混合分布
    • クラスタの重みが変数毎になっている
  • u_i^kw_i^kが唐突に登場して、これは何だという気持ちになるけど、ガウス分布の条件付きのときのことを思い出せば大丈夫

問題になること

  • 混合数Kをどうやって決めるか
    • 大き目にKを取っておいて、最適な値はアルゴリズムに決めさせる
    • Section 4
  • ノイズが大きいデータをどう扱うか、学習を安定させるにはどうすればよいか
    • sparsity-enforcingな事前分布を入れるとよい

パラメータ推定

  • 変分ベイズで2ステップを繰り返し解く
    • 混合分布になった分、推定は複雑にはなっている
  • ステップ1: GMRFのパラメータを求める
    • Section 4
    • このステップで変数間の相関やmixture componentがスパースになるようにしている
      • 混合数Kを多めに取っていたので、いらないcomponentをつぶしていく(関連度自動決定がやってくれる)
    • 変数間の相関: グラフィカルLassoを繰り返し解く[Friedman+ 08]
      • ブロック座標勾配法かな?
    • mixture component: 点推定をすることで関連度自動決定が行なわれる(必要ないクラスタの重みは0に潰れる)
  • ステップ2: GMRFのパラメータを所与として、変数毎の重みパラメータg_k^i (\mathbf{x})を求める
    • Section 3
    • 混合モデルでは変数毎の条件付き確率を出せない?(要出展)ので、このステップで計算する

変数毎の重みパラメータの推定(Section 3)

  • 変数毎の重みパラメータg_k^i (\mathbf{x})をどう求めていくか
  • データの生成過程((7)式、(8)式、(9)式)を考えて、変分ベイズで推定
    • 生成過程はいたって普通の混合モデル
      • (7)式がvariable-wiseになっているところだけが普通と違う
    • パラメータを所与として、隠れ変数の確率分布を求める((13)式)
    • 隠れ変数を所与として、パラメータの確率分布を求める((14)式)
  • これらが求まったら、負の条件付き対数尤度が異常度として計算可能になる

GMRFのパラメータ推定(Section 4)

  • Section 3で既知として扱っていた、混合ガウスのパラメータを実際に求める
  • こちらも通常の混合モデルの生成過程と同じように組み立てる
    • 異常があった変数間の関係だけ教えて欲しいので、\Lambdaの事前分布にラプラス分布を置いて0に潰れやすいようにする
  • 混合係数\piに事前分布をおかず、点推定をすることでsparseな解が求められやすいようにしている
    • 関連度自動決定と呼ばれる仕組み
    • クラスタ数を事前に大きめにしておくと、不必要なクラスタの重みは0になって潰れてくれる
  • パラメータ/混合重みの推定は変分ベイズ。以下を繰り返す
    • パラメータを所与として、混合重みを推定((29)式、(30)式)
    • 混合重みを所与として、パラメータ推定((31)式〜(36)式)

実験

実験: Synthetic data

  • 学習: A-B-A-Bというようなパターンがあるデータ(5次元)
  • テスト: A-B-(anomaly)というパターン
  • K=7でスタートしてもきちんと2個のパターンを再現できてる
    • 他の重み係数は0に潰せている

実験: Detecting pump surge failures

  • 提案手法では正常時と異常時に正しくスコアリングできている
  • 不必要なクラスタも自動的に重みが0になって潰れている

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

異常検知と変化検知 (機械学習プロフェッショナルシリーズ)

Splatoon2やってます

発売日からやっていましたが、本職のガチエリアでやっとS+に到達(人権獲得)したので何か書きます。

f:id:syou6162:20170921130244j:plain

イカリング2、いいですね。

Splatoon1との比較

前作は結構やり込んでいたんだけど(ウデマエは大したことない…)、実はSplatoon2あまりやり込めていませんでした。要因は色々あるけど

  • インクに足を取られやすくなった
    • 敵陣に突っ込んでいって無双みたいなことはしにくくなった
  • 無敵系のスペシャルがなくなった
    • 我等がわかバリア…
  • リッターが弱くなった
    • 自分はリッター使えないけど、リッターがある程度機能しないとブキのバランスがイマイチな気がした

などがありました。自分はわかバリアで一気に打開するのが好きだったので、それに代わるものが見つけられなかったというのが大きいのかもしれない。しかし、数回のアップデートを経て、かなりいい感じに調整がされてきたなぁと感じていて、最近は結構楽しんでやり込めています。

使っているブキ

  • もみじシューター
  • ジェットスイーパー

を中心に使っていますが、8割方もみじです。基本的には味方サポート中心の引き気味の立ち回りで、一試合3kill程度というのもよくあります。その代わりスペシャル(アメフラシ)の回転数を上げていくのを意識してプレイしています。つまり、なるべく死なずに塗り重視。S以上になってくると味方も優秀になってくるので、頃合いを見計らって味方をサポートしていると勝手にkillをしてくれる。エイムがない、1vs1が弱くてもS+まではいける。S帯までは勝手に死んでいく味方も多いので、ひたすら我慢。。

もみじシュータのサブはロボットボムで、近くに敵がいたらある程度追いかけていってくれる。スプラッシュボムと比較すると、ロボットボムで直接敵を倒せることは少ない。しかし、詮索してくれるというのはでかくて、相手の場所が分かったり相手の行動を限定させられるので、擬似的に人数有利な状況を作り出すことができる。Splatoon2では、一人で無双するのが難しくなったと感じていたので、擬似的にでも人数有利の状況を作ってくれるのは大きい。サブでロボットボムを持つブキは他にもいくつかある。ロボットボムの弱点はインク消費量が多いところだけど、もみじシューターはメインの燃費がわかばと同じでかなりよい。よって、ロボットボムを投げた後にも、牽制をしたり他の場所を塗ったりする余裕が他のブキよりあるのが特に気にいっている。同じサブを持つホクサイも使っていたけど、メインの燃費があまりよくないのでボムを投げた後の動きが割と難しかった。

ギア構成を見てもらうと分かるけど、スペシャルのアメフラシにかなり特化した構成になっている。スペシャル強化も付けているので、相手からすると死なないためには今いる場所から移動しないといけない。もみじの射程では届かないチャージャーやバレルスピナー、ジェットスイーパーなど長射程ブキを固定ポジションから強制的に動かせるのが強力。アメフラシを多少くらっているので、エイムががばがばでも普通よりは倒しやすくなっている。味方と交戦している敵周辺に投げてもアシストできることも多い。ヤグラやホコの絶対死守ポジションにアメフラシを投げ込むと突破できることも多いので、使い勝手がかなりよい。今後、弱体化されてもあまり文句は言えない。

一気にkillみたいなド派手な戦い方はできなくてとにかく地味だけど、ジワジワと相手を追い込んでいく戦い方ができ、自分の性格と合っていてお気に入りです。

Splatoon 2 (スプラトゥーン2)

Splatoon 2 (スプラトゥーン2)

SlackやTwitterをWeeChat経由で使う & 自分がやっている設定

Slack、最近では色々なところで使われますね。会社用、家庭用、友人との連絡用、研究室のOBOGの連絡用…などとあれこれチームに入っているとチームの切り替えが面倒になってきます。各チームでよく使うチャンネルをひとまとめで見たい、といった要望が出てきます(あと、Slack.appが定期的に日本語入力ぶっこわれるとか)。そういったことをうまくやるために、最近はWeeChat経由でslackを使っています。SlackはIRC経由で使うことができて、WeeChatはIRCクライアントなので、slackを使うことができます。

会社では数人使っている人がいますが、世の中的にはあまり使われていないような気もするので、メリット/デメリットをまとめてみました。

メリット

  • 軽い
  • (複数のチームを横断して)よく使うチャンネルを持ってくることができる
    • 以下のチャンネルを上にまとめて持ってきています
      • 会社: チームのメインチャンネル、チームの雑談チャンネル、自分の分報、仲いい人の分報、機械学習チャンネル
      • 自宅: #general、nasneの残量通知チャンネル
      • 友人連絡用: #general、ポエムチャンネル
      • twitter: プライベートリスト
  • CLIで動くので、ターミナルから動かなくてよい
    • itermの中でEmacsとweechatを並べるといったことができる
    • itermはホットキーで一瞬で呼び出せる
  • 通知も自分の好きなようにできる
    • ハイライトの正規表現をいい感じに書いたりできる
  • atig.rbとかを使うとtwitterも一緒に見れる
  • レイアウトを自由に変えることができる
    • 4分割にして、会社のチームのチャンネルだけ大きめに表示するなど
  • キーバインドの自由度がかなり高い

デメリット

  • 画像展開などは特にされない
    • mackerelの通知のグラフなどは見たい…
    • github連携とかもまあまあ困る
  • 絵文字は脳内で展開する必要がある
  • 他人のslackのstatusは分からない
  • もちろん、slack callはweechat内では使えない
    • ブラウザで開けば使えるので、そこまで困っていない

デメリットもあるけど、致命的ではないしメリットのほうが上回ってるかなと思うので、weechat使ってます。便利です。

自分がやっている設定

特に目新しいこともないけど、参考までに自分がどういうことやっているかメモしておきます。

いくつかのチャンネルを特別扱いして上に持ってくる(便利)。

/script install chanpriority.py
/chanpriority hatena.#mackerel, hatena.#times_syou6162, twitter.#private, ...

チャンネル横断でハイライトされてるものを一覧できる(便利!)。

/script install highmon.pl

見た目や配置の設定。

/set buffers.look.indenting on
/set irc.look.server_buffer independent
/set irc.look.new_channel_position near_server
/set irc.look.new_pv_position near_server

必要ない通知を切る。

/filter add irc_smart * irc_smart_filter *

C-gで移動したいチャンネルに移動しやすくなる。チャンネルの数が100個とか越えててもさっと移動できる。

/script install go.py
/key bind ctrl-G /go

水平分割。繰り返して4分割くらいにしていることが多い。

/window splith

分割すると入力バーがいくつもできるので、入力バーを一つにまとめる。

/bar add rootinput root bottom 1 0 [buffer_name]+[input_prompt]+(away),[input_search],[input_paste],input_text
/bar del input

レイアウトの保存を自動でやる。

/set weechat.look.save_layout_on_exit all

通知関連。weechat-growlなどもあるが、pythonのライブラリの関係で苦労したので、簡単なやつを使う。使えれば何でもいいと思う。

wget https://raw.githubusercontent.com/keith/terminal-notifier-weechat/master/terminal_notifier.py ~/.weechat/python
cd ~/.weechat/python/autoload
ln -s ../terminal_notifier.py

キーワードや正規表現を書いていく。

/set weechat.look.highlight "syou6162,yasuhisa,syou"

マウスの設定。

/mouse enable

サーバーへのログインの設定。

/server add my-team my-team.irc.slack.com/6667 -autoconnect -ssl -ssl_verify=off -password=my-team.XXXXXXXXXXXXX -nicks=syou6162
/connect my-team

サーバーの順番並び替えたいときに。

/server list
/server reorder

バッファの履歴を辿る。

/key bind meta-p /window page_up
/key bind meta-n /window page_down

参考

iTerm2でAquaSKKが使えるようにhammerspoonの設定をする

OSを上げると何か動かなくなるものなので、ついつい上げることが億劫になりますね。社内の大きなイベント*1がひと段落したので、やっと重い腰を上げてOSをSierraにしました。

すでにwebに色々情報が流れてますが、karabinnerがSierraでは使えません。普段AquaSKKを使っていますが、iterm2ではC-jが改行として取られてしまい、日本語入力がまともにできません。itermではemacsを立ち上げたり、weechatでslackへの書き込みをするので、影響範囲が大きいです。karabinner-elementとhammerspoonで解決するのがよくやられている方法だったので、メモ的に書いておきます。itermでC-jが効かないので設定を書いてごまかす作戦です。

local function keyCode(key, modifiers)
   modifiers = modifiers or {}
   return function()
      hs.eventtap.event.newKeyEvent(modifiers, string.lower(key), true):post()
      hs.timer.usleep(1000)
      hs.eventtap.event.newKeyEvent(modifiers, string.lower(key), false):post()      
   end
end

local function remapKey(modifiers, key, keyCode)
   hs.hotkey.bind(modifiers, key, keyCode, nil, keyCode)
end

remapKey({'ctrl'}, 'j', keyCode('kana'))

luaは分からんので、コードは適当…。

余談

AquaSKKがitermでそのままでは使えないとなった時にGoogle日本語入力に切り替えようとしばらく頑張ってみました。しかし、自分が今、かな入力/直接入力(英数)のどちらのモードに入るのかがぱっと見で分かりづらいこと、分かったとして、変換キーがSKKと比べると打鍵が多いことが非常にストレスとなり、脱出に失敗しました…(N年ぶりM度目)。日本語のみ/英語のみの文書だと問題ないのでしょうが、両方が入り混じったものだと難しいですね。ac-mozcでモードレスとかも試してみたけど、これはこれで難しかった…。

*1:インターンなどなど

Amazon Elasticsearch Serviceでcluster_block_exceptionが出てindexに書けなくなった場合の対処法

以前、自宅のElasticsearchをAmazon Elasticsearch Serviceに移した話を書いた。

www.yasuhisay.info

データは引越しせず新規のデータをAmazon Elasticsearch Serviceに放り込んでいくようにしていた(コストをめっちゃかけないと普通に動いてくれるのかちょっと不安だったので、最初は全部入れないようにした)。半年ほど経ったが、安定して運用できていたので元々あったデータもAmazon Elasticsearch Serviceに引っ越すことにした。schema(mapping)はどちらも同じなので、移行ツールを使ってデータの引っ越しをすることにした。

nmpでインストールして、inputを自宅のElasticsearch、outputをAmazon Elasticsearch Serviceに向けて動かす。

elasticdump \
  --input=http://production.es.com:9200/my_index \
  --output=http://staging.es.com:9200/my_index \
  --type=data

元気に引っ越しが始まったようだったので安心して寝たのだが、しばらくして様子を見に行ったら新規ドキュメントの追加ができなくなっており、上述のコマンドも以下のエラーで止まっていた。

{ _index: 'twitter_public_timeline',
  _type: 'tweet',
  _id: '841830783106990100',
  status: 403,
  error:
   { type: 'cluster_block_exception',
     reason: 'blocked by: [FORBIDDEN/8/index write (api)];' } }

cloudwatchに様子を見にいくと、disk fullになっており、やっちまったなーと思いながら不必要そうなドキュメントを削除。しかし、削除も403で怒られる…。調べてみるとどうやらディスクを増やすしかないようだ。

AWSのコンソールからEBS ボリュームサイズを35まで引き上げた(無料からは足が出る)。しばらくするとFreeStrageSpaceも0から余裕ができて、削除や新規のドキュメントの追加ができるようになった。AWSを普段から使っている人には慣れた操作かもしれないが、自分がメインで使っているサービスでなったのは初めてだったので、「なるほど、これが金の力で殴るってやつか」と妙な納得感が得られた。

雑なpythonスクリプトやjupyter notebookをdockerを使って動かす

気が付いたら三ヶ月ぶりのブログだった…。

きちんとした用途ならpyenv等を使って、きちんとpythonのversionを指定、使うライブラリも列挙というのをディレクトリ毎にやっていくようになりました。しかし、pythonを使いたいときはきちんとした用途だけではなく

  • 雑にスクレイピングしたい
  • 一度しかやらないようなテキスト処理をしたい
  • 後々使うか分からないけど、手元にあるtsvファイルをjupyter notebookでデータ解析したい

など、アドホックな用途も多いです。そういうときに毎回ライブラリをインストールして…とやるのはダルいので、上述のような用途で自分が使いそうなものをdockerにまとめておけば、さっと用事を済ませられるのではないかと思ってやってみました(N番煎じなのは分かってる)。

Docker、仕事ではすでに誰かが作ってくれているイメージをdocker runする程度しかやっていなかったのですが、意外と(自分にとって必要な)Dockerfileを書くのは簡単だということが分かってよかったです。