うまい寿司が食いたい。

うまい寿司が遠慮なく食べれるようになるまで,進捗とか垂れ流すブログ

google cloud platform はじめました。with 競馬のデータセット取得

動機・概要

手元のマシンスペックがあまり良くないため(下図),計算などを行うとフィンが大変なことになります。

f:id:Leo0523:20180816174148p:plain

先日twitterでそのことをボヤいていたら,「クラウドは使わないのか?」「クラウドを使うべきだ」と言われたので,とりあえず使ってみました。
GCPを使う目的は競馬のデータセットを取得することなのですが,以前に書かれたコードのscalaバージョンが古く,現在のバージョンに対応していませんでした。その点に関しても書いておきます。

目的

最終的に機械学習による競馬予測を行おうとしているので,データセットgoogle cloud platform上で取得することを目的としています。
競馬のデータセットを取得するコードは,

stockedge.hatenablog.com

こちらの方がscalaで書かれていたので,これを利用します。

GCPインスタンスの立ち上げ

適当に初心者ガイドを参照して立ち上げました。理屈はおいおい理解します。

www.topgate.co.jp

f:id:Leo0523:20180822212847p:plain

こんな感じにポチポチ選んでいくとインスタンスができます。思っていたよりもずっと簡単でした。
国によって値段が微妙に違うのを見て楽しむぐらいでした。

以前にnardtreeさんが

とつぶやいていたので,Debianを選んでみました。いまいち違いはわかっていません。

そんなこんなで,GCPインスタンスが立ち上がり,ターミナルを立ち上げることができました。

競馬のデータセットを取得する。

スクレイピングするコードは

github.com

にあるようにscalaで書かれていました。
一切触ったことがなかったので,とりあえず,

git clone https://github.com/stockedge/netkeiba-scraper

を行った後に,実行コマンドである

sbt "run collecturl"

をそのまま打ち込むと,「sbtのコマンドが無い」というエラーがでたため,

sbt Reference Manual — Linux への sbt のインストール

にてインストールを行いました。
再び,

sbt "run collecturl"

を実行しようとすると

  • scalikejdbcの2.0.7に対応していない。
  • xml関連の機能は現在のバージョンでは廃止された。参照

というエラーが出たため,いろいろ調べていると,この2つはbuild.sbt

libraryDependencies ++= Seq(
  "org.scalikejdbc" %% "scalikejdbc"       % "2.0.7",
  "ch.qos.logback"  %  "logback-classic"   % "1.1.2"
)

libraryDependencies ++= Seq(  
   "org.scala-lang.modules" %% "scala-xml" % "1.1.0",
   "org.scalikejdbc" %% "scalikejdbc"       % "2.5.3",
   "ch.qos.logback"  %  "logback-classic"   % "1.1.2"
 )

と書き換えることで,意図通り動かすことができました。

f:id:Leo0523:20180822215524p:plain

pull requestも一応送っていますので,製作者様,もし見ていればマージお願いします。
プリリクも初めて送ったので大変緊張しました。

まとめ・今回やったこと

  • GCPインスタンスを初めて立ち上げた。
  • scalaに初めて触った。
  • scalaのライブラリのimportする方法をしった。
  • プルリクを初めてやってみた。

です。

【備忘録】機械学習の環境構築のためのDockerの記事たち

概要

Dockerで機械学習の環境を構築して記事にしようと思ったんですが,私が書くよりも素晴らしい解説記事がたくさんあったので,今後参考にできそうなものをまとめました。

Dockerそのもの,DockerfileやDocker-composeについて

とりあえず公式

docs.docker.com

概要がわかってイメージがついた記事

qiita.com

dockerfile

書き方とコマンド

qiita.com

チートシート

qiita.com

qiita.com

機械学習関係のリンク

Jupyterの公式を見ていると,python3での機械学習のnotebookを起動するためのdockerの最小構成は

docker pull jupyter/scipy-notebook

でイメージを取ってくるのが良さそう。tensorflowを含めるなら,

docker pull jupyter/tensorflow-notebook

が良さそうです。

他に参考にした記事とか。

notebookをブラウザで起動してくれるところまで書いているので,便利。

qiita.com

実例を交えながら,機械学習用に作ったコンテナがある。

catindog.hatenablog.com

JupyterLabをnotebookに追加したもの。

qiita.com

うちの低スペックパソコンだとdocker Engineを入れるだけで火を吹きそうなので,もっと高いスペックのパソコンにな(ることがあ)れば,利用を検討します。

入力信号を正弦波にしたときのカルマンフィルタによる予測

カルマンフィルタって何?

一言でまとめると,正規分布した観測ノイズを乗った情報から,ノイズを除去し状態の真値を推定する方法です。
応用例はいろいろあるのですが,

  • カーナビ
  • ロケットの軌道推定

なんかに使われているようです。

この記事は何でないのか?

カルマンフィルタの内容や式の解説などはありません。
それらは,下段の参考文献を見てください。

今回のこの記事では何をするのか?

ランダムウォークを入力信号として,観測ノイズを除去するカルマンフィルタは実装されているはありました。
しかしながら,例えば入力信号が正弦波のような波形であるときにノイズを除去する例は見られなかったので,今回試してみました。

状態空間と実際の系

状態空間と観測空間が同一であるようなモデルを考えます。つまり,
{ \displaystyle
x_M(t) =x_M(t-1)+u(t)
}
{ \displaystyle
y(t) =x_M(t)
}

のモデルを考えます。ここで,x(t)は真値でy(t)は観測値で,u(t)が入力信号になります。
実際には入力信号のノイズや,観測のノイズがかかるため上の式は

{ \displaystyle
x_t(t) =x_t(t-1)+u(t)+\varepsilon(t)
}
{ \displaystyle
y_o(t) =x_t(t)+\delta(t)
}

となります。\varepsilon(t)\delta(t)ガウス分布に従うノイズです。
カルマンフィルタで求めたい値はこのx_{t}(t)です。

状態空間モデルが立っているんだから,それが真値ではないかと一度思ったのですが,x_M \neq x_{t}であるため,入力信号のノイズが少しずつ重なっていき次第にずれていくのでx_M(t)理想ではありますが,求めたい真値ではありません。

カルマンフィルタの式

このページを参考にしました(下の参考文献3です)。

最終的に求めたい式としては,

{\displaystyle
x_{kf}(t) = (1-K)x_M' (t)+K y_o(t)
}

です。ここでx_{kf}(t)はカルマンフィルタによる予測値,x_M'(t)状態空間による予測値,y_o(t)は実測値です。つまり,予測値と実測値のどちらにより重きを置くのかをカルマンゲインKを用いて計算しています。詳細は上記の参考文献にまかせて,実際にこの式を利用して計算してみます。

正弦波を入力にしてみる。

{\displaystyle
u(t)=\sin(t)
} と仮定しました。このときに,カルマンフィルタを利用して計算をしてみると,

f:id:Leo0523:20180729144151p:plain

このような結果が得られました。ここで,横軸はステップ数で,縦軸はそれぞれでの値になります。
青が観測ノイズが乗っているもの,緑が観測ノイズがない場合の値です。そして,黄色がカルマンフィルタによってノイズを除去したときの予測値になります。
計算条件としては,モデルのノイズによる偏差\sigma_x=1,観測ノイズによる偏差が\sigma_z=10としています。
正弦波を入力としても,観測ノイズを除去して真値をかなりの精度で予測できることがわかりました。

実験的にモデルのノイズを大きくして\sigma_x=10,観測ノイズを小さくすると\sigma_z=1

f:id:Leo0523:20180729144856p:plain

このような結果が得られました。 これは,観測ノイズがモデルノイズに比べてほとんどありませんので,ほぼ観測値が真値に一致していることが原因だと考えられます。

最後にモデルノイズと観測ノイズが同じとき\sigma_x=\sigma_z=5を試してみました。 f:id:Leo0523:20180729145343p:plain あまり良い予測とは言えません。

この結果を見る限り,なんとなくどこか間違ってそうな気がするので,間違いに気づけば訂正いたします。

今回利用したコードはこちらです。

github.com

まとめ

正弦波を入力信号として,カルマンフィルタを用いて真値予測を実行してみました。
今回の実験によって,観測ノイズの分散>入力ノイズの分散のときには利用できそうであることがわかりました。
入力ノイズのほうが大きい場合には,観測信号がほぼ真値であるため,そもそもカルマンフィルタを利用する必要がありません。
また,分散が同程度である場合には,予測精度がよいとは言えませんでした。

参考資料

今回,記事を書くにあたって以下の資料を参考にしました。

まず,簡単な理解のために,一次元モデルについて調べていました。

参考文献 1 qiita.com

参考文献 2 qiita.com

このあたりでざっくりとした理解を得て,

参考文献 3 hamachannel.hatenablog.com

で,数式の理解を行いました。

また,実際に実装して試している例として,

参考文献 4 qiita.com

があります。ここでは,ランダムウォークに対してカルマンフィルタを適応しています。

また,多次元まで拡張したカルマンフィルタや,他の信号処理のモデルの比較など細かい部分まで触れられているのは,

参考文献 5 九州工業大学西田健先生の講義資料

http://lab.cntl.kyutech.ac.jp/~nishida/lecture/psc/no5.pdf

が参考になりました。探していた中で一番わかりやすかった気がしています。

lab.cntl.kyutech.ac.jp

先生のホームページ上から,すべての講義資料にアクセスできるようなので,他の信号処理のモデルとの比較に良さそうです。

FORM -first order reliability method- 近似的に公差解析を行う方法 ① 導入 FORMって何?

公差解析の方法の一つFORM (First Order Reliability Method)について記載します。
FORMは公差解析なのですが,使う数学が機械学習最急降下法に似ています。
また,FORMについては日本語の記事をほとんど見つけられなかったので,自分の勉強を兼ねてまとめておきます。間違いがあればガンガン指摘してください。

公差って何?

我々の身の回りのもの,例えば定規でもパソコンでもスマートフォンでもなんでも,出来上がったものを測ってみると設計値から少しだけズレて,ばらつきがでます。
f:id:Leo0523:20180702212847j:plain


このばらつきのことを公差といい,図1のように正規分布がよく書かれます。

例えば,設計値が15mmとすると,公差を含めた書き方は 15\pm0.5です。
設計図にこう書くことで,0.5mmのばらつきは許容しますよ〜ということを実際に作る人にわかるようにします。
ばらつきをどこまで無くすのかで作成物の値段が変わってくる(加工精度にお金がかかる)ので,設計者はばらつきをどこまで広げていいのか考えます。
それでも,カメラのレンズのようなズレをほとんど許さないようなものは,厳しい公差を決めて値段を上げます。

では,どのようにして公差を決めるのでしょうか?

公差解析

公差を決める手段として,公差解析というものがあります。
最も悪くなる場合の積み重ねを考えることや,分散の加法性から平方二乗和を取る方法などが一般的によく知られています(例:ここここ

評価対象が寸法公差のみを考える場合にはこれらの手法は有効ですが,カメラのレンズの公差が照射される光にどの程度影響を及ぼすのかを評価する場合にはあまり有効ではありません。
複数のレンズの公差の積み重ねによって,最終的な光学性能は決定されるため,寸法とはあまり関係がありません。
そのため,商品として売られているシミュレータに付属している公差解析では統計的な手段が取られます。(例:サイバネットのページより, 光学シミュレータソフトOSLO) このような統計解析では公差の確率分布を定めて,分布に従った数値を生成します。
確率分布に従う数値を生成する方法として,ラテン超方格法やモンテカルロ法があります。

これらは多次元データからのデータサンプリングの手法で,最適化などでよく使われています。それぞれの特徴は,

があります。前者は少し頭を使ってデータを選んでいて,後者のほうが力技で想像しやすいかと思います。
これらを利用して何千・何百と繰り返し計算を行って故障率を計算するのが,統計的な手法となります。

とは言え,これら2つの方法は,公差のばらつきの範囲のパラメータを虱潰しにすべて検証して,問題ある・なしを判別するため,設計空間が大きくなればなるほど計算コストが莫大になることが想像できます。
そこで,計算のコストを削減する,という目的で導入されたのがFirst Order Reliability Method( FORM )になります。

前置きが長くなりましたが,ここからがFORMでの計算方法となります。今後は,こちらのノートの和訳を掲載していきます。英語が読める方はそちらを読めばいいかと思います。