/* このプログラムの目的 機械学習の手法を、2次元空間の2値の分離問題を例として体感する。 http://youtu.be/RnJCvGAGqtk 手法 wekaをProcessingから利用する。また、分類器を選択するリストボックスにはProcessingのライブラリとして公式Webに載っているControlP5を使用する。 使用方法 画面に表示されているマス目を左クリックすると赤くなり、右クリックすると青くなる。色の付いたマスが3つ以上になると自動的に分類器が学習を開始して、 その学習された分類器ですべてのマス目がテストされて、赤か青に分類される。クリックした個所はマス目の内部の色が変わり、テストされて分類された結果は マス目の枠の色が変わる。また、スペースを押すと、すべてのマス目が元に戻る。 さらに分類器を選択することができる。選択を変更すると、その分類器で学習された結果に変わる。 */ // 学習用のデータは、添え字 0:x座標位置, 1:y座標位置, 2:幅, 3:高さ, 4:教師データ, 5:テスト結果データ となっている。 //教師データ、テスト結果データは、-1:未指定, 0:red, 1:blueとなっている。この分類器は、redとblueを分離することが目的である。 Vector rects = new Vector(); int clicked_count = 0; ListBoxAd listbox; void setup() { size(300,200); int header = 30; int footer = 20; int left_right_margin = 25; for(int x=left_right_margin;x=p[0]&&mouseX<=p[0]+p[2] && mouseY>=p[1]&&mouseY<=p[1]+p[3]){ if(p[4]==-1){ clicked_count++; } p[4] = mouseButton==LEFT?0:1; learning(); break; } } } void keyPressed(){ if(key==' ' || key=='c' || (key==CODED&&keyCode==BACKSPACE)){ for(int[] p : rects){ p[4] = p[5] = -1; } clicked_count = 0; } } boolean learning(){ if(clicked_count<3){ return false; } weka.core.FastVector attrs = new weka.core.FastVector(); attrs.addElement(new weka.core.Attribute("x")); attrs.addElement(new weka.core.Attribute("y")); weka.core.FastVector attr_class = new weka.core.FastVector(); attr_class.addElement(new String("red")); attr_class.addElement(new String("blue")); attrs.addElement(new weka.core.Attribute("red_blue",attr_class)); weka.core.Instances trains = new weka.core.Instances("",attrs,0); trains.setClassIndex(trains.numAttributes()-1); for(int[] p : rects){ if(p[4]!=-1){ weka.core.Instance inst = new weka.core.Instance(trains.numAttributes()); inst.setDataset(trains); int cnt = 0; for(;cnt<2;cnt++){ inst.setValue(cnt,p[cnt]); } inst.setValue(cnt++,p[4]==0?"red":"blue"); trains.add(inst); } } weka.classifiers.Classifier cl; try{ cl = (weka.classifiers.Classifier)Class.forName(listbox.getString()).newInstance(); cl.setOptions(listbox.getOptionString().split(",")); cl.buildClassifier(trains); }catch(Exception e){ e.printStackTrace(); return false; } for(int[] p : rects){ weka.core.Instance test_data = new weka.core.Instance(trains.numAttributes()); test_data.setDataset(trains); int cnt=0; for(;cnt<2;cnt++){ test_data.setValue(cnt,p[cnt]); } try{ p[5] = (int)cl.classifyInstance(test_data); }catch(Exception e){ e.printStackTrace(); return false; } } return true; }