機械学習用データといえば,UCIのMachine Learning Repositoryですが,中でも有名なのがIris Data Setではないでしょうか。分類問題を一層のニューラルネットワーク(?)で解いていきたいと思います。
データの前処理
データセットは,カンマ区切りで,1行につき1つのデータとなっています。4つの数値と,1つのラベルからなっています。
splitの実装
さて,perlにもpythonにもsplitなるものがあるのですが,プロデルにはありませんので,まずこれを実装します。
[文字列:文字列]を[区切り文字:文字列]で分割する手順:配列
【配列】は,{}。
【現在位置】は,1。
【次の位置】。
繰り返す
次の位置は,文字列の現在位置文字目から区切り文字を探したもの。
もし次の位置が0なら
文字列の現在位置文字目以降を配列に加える。
繰り返しから抜ける
でないなら
文字列の現在位置文字目から次の位置-現在位置文字,取り出したものを配列に加える。
現在位置は,次の位置+1。
もし終わり
繰り返し終わり
配列を返す。
終わり
配列の添字が1から始まることに注意して下さい。
これで,「アイリスデータを「,」で分割する」という表現が可能になりました。
データの読み込み
HTTPから直接読み込む場合は,
アイリスデータは,HTTPで「https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data」を取得したものの行区切り
このようにします。ローカルに保存した場合は,
アイリスデータは,「ファイル名」から読み込んだものの行区切り
とします。これで,配列アイリスデータに,1行ずつテキストが入りました。
データ数は150ですが,なぜか空っぽの151行目,152行目があるので,これを消しておきます。
アイリスデータは,アイリスデータの151番目を消したもの。
アイリスデータは,アイリスデータの151番目を消したもの。
次に,データとラベルを入れるための行列を作ります。データは,1行につき1つですから,150行4列の行列が必要です。また,ラベルはone-hotベクトルになっていないといけないので,3クラスの分類ですから3次元必要です。よって,150行3列の行列を作ります。
データという行列(アイリスデータの個数,4)を作る。
正解という行列(アイリスデータの個数,3)を作る。
ちなみに,
データは,行列(アイリスデータの個数,4)を作ったもの。
正解は,行列(アイリスデータの個数,3)を作ったもの。
という書き方もできます。
続いて,1行ずつデータを処理していきます。
アイリスデータの個数回,【カウンタ】にカウントしながら繰り返す
【一行】は,アイリスデータ(カウンタ)を「,」で分割したもの。
4回,【添字】にカウントしながら繰り返す
データの中身(カウンタ)(添字)は,一行(添字)。
繰り返し終わり
一行(5)について分岐
「Iris-setosa」の場合
正解の中身(カウンタ)は,{1,0,0}。
「Iris-versicolor」の場合
正解の中身(カウンタ)は,{0,1,0}。
「Iris-virginica」の場合
正解の中身(カウンタ)は,{0,0,1}。
分岐終わり
繰り返し終わり
これで,前処理は終了です。
学習を行う
本来は訓練データと評価データを分けるのですが,別に研究をやっているわけではないので,全部ぶち込みます。
ネットワークは,一層(4,3)を作ったもの。
反復数は,500。
学習率は,0.05。
反復数回,繰り返す
勾配は,ネットワークで正解が正解でデータにおける勾配を計算したもの。
勾配の個数回,【キー】にカウントしながら繰り返す
ネットワークのパラメータ(キー)から,学習率を勾配(キー)に全部かけたものを破壊的に引く。
繰り返し終わり
ネットワークで正解が正解でデータにおける損失を計算したものを表示。
繰り返し終わり
結果は,ネットワークでデータから推定したものが最大値となる添字を転置したもの。
結果を表示。
正解が最大値となる添字を転置したもので結果を比較したものを表示。
たかが150個なので,ミニバッチもなにもありません。全部そのまま投げます。
「正解が正解で」という変な表現がありますが,これは変数名のつけ方がヘタクソなだけです。
インタプリタで実行しても大して時間はかかりません。
結果は以下のようになりました。
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,3,2,2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
----- アヤメの分類_NN -----
0.973333333333333
学習データをそのまま使って推定していますが,正解率は97.3%です。きちんと学習したことが分かります。「きちんと」というのは,プログラムが無事動作したという意味で,汎化性能が良いなどという意味ではありません。