課題提出に使ったJulia用のスクリプトは、こちらのリポジトリにおいています。
Juliaで課題を提出したい方は、是非ご利用ください。多少手間が省けるかと。
Coursera Machine Learningについて
Andrew Ng氏による、機械学習のオンライン講座です。
https://www.coursera.org/learn/machine-learning
以下の記事などで紹介されています。
http://qiita.com/daxanya1/items/218f2e3b922142550ef9
講座を進めていくと、途中で課題(Assignment)を提出する必要があるのですが、これらはプログラムを書いて、その出力をサーバに送信する形式になっています。
公式ではMatlabかOctaveで解くことになっていますが、今回はこれをJuliaで解いてみたお話です。
Why Julia?
Octaveが遅すぎるなどして、この先使っていく気が全くせず = Octaveを全く覚える気になれず。
Juliaは書いたことがなかっものの、気にはなっていたのと、比較的速いということも聞いていたので、この機会に試してみようということでやってみました。
実際にやってみた感想として、OctaveやMatlabとsyntaxや関数が近いことが多いので、比較的課題に取り組みやすい印象はあります。
Python用のスクリプトを公開している人もいて(解答コードが書かれていないものもある)、これらを使ってPythonで解いても良かったのですが、「PythonよりもOctaveのほうがいいよー」という趣旨の説明が講義の中でもされていた気がするので(学習コストに関する文脈)、Pythonは回避しました。
JuliaでAssignmentをやる
提供されているOctaveのスクリプトを、Juliaで書き直してあげればよいわけですが、問題を解くだけであれば、さほど大変ではないです。
例えばですが、OctaveのExercise1用のスクリプトのある部分はこうなっていて、
%% ======================= Part 2: Plotting =======================
printf('Plotting Data ...\n')
data = load('ex1data1.txt');
X = data(:, 1); y = data(:, 2);
m = length(y); % number of training examples
% Plot Data
% Note: You have to complete the code in plotData.m
plotData(X, y);
fprintf('Program paused. Press enter to continue.\n');
pause;
Juliaで書き換えるとこんな感じになります。
using Gadfly
@printf("Plotting Data ...\n")
data = readcsv("ex1data1.txt")
X = data[:, 1]
y = data[:, 2]
m = length(y) # number of training examples
# Plot Data
# Note: You have to complete the code in plotData.jl
l1 = plotData(X, y)
draw(SVGJS("ex1-dataset.js.svg", 6inch, 6inch), plot(l1))
println("Program paused. Press enter to continue.")
readline()
他のスクリプトでも、大体変更が入るのはこの例と同じで、
-
ファイル入力、標準出力
-
fprintf
->@printf
やprintln
に - ファイル入力は適当に
- .matを読むときは、PyCall使って、scipy.ioの
loadmat
メソッドを呼び出す
-
-
配列、行列の操作
-
X(1, :)
->X[1, :]
-
[X, Y]
->[X; Y]
or[X Y]
... などなど
-
-
Data Visualization
- 適当なライブラリを使う
- PyPlotなら、matplotlibを使えて、使い方もOctaveの関数とかなり近くなる
- Gadfly, Plotlyなども使えるが、結構書き直しが必要
- meshgridに相当する関数はないので、自力で書く
- 適当なライブラリを使う
といったところで、他はそのままで動くことが多いです。
plotDataあたりが気持ち悪いことになっていますが、そのあたりは後述します。
Data Visualization
やらなくても、課題を提出する上では問題ないです。
きれいに出力したい気持ちはありつつ、結構ハマったりします。
PyPlot
多分一番楽です。
以下単純にデータセットをplotするだけのコードですが、コードを比較的近い対応で書き直すことができます。
以下、上図のplotを行うコードです。
都合により、直線を引く部分は書いていないですが、
figure;
hold on;
plot(x=X[ps, 1], y=X[ps, 2], color="b");
plot(x=X[ns, 1], y=X[ns, 2], color="y");
xlabel("Exam 1 score");
ylabel("Exam 2 score");
hold off;
PyPlotを使ってJuliaで書くと、
using PyPlot
figure()
hold(true)
scatter(x=X[ps, 1], y=X[ps, 2], color="b")
scatter(x=X[ns, 1], y=X[ns, 2], color="y")
xlabel("Exam 1 score")
ylabel("Exam 2 score")
hold(false)
ただ、NumpyのオブジェクトをJuliaのデータに変換する操作などがバックで走るときに、たまにキレイに動いてくれないときがあって、PyCallに依存すると後々気持ち悪そうな気がしています。
Gadfly
先ほどの図をGadflyで書くとこんな感じになります(微妙に対応していない部分もありますが)。
同じく都合により、直線を引くコードがないですが、
l1 = layer(x=X[ps, 1], y=X[ps, 2], Geom.point, Theme(default_color=colorant"blue"))
l2 = layer(x=X[ns, 1], y=X[ns, 2], Geom.point, Theme(default_color=colorant"yellow"))
plot(l1, l2 Stat.xticks(ticks=collect(30:10:100)), Stat.yticks(ticks=collect(30:10:100)),
Guide.xlabel("Exam 1 score"), Guide.ylabel("Exam 2 score"))
とりあえず重いです。ひたすら重いです。
図は多少洗練された感じになりますが。
その他にも
- legendを扱う標準的な方法がない
- 工夫すれば大体できるとは思われるものの、いずれにせよ面倒
- layerの取り扱いが微妙。
- 既存のplotに上書きしようとすると、layerを使う必要がある(ので、plotDataとかでlayerを返したりしてました。。関数の名前を変えれば、多少はましな印象になるかもしれないですが)
- contour使うと、plotや他のlayerで、特定の属性(Scale系など。点の色を数値によって連続的に変えたい時に萎える)が使えなくなる
- surfなど、3Dのplot用の関数がないなど、必要な関数が揃っていない
など、微妙な点はいくつかあります。SVGを出力してくれて、ブラウザ上で操作できるのは嬉しいので使ってました。
※Juliaのインタプリタでplot関数を呼び出すと、ブラウザが起動してくれるのですが、plotを呼んでいるファイルを読み込んでも、ブラウザは自動では起動してくれなかったです。やり方が間違っているような気はしますが、まだ詳しくは調べていません。
Plotly
まだ使ってないので、これから使ってみようと思ってます。
Gadflyよりは速そうなのと、 3Dのplotができるので、PyPlotに頼らなくて良くなると期待。
結果
- 時間はかかる
- 予めOctaveで用意されている部分も含めて、Juliaで書いていくため
- 500行ぐらいのスクリプトを、Juliaで書き直さなければいけない時もあり、後半は結構辛くなった
- 変更箇所が多くないとはいえ、エラーが起きたら直すといったスタイルでやっていたせいかも
- ライブラリは強力
- 線形代数系はよさげ。blas.jlとかあって、熱い(速度は計ってないですが)
- コードは表現力も高く、書きやすい
- 確かに速い
- 当たり前ですが、Octaveとは比べ物にならないぐらい速かったです
とまれ、Juliaいいね!(これが言いたかった)