| @@ -0,0 +1,502 @@ | |||||
| import libsvm.*; | |||||
| import java.applet.*; | |||||
| import java.awt.*; | |||||
| import java.util.*; | |||||
| import java.awt.event.*; | |||||
| import java.io.*; | |||||
| public class svm_toy extends Applet { | |||||
| static final String DEFAULT_PARAM="-t 2 -c 100"; | |||||
| int XLEN; | |||||
| int YLEN; | |||||
| // off-screen buffer | |||||
| Image buffer; | |||||
| Graphics buffer_gc; | |||||
| // pre-allocated colors | |||||
| final static Color colors[] = | |||||
| { | |||||
| new Color(0,0,0), | |||||
| new Color(0,120,120), | |||||
| new Color(120,120,0), | |||||
| new Color(120,0,120), | |||||
| new Color(0,200,200), | |||||
| new Color(200,200,0), | |||||
| new Color(200,0,200) | |||||
| }; | |||||
| class point { | |||||
| point(double x, double y, byte value) | |||||
| { | |||||
| this.x = x; | |||||
| this.y = y; | |||||
| this.value = value; | |||||
| } | |||||
| double x, y; | |||||
| byte value; | |||||
| } | |||||
| Vector<point> point_list = new Vector<point>(); | |||||
| byte current_value = 1; | |||||
| public void init() | |||||
| { | |||||
| setSize(getSize()); | |||||
| final Button button_change = new Button("Change"); | |||||
| Button button_run = new Button("Run"); | |||||
| Button button_clear = new Button("Clear"); | |||||
| Button button_save = new Button("Save"); | |||||
| Button button_load = new Button("Load"); | |||||
| final TextField input_line = new TextField(DEFAULT_PARAM); | |||||
| BorderLayout layout = new BorderLayout(); | |||||
| this.setLayout(layout); | |||||
| Panel p = new Panel(); | |||||
| GridBagLayout gridbag = new GridBagLayout(); | |||||
| p.setLayout(gridbag); | |||||
| GridBagConstraints c = new GridBagConstraints(); | |||||
| c.fill = GridBagConstraints.HORIZONTAL; | |||||
| c.weightx = 1; | |||||
| c.gridwidth = 1; | |||||
| gridbag.setConstraints(button_change,c); | |||||
| gridbag.setConstraints(button_run,c); | |||||
| gridbag.setConstraints(button_clear,c); | |||||
| gridbag.setConstraints(button_save,c); | |||||
| gridbag.setConstraints(button_load,c); | |||||
| c.weightx = 5; | |||||
| c.gridwidth = 5; | |||||
| gridbag.setConstraints(input_line,c); | |||||
| button_change.setBackground(colors[current_value]); | |||||
| p.add(button_change); | |||||
| p.add(button_run); | |||||
| p.add(button_clear); | |||||
| p.add(button_save); | |||||
| p.add(button_load); | |||||
| p.add(input_line); | |||||
| this.add(p,BorderLayout.SOUTH); | |||||
| button_change.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_change_clicked(); button_change.setBackground(colors[current_value]); }}); | |||||
| button_run.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_run_clicked(input_line.getText()); }}); | |||||
| button_clear.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_clear_clicked(); }}); | |||||
| button_save.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_save_clicked(input_line.getText()); }}); | |||||
| button_load.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_load_clicked(); }}); | |||||
| input_line.addActionListener(new ActionListener() | |||||
| { public void actionPerformed (ActionEvent e) | |||||
| { button_run_clicked(input_line.getText()); }}); | |||||
| this.enableEvents(AWTEvent.MOUSE_EVENT_MASK); | |||||
| } | |||||
| void draw_point(point p) | |||||
| { | |||||
| Color c = colors[p.value+3]; | |||||
| Graphics window_gc = getGraphics(); | |||||
| buffer_gc.setColor(c); | |||||
| buffer_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4); | |||||
| window_gc.setColor(c); | |||||
| window_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4); | |||||
| } | |||||
| void clear_all() | |||||
| { | |||||
| point_list.removeAllElements(); | |||||
| if(buffer != null) | |||||
| { | |||||
| buffer_gc.setColor(colors[0]); | |||||
| buffer_gc.fillRect(0,0,XLEN,YLEN); | |||||
| } | |||||
| repaint(); | |||||
| } | |||||
| void draw_all_points() | |||||
| { | |||||
| int n = point_list.size(); | |||||
| for(int i=0;i<n;i++) | |||||
| draw_point(point_list.elementAt(i)); | |||||
| } | |||||
| void button_change_clicked() | |||||
| { | |||||
| ++current_value; | |||||
| if(current_value > 3) current_value = 1; | |||||
| } | |||||
| private static double atof(String s) | |||||
| { | |||||
| return Double.valueOf(s).doubleValue(); | |||||
| } | |||||
| private static int atoi(String s) | |||||
| { | |||||
| return Integer.parseInt(s); | |||||
| } | |||||
| void button_run_clicked(String args) | |||||
| { | |||||
| // guard | |||||
| if(point_list.isEmpty()) return; | |||||
| svm_parameter param = new svm_parameter(); | |||||
| // default values | |||||
| param.svm_type = svm_parameter.C_SVC; | |||||
| param.kernel_type = svm_parameter.RBF; | |||||
| param.degree = 3; | |||||
| param.gamma = 0; | |||||
| param.coef0 = 0; | |||||
| param.nu = 0.5; | |||||
| param.cache_size = 40; | |||||
| param.C = 1; | |||||
| param.eps = 1e-3; | |||||
| param.p = 0.1; | |||||
| param.shrinking = 1; | |||||
| param.probability = 0; | |||||
| param.nr_weight = 0; | |||||
| param.weight_label = new int[0]; | |||||
| param.weight = new double[0]; | |||||
| // parse options | |||||
| StringTokenizer st = new StringTokenizer(args); | |||||
| String[] argv = new String[st.countTokens()]; | |||||
| for(int i=0;i<argv.length;i++) | |||||
| argv[i] = st.nextToken(); | |||||
| for(int i=0;i<argv.length;i++) | |||||
| { | |||||
| if(argv[i].charAt(0) != '-') break; | |||||
| if(++i>=argv.length) | |||||
| { | |||||
| System.err.print("unknown option\n"); | |||||
| break; | |||||
| } | |||||
| switch(argv[i-1].charAt(1)) | |||||
| { | |||||
| case 's': | |||||
| param.svm_type = atoi(argv[i]); | |||||
| break; | |||||
| case 't': | |||||
| param.kernel_type = atoi(argv[i]); | |||||
| break; | |||||
| case 'd': | |||||
| param.degree = atoi(argv[i]); | |||||
| break; | |||||
| case 'g': | |||||
| param.gamma = atof(argv[i]); | |||||
| break; | |||||
| case 'r': | |||||
| param.coef0 = atof(argv[i]); | |||||
| break; | |||||
| case 'n': | |||||
| param.nu = atof(argv[i]); | |||||
| break; | |||||
| case 'm': | |||||
| param.cache_size = atof(argv[i]); | |||||
| break; | |||||
| case 'c': | |||||
| param.C = atof(argv[i]); | |||||
| break; | |||||
| case 'e': | |||||
| param.eps = atof(argv[i]); | |||||
| break; | |||||
| case 'p': | |||||
| param.p = atof(argv[i]); | |||||
| break; | |||||
| case 'h': | |||||
| param.shrinking = atoi(argv[i]); | |||||
| break; | |||||
| case 'b': | |||||
| param.probability = atoi(argv[i]); | |||||
| break; | |||||
| case 'w': | |||||
| ++param.nr_weight; | |||||
| { | |||||
| int[] old = param.weight_label; | |||||
| param.weight_label = new int[param.nr_weight]; | |||||
| System.arraycopy(old,0,param.weight_label,0,param.nr_weight-1); | |||||
| } | |||||
| { | |||||
| double[] old = param.weight; | |||||
| param.weight = new double[param.nr_weight]; | |||||
| System.arraycopy(old,0,param.weight,0,param.nr_weight-1); | |||||
| } | |||||
| param.weight_label[param.nr_weight-1] = atoi(argv[i-1].substring(2)); | |||||
| param.weight[param.nr_weight-1] = atof(argv[i]); | |||||
| break; | |||||
| default: | |||||
| System.err.print("unknown option\n"); | |||||
| } | |||||
| } | |||||
| // build problem | |||||
| svm_problem prob = new svm_problem(); | |||||
| prob.l = point_list.size(); | |||||
| prob.y = new double[prob.l]; | |||||
| if(param.kernel_type == svm_parameter.PRECOMPUTED) | |||||
| { | |||||
| } | |||||
| else if(param.svm_type == svm_parameter.EPSILON_SVR || | |||||
| param.svm_type == svm_parameter.NU_SVR) | |||||
| { | |||||
| if(param.gamma == 0) param.gamma = 1; | |||||
| prob.x = new svm_node[prob.l][1]; | |||||
| for(int i=0;i<prob.l;i++) | |||||
| { | |||||
| point p = point_list.elementAt(i); | |||||
| prob.x[i][0] = new svm_node(); | |||||
| prob.x[i][0].index = 1; | |||||
| prob.x[i][0].value = p.x; | |||||
| prob.y[i] = p.y; | |||||
| } | |||||
| // build model & classify | |||||
| svm_model model = svm.svm_train(prob, param); | |||||
| svm_node[] x = new svm_node[1]; | |||||
| x[0] = new svm_node(); | |||||
| x[0].index = 1; | |||||
| int[] j = new int[XLEN]; | |||||
| Graphics window_gc = getGraphics(); | |||||
| for (int i = 0; i < XLEN; i++) | |||||
| { | |||||
| x[0].value = (double) i / XLEN; | |||||
| j[i] = (int)(YLEN*svm.svm_predict(model, x)); | |||||
| } | |||||
| buffer_gc.setColor(colors[0]); | |||||
| buffer_gc.drawLine(0,0,0,YLEN-1); | |||||
| window_gc.setColor(colors[0]); | |||||
| window_gc.drawLine(0,0,0,YLEN-1); | |||||
| int p = (int)(param.p * YLEN); | |||||
| for(int i=1;i<XLEN;i++) | |||||
| { | |||||
| buffer_gc.setColor(colors[0]); | |||||
| buffer_gc.drawLine(i,0,i,YLEN-1); | |||||
| window_gc.setColor(colors[0]); | |||||
| window_gc.drawLine(i,0,i,YLEN-1); | |||||
| buffer_gc.setColor(colors[5]); | |||||
| window_gc.setColor(colors[5]); | |||||
| buffer_gc.drawLine(i-1,j[i-1],i,j[i]); | |||||
| window_gc.drawLine(i-1,j[i-1],i,j[i]); | |||||
| if(param.svm_type == svm_parameter.EPSILON_SVR) | |||||
| { | |||||
| buffer_gc.setColor(colors[2]); | |||||
| window_gc.setColor(colors[2]); | |||||
| buffer_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p); | |||||
| window_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p); | |||||
| buffer_gc.setColor(colors[2]); | |||||
| window_gc.setColor(colors[2]); | |||||
| buffer_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p); | |||||
| window_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p); | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if(param.gamma == 0) param.gamma = 0.5; | |||||
| prob.x = new svm_node [prob.l][2]; | |||||
| for(int i=0;i<prob.l;i++) | |||||
| { | |||||
| point p = point_list.elementAt(i); | |||||
| prob.x[i][0] = new svm_node(); | |||||
| prob.x[i][0].index = 1; | |||||
| prob.x[i][0].value = p.x; | |||||
| prob.x[i][1] = new svm_node(); | |||||
| prob.x[i][1].index = 2; | |||||
| prob.x[i][1].value = p.y; | |||||
| prob.y[i] = p.value; | |||||
| } | |||||
| // build model & classify | |||||
| svm_model model = svm.svm_train(prob, param); | |||||
| svm_node[] x = new svm_node[2]; | |||||
| x[0] = new svm_node(); | |||||
| x[1] = new svm_node(); | |||||
| x[0].index = 1; | |||||
| x[1].index = 2; | |||||
| Graphics window_gc = getGraphics(); | |||||
| for (int i = 0; i < XLEN; i++) | |||||
| for (int j = 0; j < YLEN ; j++) { | |||||
| x[0].value = (double) i / XLEN; | |||||
| x[1].value = (double) j / YLEN; | |||||
| double d = svm.svm_predict(model, x); | |||||
| if (param.svm_type == svm_parameter.ONE_CLASS && d<0) d=2; | |||||
| buffer_gc.setColor(colors[(int)d]); | |||||
| window_gc.setColor(colors[(int)d]); | |||||
| buffer_gc.drawLine(i,j,i,j); | |||||
| window_gc.drawLine(i,j,i,j); | |||||
| } | |||||
| } | |||||
| draw_all_points(); | |||||
| } | |||||
| void button_clear_clicked() | |||||
| { | |||||
| clear_all(); | |||||
| } | |||||
| void button_save_clicked(String args) | |||||
| { | |||||
| FileDialog dialog = new FileDialog(new Frame(),"Save",FileDialog.SAVE); | |||||
| dialog.setVisible(true); | |||||
| String filename = dialog.getDirectory() + dialog.getFile(); | |||||
| if (filename == null) return; | |||||
| try { | |||||
| DataOutputStream fp = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); | |||||
| int svm_type = svm_parameter.C_SVC; | |||||
| int svm_type_idx = args.indexOf("-s "); | |||||
| if(svm_type_idx != -1) | |||||
| { | |||||
| StringTokenizer svm_str_st = new StringTokenizer(args.substring(svm_type_idx+2).trim()); | |||||
| svm_type = atoi(svm_str_st.nextToken()); | |||||
| } | |||||
| int n = point_list.size(); | |||||
| if(svm_type == svm_parameter.EPSILON_SVR || svm_type == svm_parameter.NU_SVR) | |||||
| { | |||||
| for(int i=0;i<n;i++) | |||||
| { | |||||
| point p = point_list.elementAt(i); | |||||
| fp.writeBytes(p.y+" 1:"+p.x+"\n"); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| for(int i=0;i<n;i++) | |||||
| { | |||||
| point p = point_list.elementAt(i); | |||||
| fp.writeBytes(p.value+" 1:"+p.x+" 2:"+p.y+"\n"); | |||||
| } | |||||
| } | |||||
| fp.close(); | |||||
| } catch (IOException e) { System.err.print(e); } | |||||
| } | |||||
| void button_load_clicked() | |||||
| { | |||||
| FileDialog dialog = new FileDialog(new Frame(),"Load",FileDialog.LOAD); | |||||
| dialog.setVisible(true); | |||||
| String filename = dialog.getDirectory() + dialog.getFile(); | |||||
| if (filename == null) return; | |||||
| clear_all(); | |||||
| try { | |||||
| BufferedReader fp = new BufferedReader(new FileReader(filename)); | |||||
| String line; | |||||
| while((line = fp.readLine()) != null) | |||||
| { | |||||
| StringTokenizer st = new StringTokenizer(line," \t\n\r\f:"); | |||||
| if(st.countTokens() == 5) | |||||
| { | |||||
| byte value = (byte)atoi(st.nextToken()); | |||||
| st.nextToken(); | |||||
| double x = atof(st.nextToken()); | |||||
| st.nextToken(); | |||||
| double y = atof(st.nextToken()); | |||||
| point_list.addElement(new point(x,y,value)); | |||||
| } | |||||
| else if(st.countTokens() == 3) | |||||
| { | |||||
| double y = atof(st.nextToken()); | |||||
| st.nextToken(); | |||||
| double x = atof(st.nextToken()); | |||||
| point_list.addElement(new point(x,y,current_value)); | |||||
| }else | |||||
| break; | |||||
| } | |||||
| fp.close(); | |||||
| } catch (IOException e) { System.err.print(e); } | |||||
| draw_all_points(); | |||||
| } | |||||
| protected void processMouseEvent(MouseEvent e) | |||||
| { | |||||
| if(e.getID() == MouseEvent.MOUSE_PRESSED) | |||||
| { | |||||
| if(e.getX() >= XLEN || e.getY() >= YLEN) return; | |||||
| point p = new point((double)e.getX()/XLEN, | |||||
| (double)e.getY()/YLEN, | |||||
| current_value); | |||||
| point_list.addElement(p); | |||||
| draw_point(p); | |||||
| } | |||||
| } | |||||
| public void paint(Graphics g) | |||||
| { | |||||
| // create buffer first time | |||||
| if(buffer == null) { | |||||
| buffer = this.createImage(XLEN,YLEN); | |||||
| buffer_gc = buffer.getGraphics(); | |||||
| buffer_gc.setColor(colors[0]); | |||||
| buffer_gc.fillRect(0,0,XLEN,YLEN); | |||||
| } | |||||
| g.drawImage(buffer,0,0,this); | |||||
| } | |||||
| public Dimension getPreferredSize() { return new Dimension(XLEN,YLEN+50); } | |||||
| public void setSize(Dimension d) { setSize(d.width,d.height); } | |||||
| public void setSize(int w,int h) { | |||||
| super.setSize(w,h); | |||||
| XLEN = w; | |||||
| YLEN = h-50; | |||||
| clear_all(); | |||||
| } | |||||
| public static void main(String[] argv) | |||||
| { | |||||
| new AppletFrame("svm_toy",new svm_toy(),500,500+50); | |||||
| } | |||||
| } | |||||
| class AppletFrame extends Frame { | |||||
| AppletFrame(String title, Applet applet, int width, int height) | |||||
| { | |||||
| super(title); | |||||
| this.addWindowListener(new WindowAdapter() { | |||||
| public void windowClosing(WindowEvent e) { | |||||
| System.exit(0); | |||||
| } | |||||
| }); | |||||
| applet.init(); | |||||
| applet.setSize(width,height); | |||||
| applet.start(); | |||||
| this.add(applet); | |||||
| this.pack(); | |||||
| this.setVisible(true); | |||||
| } | |||||
| } | |||||