liblinear-ruby-swigを使って手書き数字を判別する2
今回も、前回に引き続きliblinear-ruby-swigを使って手書き数字を判別する機械学習のプログラムを組んでいきたいと思います。
【サンプルコードの改良】
サンプルコードには今回は関係ないものとかが多いので簡単に整理します。
libsvm.rb----------
require "linear" # types = [ 'L2R_LR', 'L2R_L2LOSS_SVC_DUAL', 'L2R_L2LOSS_SVC', 'L2R_L1LOSS_SVC_DUAL', 'MCSVM_CS', 'L1R_L2LOSS_SVC', 'L1R_LR' ] SVMの種類 # 0:L2_LR , 1:L2LOSS_SVM_DUAL , 2:L2LOSS_SVM , 3: L1L1LOSS_SVM_DUAL, 4: MCSVM_CS, ... 定義されている変数名 pa = LParameter.new pa.solver_type = MCSVM_CS pa.eps = 0.1 bias = 1 labels, samples = read_file("training_file") sp = LProblem.new(labels,samples,bias) model = LModel.new(sp,pa) x = {1=>1,2=>0.1,3=>0.2,4=>0,5=>0} # テストしてみるデータ puts model.predict(x)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
簡単ですけどこんな感じに整理しておきます。
みたらなんとなくわかると思いますが、
sp = LProblem.new(labels,samples,bias)
この部分に必要なデータを与えることがポイントになっています。
【csvファイルの読み込み】
機械学習において重要なのがデータをいかにプログラムに組み込むかという点である。
今回の最終目標は
sp = LProblem.new(labels,samples,bias)
この部分に
label:正解の配列
samples:ピクセルデータの配列
を渡すことである。
そのためにそれにあった配列を作成する。
整理しておいてなんですが、先ほどのコードを全部コメントアウトします。
面倒な方は一旦消してもいいです。
そして以下のようなコードを書いていきます。
libsvm.rb----------
require "linear" require "csv" label = [] data = [] load_data = [] cnt = 0; CSV.foreach("train.csv") do |row| load_data.push(row) cnt = cnt + 1 if cnt == 5 break end end load_data.shift #先頭の一行を削除 load_data.each do |load| label.push(load.shift.to_i) data.push(load.map(&:to_i)) end p label p data
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
これで、csvファイルからlabel(正解の数字)とそれに関するデータ(ピクセル)をそれぞれ配列に入れることができます。
無理やりbreakさせてるのは、すべてやると4万個ロードしてなかなか動かないし、結果も見づらいからです。
to_iやmap(&:to_i)などは、もともとのcsvファイルの情報は全部文字列なので数値に変換する必要があるため行っています。
【実際のコーディング】
libsvm.rb----------
require "linear" require "csv" # types = [ 'L2R_LR', 'L2R_L2LOSS_SVC_DUAL', 'L2R_L2LOSS_SVC', 'L2R_L1LOSS_SVC_DUAL', 'MCSVM_CS', 'L1R_L2LOSS_SVC', 'L1R_LR' ] SVMの種類 # 0:L2_LR , 1:L2LOSS_SVM_DUAL , 2:L2LOSS_SVM , 3: L1L1LOSS_SVM_DUAL, 4: MCSVM_CS, ... 定義されている変数名 # def train_loop(limit) label = [] data = [] load_data = [] cnt = 0; CSV.foreach("train.csv") do |row| load_data.push(row) cnt = cnt + 1 if cnt == limit break end end load_data.shift #先頭の一行を削除 load_data.each do |load| label.push(load.shift.to_i) data.push(load.map(&:to_i)) end test_method(label,data) end def test_method(label,data) load_test_data = [] label_test = [] data_test = [] CSV.foreach("mini_test.csv") do |row| load_test_data.push(row) end load_test_data.shift #先頭の一行を削除 load_test_data.each do |load| label_test.push(load.shift.to_i) data_test.push(load.map(&:to_i)) end pa = LParameter.new pa.solver_type = MCSVM_CS pa.eps = 0.1 bias = 1 sp = LProblem.new(label,data,bias) model = LModel.new(sp,pa) index = 0.0 success = 0.0 data_test.each do |test| # puts "#{model.predict(test)}:#{label_test[index]}" if model.predict(test) == label_test[index] success = success + 1 end index = index + 1 end puts "トータル#{index}正解#{success}正答率#{success/index*100}%" end num = [100,200,500,1000,5000] 5.times{|i| puts "学習数#{num[i]}" train_loop(num[i]) }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-