ということで、パーセプトロンがどんな感じで判定してるかを見てみました。
判定の境界が直線になっていることがわかります。パーセプトロンは、こういう具合に判定結果を分離する直線(平面)を求めるもので、これが線形分離ということです。そのため、線形分離不可能な場合には、誤判定が発生してます。
import java.util.*; public class Perceptron implements LearningMachine{ List<Map.Entry<Integer, double[]>> patterns = new ArrayList<Map.Entry<Integer, double[]>>(); double b; double[] p; int dim; public Perceptron(int dim) { this.dim = dim; } public static void main(String[] args) { new Graph("パーセプトロン評価"){ @Override public LearningMachine createLearningMachine() { return new Perceptron(2); } }; } public void learn(int cls, double[] data) { int yi = cls == 1 ? 1 : -1; patterns.add(new AbstractMap.SimpleEntry(yi, data)); final double k = .01; b = 0; p = new double[dim]; for(int j = 0; j < 100; ++j){ //学習を繰り返す boolean fin = true; for(Map.Entry<Integer, double[]> entry : patterns){ double[] pattern = entry.getValue(); int pcls = entry.getKey(); double in = 0; for(int i = 0; i < pattern.length; ++i){ in += pattern[i] * p[i]; } in += b; if(in * pcls <= 0){ //誤判定で再学習 fin = false; for(int i = 0; i < p.length; ++i){ p[i] += pattern[i] * k * pcls; } b += k * pcls; } } if(fin) break;//パーセプトロンの収束 } } public int trial(double[] data) { double in = 0; for(int i = 0; i < data.length; ++i){ in += data[i] * p[i]; } in += b; return (in > 0) ? 1 : -1; } }