中野智文のブログ

データ・マエショリスト(※データ・マエストロではない)のメモ

Julia の GaussianProcesses を jupyter notebook で表示する

背景

そろそろ jupyter notebook を使いたくなってきた。

前回、Gaussian Processes のライブラリを入れるところまではできたので(下記参照) nakano-tomofumi.hatenablog.com

今回は、jupyter notebook 上でグラフを表示するところまでやってみる。

IJulia インストー

申し訳ない。既にインストール済みだったのか、さっくりできた。

julia> Pkg.add("IJulia")
julia> Pkg.update()
julia> using IJulia
julia> notebook()

jupyter 上で GaussianProcesses ライブラリを使う。

以下は jupyter notebook 上での実行の話。

using GaussianProcesses

INFO: Recompiling stale cache file /Users/nakanotomofumi/.julia/lib/v0.5/Optim.ji for module Optim.

LoadError: ArgumentError: Module Klara not found in current path.
Run `Pkg.add("Klara")` to install the Klara package.
while loading /Users/nakanotomofumi/.julia/v0.5/GaussianProcesses/src/GaussianProcesses.jl, in expression starting on line 2

もしかしてパスの問題かもしれないが、素直に入れてみる。

Pkg.add("Klara")

問題なく入った。

本家のReadme.md が変更されている。

よく読むと、jupyter notebook へ移ったとある。つい最近変更したようだ。 なるほど、前回の例は、何が実行コマンドで何が出力か分かりにくかった。 しかしjupyter notebookへのリンクをクリックしても、当該ファイルへは飛ばない…

どうやら、下記らしい。

github.com

あとはこの通りに実行して…。

pyplot の場所でエラーが…。あれ?本家の jupyter notebookもエラーだし…。

エラーでなくなってからマージして欲しい…。

BigQuery のスキーマを bq コマンドで使う形式で表示する jq

背景

ある日の空テーブルを作成しようとしたが、スキーマの文字列が必要になった。手作業だとミスが起こるから、コマンドが欲しい。

jq コマンド

スキーマ文字列を取得

$ bq show --format prettyjson <既存のBQのテーブル名> | jq -r '.schema[] | map(.name+":"+.type) | join(",")

一気に空テーブル作成

$ bq mk --schema `bq show --format prettyjson <既存のBQのテーブル名> | jq -r '.schema[] | map(.name+":"+.type) | join(",")'` -t <空のBQのテーブル名>

Julia の GaussianProcesses のライブラリを入れようとする (2)

前回はこちら

nakano-tomofumi.hatenablog.com

Optim の仕様変更への対応

問題のエラーは、次のようなもの

julia> optimize!(gp)
ERROR: MethodError: no method matching set_params!(::GaussianProcesses.GP, ::Float64; noise=true, mean=true, kern=true)
Closest candidates are:
  set_params!(::GaussianProcesses.GP, ::Array{Float64,1}; noise, mean, kern) at /Users/xxxxx/.julia/v0.5/GaussianProcesses/src/GP.jl:275
  set_params!{K<:GaussianProcesses.Kernel}(::GaussianProcesses.Masked{K<:GaussianProcesses.Kernel}, ::Any) at /Users/xxxxxx/.julia/v0.5/GaussianProcesses/src/kernels/masked_kernel.jl:55 got unsupported keyword arguments "noise", "mean", "kern"

これに対して、既に修正が行われている模様:

github.com

そして実行。

julia> Pkg.checkout("GaussianProcesses")
INFO: Checking out GaussianProcesses master...
INFO: Pulling GaussianProcesses latest master...
INFO: No packages to install, update or remove

おや?変化なし。

パッケージが最新版を見ていない模様。

julia> Pkg.status()
4 required packages:
 - GaussianProcesses             0.4.0+             master

statusを見ると、master を見ていることになっている。再コンパイルが必要?

最新のブランチを反映させる方法を知らないため、一旦 exit() し、再び julia を起動し、using で呼び出し。

次は、plot(gp) でエラーだ。

なので、 一旦、Pkg.free("GaussianProcesses") で元に戻す。

そして、再び exit して、その後、Pkg.checkout("GaussianProcesses") を実行。

plot(gp) でエラー出ず。

f:id:nakano-tomofumi:20170710191518p:plain

そして、

julia> optimize!(gp)
Results of Optimization Algorithm
 * Algorithm: Conjugate Gradient
 * Starting Point: [-1.0,0.0,0.0,0.0]
 * Minimizer: [-3.506712993556627,-0.080606913136668, ...]
 * Minimum: -3.600592e+00
 * Iterations: 19
 * Convergence: false
   * |x - x'| < 1.0e-32: false
   * |f(x) - f(x')| / |f(x)| < 1.0e-32: false
   * |g(x)| < 1.0e-08: false
   * f(x) > f(x'): true
   * Reached Maximum Number of Iterations: false
 * Objective Function Calls: 69
 * Gradient Calls: 50

キタ━━━━(゚∀゚)━━━━!!

f:id:nakano-tomofumi:20170710191527p:plain

まとめ

一応、Juliaのライブラリ GaussianProcesses で超パラメータの最適化は出来た。 しかし、他のライブラリ(Optim)の勝手なバージョンアップ等もあって、うまく動くことは保証されない。 今後も勝手なバージョンアップがありそうだから、ビジネス用途には全く向いていない。あくまで遊び(教育用途)レベルにとどめておくべき。

Julia の GaussianProcesses のライブラリを入れようとする

背景

連続腕バンディット(それもトンプソンサンプリング)をやってみようと思った。 ベルヌーイ分布のトンプソンサンプリングは、ベータ分布の乱数生成だけが肝だが、ライブラリを使ったり、最悪Cの関数を参考にしながら自分で実装すれば特に問題はない。 ところが、ガウス過程の乱数生成は、まずガウス過程の分布を計算するのが一苦労なのと、その分布から乱数を生成する必要があり、またこれも面倒である可能性がある。 とりあえず、フォン・ノイマンの棄却法とか、分布さえ求められればなんとかなりそうな気配はあるので、ガウス過程の分布を求めるところからスタートする。

Julia の GaussianProcesses のライブラリを入れる。

なぜ Julia かといえば、特に理由はないが、python はすでに多くやられていて、特に問題なくインストールとかできそうだから。

github.com

早速、README.md どおりインストールを開始する。

julia> Pkg.add("GaussianProcesses")
INFO: Cloning cache of Distances from https://github.com/JuliaStats/Distances.jl.git
INFO: Cloning cache of GaussianProcesses from https://github.com/STOR-i/GaussianProcesses.jl.git
INFO: Cloning cache of LineSearches from https://github.com/JuliaNLSolvers/LineSearches.jl.git
INFO: Cloning cache of Optim from https://github.com/JuliaNLSolvers/Optim.jl.git
INFO: Cloning cache of PositiveFactorizations from https://github.com/timholy/PositiveFactorizations.jl.git
INFO: Cloning cache of ScikitLearnBase from https://github.com/cstjean/ScikitLearnBase.jl.git
INFO: Installing Distances v0.4.1
INFO: Installing GaussianProcesses v0.4.0
INFO: Installing LineSearches v0.1.5
INFO: Installing Optim v0.7.8
INFO: Installing PositiveFactorizations v0.0.4
INFO: Installing ScikitLearnBase v0.3.0
INFO: Package database updated
INFO: METADATA is out-of-date — you may not have the latest version of GaussianProcesses
INFO: Use `Pkg.update()` to get the latest versions of your packages

julia> Pkg.update()
INFO: Updating METADATA...
INFO: Updating cache of Combinatorics...
INFO: Updating cache of StatsBase...
INFO: Updating cache of Roots...
INFO: Updating cache of PolynomialFactors...
INFO: Updating cache of Distributions...
INFO: Updating cache of Rmath...
INFO: Updating cache of Compat...
INFO: Updating cache of PDMats...
INFO: Computing changes...
INFO: Cloning cache of IterTools from https://github.com/JuliaCollections/IterTools.jl.git
INFO: Upgrading Combinatorics: v0.4.0 => v0.4.1
INFO: Upgrading Compat: v0.25.2 => v0.26.0
INFO: Installing IterTools v0.1.0
INFO: Upgrading PDMats: v0.6.0 => v0.7.0
INFO: Upgrading Rmath: v0.1.6 => v0.1.7
INFO: Upgrading Roots: v0.3.1 => v0.4.0
INFO: Upgrading StatsBase: v0.15.0 => v0.17.0
INFO: Removing Iterators v0.3.1
INFO: Removing PolynomialFactors v0.0.5
INFO: Removing Primes v0.1.3
INFO: Building Rmath

ちょっと GaussianProcesses は古いとでた。

ではヘルプを見てみよう。

julia>

help?> GP
search: get_bigfloat_precision gperm CachingPool log1p logspace getpid graphemes isgraph getipaddr set_bigfloat_precision with_bigfloat_precision

Couldn't find GP
Perhaps you meant gc, !, !=, $, %, &, *, +, -, .%, .*, .+, .-, ./, .<, .>, .\, .^, .÷, .≠, .≤, .≥, /, //, :, <, <:, <<, <=, ==, =>, >, >=, >>, I, \, ^, cd, cp, e, eu, fd, im, in, lq, lu, mv, pi, qr, rm, |, |>, ~, ×, ÷, γ, π, φ, ∈, ∉, ∋, ∌, √, ∛, ∩, ∪, ≈, ≉, ≠, ≡, ≢ or ≤
  No documentation found.

  Binding GP does not exist.

おっと、いきなりこれか。using してないからじゃないの?

julia> using GaussianProcesses
INFO: Precompiling module Optim.
INFO: Recompiling stale cache file /Users/xxxxxx/.julia/lib/v0.5/PDMats.ji for module PDMats.
INFO: Precompiling module Distances.
INFO: Precompiling module ScikitLearnBase.

したら、

help?> GP
search: get_bigfloat_precision GP gperm CachingPool log1p logspace getpid graphemes isgraph getipaddr GaussianProcesses set_bigfloat_precision with_bigfloat_precision
...

でるじゃん。

サンプルを試す。

julia> using PyPlot, GaussianProcesses
ERROR: ArgumentError: Module PyPlot not found in current path.
Run `Pkg.add("PyPlot")` to install the PyPlot package.
 in require(::Symbol) at ./loading.jl:365
 in require(::Symbol) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?

やはり。

julia> Pkg.add("PyPlot")
....

うーん、conda とか、numpy とかがインストールされていくのを見ると、julia でやっている意味はあるのかって一瞬思う。 (一瞬だったが)

その後 README.md にあるコマンドを順に実行する。

次は出力なので気をつける。

  Dim = 1
...
julia> plot(gp)

f:id:nakano-tomofumi:20170707171604p:plain

それっぽいのが出てきた。

カーネル関数の超パラメータの調整

カーネル関数には事前にセットされた数々の超パラメータがある。この超パラメータを調整する方法として、第二種の最尤推定法とよばれる方法がある。 PRML本だと、ガウス過程の第二種の最尤推定法は「6.4.3 超パラメータの学習」で触れられている。

では、この超パラメータの調整をREAEME.mdどおり optimize!(gp) で行ってみよう。

julia> optimize!(gp)   #Optimise the hyperparameters
WARNING: DifferentiableFunction(args...) is deprecated, use OnceDifferentiable(args...) instead.
 in depwarn(::String, ::Symbol) at ./deprecated.jl:64
 in DifferentiableFunction(::Function, ::Vararg{Function,N}) at ./deprecated.jl:50
 in #get_optim_target#20(::Bool, ::Bool, ::Bool, ::Function, ::GaussianProcesses.GP) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/optimize.jl:74
 in (::GaussianProcesses.#kw##get_optim_target)(::Array{Any,1}, ::GaussianProcesses.#get_optim_target, ::GaussianProcesses.GP) at ./<missing>:0
 in #optimize!#19(::Bool, ::Bool, ::Bool, ::Optim.ConjugateGradient{Void,Optim.##29#31,LineSearches.#hagerzhang!}, ::Array{Any,1}, ::Function, ::GaussianProcesses.GP) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/optimize.jl:17
 in optimize!(::GaussianProcesses.GP) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/optimize.jl:17
 in eval(::Module, ::Any) at ./boot.jl:234
 in eval(::Module, ::Any) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
 in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
 in macro expansion at ./REPL.jl:95 [inlined]
 in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68
while loading no file, in expression starting on line 0
ERROR: MethodError: no method matching set_params!(::GaussianProcesses.GP, ::Float64; noise=true, mean=true, kern=true)
Closest candidates are:
  set_params!(::GaussianProcesses.GP, ::Array{Float64,1}; noise, mean, kern) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/GP.jl:275
  set_params!{K<:GaussianProcesses.Kernel}(::GaussianProcesses.Masked{K<:GaussianProcesses.Kernel}, ::Any) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/kernels/masked_kernel.jl:55 got unsupported keyword arguments "noise", "mean", "kern"
 in #optimize!#19(::Bool, ::Bool, ::Bool, ::Optim.ConjugateGradient{Void,Optim.##29#31,LineSearches.#hagerzhang!}, ::Array{Any,1}, ::Function, ::GaussianProcesses.GP) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/optimize.jl:20
 in optimize!(::GaussianProcesses.GP) at /Users/XXXX/.julia/v0.5/GaussianProcesses/src/optimize.jl:17

グフ… 色々古いのか。次回以降に続く。

nakano-tomofumi.hatenablog.com

mac の gimp から印刷

背景

証明書写真を印刷したい。1mm もサイズが違わないように印刷したい。

結論

macgimp から印刷はうまくいかない。一旦、jpeg にして、jpegmac の previewer で詳細な印刷設定をしてうまくいく。

印刷前までの方法

ほぼ、下記の通り

fanblogs.jp

ただし事前に次のようなプロセスがあった。

背景にできる影

壁までの距離が近いと、本人の影ができる。 だから、壁までの距離がそれなり(3m)にある場所を選んだ。

縦撮り

横にしても横が無駄に広いばかりか、上と下が規定のサイズに収まらないことが過去にあった。証明写真は縦向きなんだから縦撮り。

フラッシュ

フラッシュは使ったが、手で遮って、反射光を天井に当てるようにした。ビルトインのフラッシュじゃなければ特にこのあたりのテクニックは必要なさそう。

切り抜き

証明写真を加工する前に、始めに証明写真のサイズに切り抜きたい。なぜなら、切り抜きの段階で写真が不適切なことがわかることもあるから。 自分はpicasa を利用しているので picasa で切り抜きを証明写真のサイズのカスタムアスペクト比を先に作ってから、目視 で切り抜き。

gimp での加工

背景の処理

背景はオフホワイトとかでもNGで完全な白が必要らしい。そこで背景を選択し、白にした。

レンジの調整

これは

上記のページのように、写真を入れる。

既にサイズ通りの比になっているので特に難しいことは無いはず。

背景に grid を書く。

背景が白だと、どこを切ったらいいかわからない。トンボを入れると、ぎりだと写真の中に線が入ってしまう。 無難そうな水色の格子を背景に作った。

https://docs.gimp.org/ja/plug-in-grid.html

gimp での印刷

何度やってもうまくいかない。そもそも後部トレーの紙を給紙しなくてはいけないのに、普通紙を給紙してくる。馬鹿か。 そして、結論の方法を試し、やっと印刷できた。

トラフィックエクスチェンジの闇

背景

ad fraud を追う間に、「トラフィックエクスチェンジ」というサービスを知ることになった。

トラフィックエクスチェンジとは、サイト間でユーザを交換しようという試みである。 まだ検索エンジンがあまり発展していなかった時代などは、サイト間のリンクのみが唯一自分のサイトに訪れてもらえる方法だった。 そのようなときに相互リンクをはることで、お互いのページを行き来できるようになる。 相互リンクを貼る場合、お互いにメールや掲示板を利用して連絡をする必要がある。

トラフィックエクスチェンジのシステムはそのような背景があって、登録しておけば別の登録サイトにランダムにジャンプしてくれるツールだった。

トラフィックエクスチェンジの闇

検索エンジンSNSが発達した今、それは全く別物になっている。 詳しくは下記のページを御覧いただきたい。

https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%81%E3%82%A7%E3%83%B3%E3%82%B8

トラフィックをやり取りすることで、将来的に換金可能なポイントがもらえるシステムになっている。 それも自動的に別サイトに遷移する仕組みになっていて、人間が不在でも時間が経てばどんどんポイントがたまるのだ。

こういう本もあるくらいだから、

初めから自動化されているのは、本当に素晴らしいことだと思う。 人間不在でページが遷移することになんの意味があるかわからないが、その自動化まですでに仕込んであるのは、素晴らしいとことだと思う。

ところが、Web広告を出す側にとっては大きな問題だ。人間が見ていない広告に価値はない。

トラフィックエクスチェンジを行っている方へお願い。

adblock を入れてください。

Chromeこちhttps://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwjyiJb7r-XUAhWDerwKHc3CCi0QFgguMAE&url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fadblock-plus%2Fcfhdojbkjhnklbpkdaibdccddilifddb%3Fhl%3Dja&usg=AFQjCNHqQbwfsSRVUqnfKN4MDGPo2VCs5g

Firefoxこちhttps://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwjyiJb7r-XUAhWDerwKHc3CCi0QFgg1MAI&url=https%3A%2F%2Faddons.mozilla.org%2Fja%2Ffirefox%2Faddon%2Fadblock-plus%2F%3Fsrc%3Dhp-dl-mostpopular&usg=AFQjCNGhrDoOldicKhr0a9YJbDWgsfvO8g

29戦中29連勝の勝率の信頼区間を求める

背景

仕事でどうしても必要になった(嘘)

Wilson score interval で計算する。

早速だけど、下記の式を使ってみよう。

nakano-tomofumi.hatenablog.com

今回は、p = 0.05 で求める。標準正規分布の分位数はZ=1.96となる。

よって、

UCB: (29+1.96*1.96/2+1.96*sqrt(29*(29-29)/29+1.96*1.96/4))/(29+1.96*1.96)
LCB: (29+1.96*1.96/2-1.96*sqrt(29*(29-29)/29+1.96*1.96/4))/(29+1.96*1.96)

これを python でそれぞれ求める。

$ python
>>> import math
>>> (29+1.96*1.96/2+1.96*math.sqrt(29*(29-29)/29+1.96*1.96/4))/(29+1.96*1.96)
1.0
>>> (29+1.96*1.96/2-1.96*math.sqrt(29*(29-29)/29+1.96*1.96/4))/(29+1.96*1.96)
0.8830264055344441
>>>

勝率は 88.3%から100%(p=0.05)となった。

結論

勝率は 88.3%から100%(p=0.05)

信頼上限より大きくないから、片側の信頼区間は両側の信頼区間と同じである。

勝率は 88.3%以上(p=0.025)

でもいいかもしれない。