パーセプトロンってなんだろう?

ということで、パーセプトロンがどんな感じで判定してるかを見てみました。


判定の境界が直線になっていることがわかります。パーセプトロンは、こういう具合に判定結果を分離する直線(平面)を求めるもので、これが線形分離ということです。そのため、線形分離不可能な場合には、誤判定が発生してます。

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;
    }
}