package JKernelMachines; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Random; import JKernelMachines.DoubleLinear; import JKernelMachines.TrainingSample; public class DoublePegasosSVM implements Classifier, Serializable{ /** * */ private static final long serialVersionUID = 5289136605543751554L; private DoubleLinear kernel = new DoubleLinear(); private List> tList; private double[] w; private double b = 0; int T = 100000; int k = 10; double lambda = 1e-3; double t0 = 1.e2; boolean bias = true; double C = 1; boolean hasC = false; /* (non-Javadoc) * @see JKernelMachines.Classifier#train(java.util.ArrayList) */ @Override public void train(List> l) { Random ran = new Random(System.currentTimeMillis()); //hard limit for k if(k > l.size()) k = l.size(); tList = l; int taille = tList.get(0).sample.length; //reset w w = new double[taille]; for(int m = 0 ; m < taille; m++) w[m] = 0.; //reset bias b = 0; //check if C if(hasC) lambda = 1.0 / (C * tList.size()); eprintln(1, "begin training"); long time = System.currentTimeMillis(); for(int i = 0; i< T; i++) { //sub sample selection ArrayList subSampleIndices = new ArrayList(); for( ;subSampleIndices.size()< k;) { int e = ran.nextInt(tList.size()); if(!subSampleIndices.contains(e)) { subSampleIndices.add(e); } } //remove y(-b) >= 1 for(Iterator iter = subSampleIndices.iterator(); iter.hasNext(); ) { Integer index = iter.next(); double[] d = tList.get(index).sample; int y = tList.get(index).label; if((kernel.valueOf(w, d) - b)*y > 1) iter.remove(); } //choosing step double eta = 1/(double)(lambda*(i+t0)); //calculate half step coefficient; double[] w_halfstep = new double[w.length]; for(int m = 0 ; m < taille; m++) { w_halfstep[m] = (1-eta*lambda)*w[m]; } double dir = 0; for(Iterator iter = subSampleIndices.iterator(); iter.hasNext(); ) { Integer index = iter.next(); TrainingSample t = tList.get(index); for(int m = 0 ; m < taille; m++) { if(t.sample[m] != 0) { dir = t.label*t.sample[m]; w_halfstep[m] += eta/(double)(k)*dir; } } } //b double b_new = 0; if(bias) for(int index : subSampleIndices) { b_new += tList.get(index).label; } //final step double norm = Math.sqrt(kernel.valueOf(w_halfstep, w_halfstep)); double min = 1/Math.sqrt(lambda)/norm; if(min > 1) min = 1; double[] w_fullstep = w_halfstep.clone(); for(int m = 0 ; m < taille; m++) w_fullstep[m] = w_halfstep[m] * min; w = w_fullstep; if(bias) b = min*( (1-eta*lambda)*b - eta/(double)k*b_new); else b = 0; eprintln(4, "w : "+Arrays.toString(w)+" b : "+b); if(T>20 && i%(T/20) == 0) eprint(2, "."); } eprintln(2, ""); eprintln(1, "done in "+(System.currentTimeMillis()-time)+" ms"); eprintln(3, "w : "+Arrays.toString(w)+" b : "+b); /*for (int indice = 0; indice < w.length; indice++) { System.err.print(indice + " : " + w[indice] + ", "); }*/ } /* (non-Javadoc) * @see JKernelMachines.Classifier#train(JKernelMachines.TrainingSample) */ @Override public void train(TrainingSample t) { if(tList == null) tList = new ArrayList>(); tList.add(t); train(tList); } /* (non-Javadoc) * @see JKernelMachines.Classifier#valueOf(java.lang.Object) */ @Override public double valueOf(double[] e) { return kernel.valueOf(w, e)-b; } /** * @return the t */ public int getT() { return T; } /** * @param t the t to set */ public void setT(int t) { T = t; } /** * @return the k */ public int getK() { return k; } /** * @param k the k to set */ public void setK(int k) { this.k = k; } /** * @return the lambda */ public double getLambda() { return lambda; } /** * @param lambda the lambda to set */ public void setLambda(double lambda) { this.lambda = lambda; } /** * @return the hyperplane coordinates */ public double[] getW() { return w; } /** * Setting the hyperplane coordinates * @param w the w to set */ public void setW(double[] w) { this.w = w; } /** * the bias b of (w*x -b) * @return the bias */ public double getB() { return b; } /** * Setting the bias term * @param b the b to set */ public void setB(double b) { this.b = b; } public boolean isBias() { return bias; } public void setBias(boolean bias) { this.bias = bias; } private int VERBOSITY_LEVEL = 0; /** * set how verbose SimpleMKL shall be.
* Everything is printed to stderr.
* none : 0 (default), few : 1, more : 2, all : 3 * @param l */ public void setVerbosityLevel(int l) { VERBOSITY_LEVEL = l; } public void eprint(int level, String s) { if(VERBOSITY_LEVEL >= level) System.err.print(s); } public void eprintln(int level, String s) { if(VERBOSITY_LEVEL >= level) System.err.println(s); } public double getT0() { return t0; } public void setT0(double t0) { this.t0 = t0; } /** * Set C hyperparameter * @param c */ public void setC(double c) { hasC = true; C = c; } }