retrofocus’s blog

Compressed Sensingの勉強

SVMの使い方

当たり前のように「SVMで分類しました-」と言えるようになりたい。
そんな人のためにPractical Guide to SVMなんてものがある。
http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

日本語の概要はd.hatena.ne.jp

先に日本語のスライドを読んでから原文を当たると素早く理解できる。
今回はおすすめ手順を踏んでSVMを使ってみたい。

使用するのはお馴染みscikit-learn。
データは手書き数字認識を行ってみる。

0.サンプルデータの読み込み

from sklearn import datasets
digits = datasets.load_digits()

data = digits.data
target = digits.target

1. クラスラベルをつける。

元論文では{red, green, blue} を (0,0,1), (0,1,0), (1,0,0)とラベル付けしろと書いてある。
scikit-learnではSVCとNuSVCでは自動でそうしてくれる。よって上記のtargetをそのまま使えばよい。
1.4. Support Vector Machines — scikit-learn 0.16.1 documentation

2. データのスケーリング

特徴量ごとにスケーリングする。今回の場合は特徴量が画素値だが、たとえば、身長と体重なんか違う指標のものを比べたりする場合に単位が違う効果を打ち消す必要がある。
今回は標準化(平均0、標準偏差1)を行う。調べてみるとscikit-learnにあった。
4.3. Preprocessing data — scikit-learn 0.16.1 documentation

from sklearn import preprocessing
scaled = preprocessing.scale(data)

3. カーネルにはRBFを使う。

scikit-learnのSVCはデフォルトでRBFを使うようになっている。呼び出し時に指定すればよい。
(SVCのCはClassificationのCらしい。回帰の場合はRになる)

4. Cross-validationとグリッド探索してパラメータであるCとγを決定する。

これもすでに実装されている。
sklearn.grid_search.GridSearchCV — scikit-learn 0.16.1 documentation

論文では例としてC=[2^-5, ..., 2^15], γ=[2^-15, ..., 2^3]いるのでそれを使ってみる。

from sklearn import svm, grid_search
parameters = {'C':np.logspace(-5, 15, 21, base=2), 'gamma':np.logspace(-15, 3, 19, base=2)}
svc = svm.SVC(kernel='rbf')
gridcv = grid_search.GridSearchCV(svc, parameters, cv=5, verbose=1, n_jobs=4)
gridcv.fit(scaled_data, target)

cvがサンプルを何分割するか、verboseで途中経過の表示をコントロールできる。

可視化ツールはついていないので自分で作成する。

means = np.array([s[1] for s in gridcv.grid_scores_]).reshape(len(c_range), len(g_range))

plt.xscale('log')
plt.yscale('log')
plt.imshow(means, extent=[g_range[0], g_range[-1], c_range[0], c_range[-1]], interpolation='none')
print(gridcv.best_params_)
print(gridcv.best_score_)

f:id:retrofocus:20150502102202p:plain

ちょっとわかりにくいけど、ベスト結果のパラメータ{'C': 32.0, 'gamma': 0.0078125} scoreは0.959となった。絵は真っ赤でわかりにくいけど、一様真ん中あたりにピークがありそうなので、細かい探索をする。
すると、
{'C': 10.947368421052632, 'gamma': 0.0069901315789473685}
0.959376739009

まぁ今回はあまり変わらず。

5.最後に最適化したCとγで学習データ全体を使って学習させる。

c_best = gridcv.best_params_["C"]
g_best = gridcv.best_params_["gamma"]
svc = svm.SVC(kernel='rbf', C=c_best, gamma=g_best)
svc.fit(scaled_data, target)

これでお手軽SVMの完成である。
scikit-learnを使うと楽勝ですね。

サポートベクターマシン入門

サポートベクターマシン入門

2DグラフィックライブラリCairoの使い方

OpenGLを使ったことはあるけど、簡単な図を出力させたいときになんか面倒だなーと思ってしまう。 何か他にないかなと探したらCairoというモノがあった。

cairographics.org

cairo - Wikipedia

Wikipediaによると、FirefoxレンダリングエンジンGeckoにも採用されているらしい。Cで書かれているが、いろいろな言語のバインディングが存在する。今流行りの言語「Julia」にもバインディングが準備されている。
Cairo.jl/sample_arc.jl at master · JuliaLang/Cairo.jl · GitHub

サンプルが準備されているのですぐに始められると思ったが、OpenGLとは少し勝手が違うようだ。チュートリアルを読んでみるとすごくシンプルな仕組みでわかりやすかったので、ここにメモしておこう。本当のチュートリアル

http://cairographics.org/tutorial/

にあるので適宜照らし合わせながら読めばよい。あとはサンプルを動かしながら学べばよいと思う。

Cairoは3つのレイヤーがあると考えるのがよい。スプレーと描きたい形の開いたもので、キャンバスに絵を描く工程を思い浮かべればよい。Cairoでは以下の様に呼ぶ.

  • Destination(キャンバス)
  • Mask(マスク)
  • Source(色)

http://cairographics.org/tutorial/#L2nounsの右の図に3つの説明がある。
更にContextというのもある。Contextには線の太さとかフォントとかいろいろ設定が書いてある。

この3つの道具を操作しながら図を描画していく。
何種類かの基本的な操作が準備されている。

  • Stroke
  • Fill
  • ShowText
  • etc

例えばStrokeはペンの役割を果たす。

cairo_rectangle (cr, 0.25, 0.25, 0.5, 0.5);
cairo_stroke (cr);

とすればマスクに長方形の線が空いて、長方形の線が描かれるし、

cairo_rectangle (cr, 0.25, 0.25, 0.5, 0.5);
cairo_fill (cr);

とすればマスクに長方形の穴が空いて、そこが塗り潰される。
http://cairographics.org/tutorial/#L2verbsの右の図がわかりやすい。

これで基本的な描画は分かったので、あとはそれをどうつなげて図を描くかだ。
チュートリアルではPathをつなげてながら図を描く様子が描かれている。
http://cairographics.org/tutorial/#L2createpath

cairo_line_to (cr, 0.5, 0.375);

とすると今の座標から指定した座標まで線を引く。
線を引かずにただ単に移動したい場合は

cairo_move_to (cr, 0.2, 0.2);

とりあえずここまで。あとはまた勉強した時に追記しよう。

ImageMagickをつかって大量の画像を並列処理する

画像データを扱う際、そのままだと膨大なデータとなって学習に時間が掛かってしまう。 ちなみに今回挑戦するKaggleのデータは90GBくらいある。 www.kaggle.com

いつもはPythonで画像処理をやっているが、今回はImageMagickGNU Parallelを使ってサクッとしかも並列に画像のりサイズを行いたい。もちろんImageMagickはリサイズ以外様々なことができるので、それもさくっと並列化できる。 環境はUbuntu 14.04 64-bit。

まずはImageMagickGNU parallelをインストール。 どちらも標準的なソフトなのですぐに入るはず。

sudo apt-get install imagemagick
sudo apt-get install parallel

※インストール出来ない場合はsudo apt-get update

画像をリサイズしたい場合は以下の1行で終わる。

parallel convert {} -verbose -resize 300x300 ./resize/resized_{} ::: *.jpeg

{}には:::のあと引数が入る。 つまり上のコマンドを展開するとすれば

convert img1.jpeg -verbose -resize 300x300 ./resize/resized_img1.jpeg
convert img2.jpeg -verbose -resize 300x300 ./resize/resized_img2.jpeg
convert img3.jpeg -verbose -resize 300x300 ./resize/resized_img3.jpeg
.
.
.

となる。

parallelの使い方は以下の2つを見て勉強

GNU parallelでちょっとした確認に使ってみた - ねぎまんち

https://www.gnu.org/software/parallel/man.html#options