1 import libsvm.*; 2 import java.applet.*; 3 import java.awt.*; 4 import java.util.*; 5 import java.awt.event.*; 6 import java.io.*; 7 8 public class svm_toy extends Applet { 9 10 static final String DEFAULT_PARAM="-t 2 -c 100"; 11 int XLEN; 12 int YLEN; 13 14 // off-screen buffer 15 16 Image buffer; 17 Graphics buffer_gc; 18 19 // pre-allocated colors 20 21 final static Color colors[] = 22 { 23 new Color(0,0,0), 24 new Color(0,120,120), 25 new Color(120,120,0), 26 new Color(120,0,120), 27 new Color(0,200,200), 28 new Color(200,200,0), 29 new Color(200,0,200) 30 }; 31 32 class point { point(double x, double y, byte value)33 point(double x, double y, byte value) 34 { 35 this.x = x; 36 this.y = y; 37 this.value = value; 38 } 39 double x, y; 40 byte value; 41 } 42 43 Vector<point> point_list = new Vector<point>(); 44 byte current_value = 1; 45 init()46 public void init() 47 { 48 setSize(getSize()); 49 50 final Button button_change = new Button("Change"); 51 Button button_run = new Button("Run"); 52 Button button_clear = new Button("Clear"); 53 Button button_save = new Button("Save"); 54 Button button_load = new Button("Load"); 55 final TextField input_line = new TextField(DEFAULT_PARAM); 56 57 BorderLayout layout = new BorderLayout(); 58 this.setLayout(layout); 59 60 Panel p = new Panel(); 61 GridBagLayout gridbag = new GridBagLayout(); 62 p.setLayout(gridbag); 63 64 GridBagConstraints c = new GridBagConstraints(); 65 c.fill = GridBagConstraints.HORIZONTAL; 66 c.weightx = 1; 67 c.gridwidth = 1; 68 gridbag.setConstraints(button_change,c); 69 gridbag.setConstraints(button_run,c); 70 gridbag.setConstraints(button_clear,c); 71 gridbag.setConstraints(button_save,c); 72 gridbag.setConstraints(button_load,c); 73 c.weightx = 5; 74 c.gridwidth = 5; 75 gridbag.setConstraints(input_line,c); 76 77 button_change.setBackground(colors[current_value]); 78 79 p.add(button_change); 80 p.add(button_run); 81 p.add(button_clear); 82 p.add(button_save); 83 p.add(button_load); 84 p.add(input_line); 85 this.add(p,BorderLayout.SOUTH); 86 87 button_change.addActionListener(new ActionListener() 88 { public void actionPerformed (ActionEvent e) 89 { button_change_clicked(); button_change.setBackground(colors[current_value]); }}); 90 91 button_run.addActionListener(new ActionListener() 92 { public void actionPerformed (ActionEvent e) 93 { button_run_clicked(input_line.getText()); }}); 94 95 button_clear.addActionListener(new ActionListener() 96 { public void actionPerformed (ActionEvent e) 97 { button_clear_clicked(); }}); 98 99 button_save.addActionListener(new ActionListener() 100 { public void actionPerformed (ActionEvent e) 101 { button_save_clicked(input_line.getText()); }}); 102 103 button_load.addActionListener(new ActionListener() 104 { public void actionPerformed (ActionEvent e) 105 { button_load_clicked(); }}); 106 107 input_line.addActionListener(new ActionListener() 108 { public void actionPerformed (ActionEvent e) 109 { button_run_clicked(input_line.getText()); }}); 110 111 this.enableEvents(AWTEvent.MOUSE_EVENT_MASK); 112 } 113 draw_point(point p)114 void draw_point(point p) 115 { 116 Color c = colors[p.value+3]; 117 118 Graphics window_gc = getGraphics(); 119 buffer_gc.setColor(c); 120 buffer_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4); 121 window_gc.setColor(c); 122 window_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4); 123 } 124 clear_all()125 void clear_all() 126 { 127 point_list.removeAllElements(); 128 if(buffer != null) 129 { 130 buffer_gc.setColor(colors[0]); 131 buffer_gc.fillRect(0,0,XLEN,YLEN); 132 } 133 repaint(); 134 } 135 draw_all_points()136 void draw_all_points() 137 { 138 int n = point_list.size(); 139 for(int i=0;i<n;i++) 140 draw_point(point_list.elementAt(i)); 141 } 142 button_change_clicked()143 void button_change_clicked() 144 { 145 ++current_value; 146 if(current_value > 3) current_value = 1; 147 } 148 atof(String s)149 private static double atof(String s) 150 { 151 return Double.valueOf(s).doubleValue(); 152 } 153 atoi(String s)154 private static int atoi(String s) 155 { 156 return Integer.parseInt(s); 157 } 158 button_run_clicked(String args)159 void button_run_clicked(String args) 160 { 161 // guard 162 if(point_list.isEmpty()) return; 163 164 svm_parameter param = new svm_parameter(); 165 166 // default values 167 param.svm_type = svm_parameter.C_SVC; 168 param.kernel_type = svm_parameter.RBF; 169 param.degree = 3; 170 param.gamma = 0; 171 param.coef0 = 0; 172 param.nu = 0.5; 173 param.cache_size = 40; 174 param.C = 1; 175 param.eps = 1e-3; 176 param.p = 0.1; 177 param.shrinking = 1; 178 param.probability = 0; 179 param.nr_weight = 0; 180 param.weight_label = new int[0]; 181 param.weight = new double[0]; 182 183 // parse options 184 StringTokenizer st = new StringTokenizer(args); 185 String[] argv = new String[st.countTokens()]; 186 for(int i=0;i<argv.length;i++) 187 argv[i] = st.nextToken(); 188 189 for(int i=0;i<argv.length;i++) 190 { 191 if(argv[i].charAt(0) != '-') break; 192 if(++i>=argv.length) 193 { 194 System.err.print("unknown option\n"); 195 break; 196 } 197 switch(argv[i-1].charAt(1)) 198 { 199 case 's': 200 param.svm_type = atoi(argv[i]); 201 break; 202 case 't': 203 param.kernel_type = atoi(argv[i]); 204 break; 205 case 'd': 206 param.degree = atoi(argv[i]); 207 break; 208 case 'g': 209 param.gamma = atof(argv[i]); 210 break; 211 case 'r': 212 param.coef0 = atof(argv[i]); 213 break; 214 case 'n': 215 param.nu = atof(argv[i]); 216 break; 217 case 'm': 218 param.cache_size = atof(argv[i]); 219 break; 220 case 'c': 221 param.C = atof(argv[i]); 222 break; 223 case 'e': 224 param.eps = atof(argv[i]); 225 break; 226 case 'p': 227 param.p = atof(argv[i]); 228 break; 229 case 'h': 230 param.shrinking = atoi(argv[i]); 231 break; 232 case 'b': 233 param.probability = atoi(argv[i]); 234 break; 235 case 'w': 236 ++param.nr_weight; 237 { 238 int[] old = param.weight_label; 239 param.weight_label = new int[param.nr_weight]; 240 System.arraycopy(old,0,param.weight_label,0,param.nr_weight-1); 241 } 242 243 { 244 double[] old = param.weight; 245 param.weight = new double[param.nr_weight]; 246 System.arraycopy(old,0,param.weight,0,param.nr_weight-1); 247 } 248 249 param.weight_label[param.nr_weight-1] = atoi(argv[i-1].substring(2)); 250 param.weight[param.nr_weight-1] = atof(argv[i]); 251 break; 252 default: 253 System.err.print("unknown option\n"); 254 } 255 } 256 257 // build problem 258 svm_problem prob = new svm_problem(); 259 prob.l = point_list.size(); 260 prob.y = new double[prob.l]; 261 262 if(param.kernel_type == svm_parameter.PRECOMPUTED) 263 { 264 } 265 else if(param.svm_type == svm_parameter.EPSILON_SVR || 266 param.svm_type == svm_parameter.NU_SVR) 267 { 268 if(param.gamma == 0) param.gamma = 1; 269 prob.x = new svm_node[prob.l][1]; 270 for(int i=0;i<prob.l;i++) 271 { 272 point p = point_list.elementAt(i); 273 prob.x[i][0] = new svm_node(); 274 prob.x[i][0].index = 1; 275 prob.x[i][0].value = p.x; 276 prob.y[i] = p.y; 277 } 278 279 // build model & classify 280 svm_model model = svm.svm_train(prob, param); 281 svm_node[] x = new svm_node[1]; 282 x[0] = new svm_node(); 283 x[0].index = 1; 284 int[] j = new int[XLEN]; 285 286 Graphics window_gc = getGraphics(); 287 for (int i = 0; i < XLEN; i++) 288 { 289 x[0].value = (double) i / XLEN; 290 j[i] = (int)(YLEN*svm.svm_predict(model, x)); 291 } 292 293 buffer_gc.setColor(colors[0]); 294 buffer_gc.drawLine(0,0,0,YLEN-1); 295 window_gc.setColor(colors[0]); 296 window_gc.drawLine(0,0,0,YLEN-1); 297 298 int p = (int)(param.p * YLEN); 299 for(int i=1;i<XLEN;i++) 300 { 301 buffer_gc.setColor(colors[0]); 302 buffer_gc.drawLine(i,0,i,YLEN-1); 303 window_gc.setColor(colors[0]); 304 window_gc.drawLine(i,0,i,YLEN-1); 305 306 buffer_gc.setColor(colors[5]); 307 window_gc.setColor(colors[5]); 308 buffer_gc.drawLine(i-1,j[i-1],i,j[i]); 309 window_gc.drawLine(i-1,j[i-1],i,j[i]); 310 311 if(param.svm_type == svm_parameter.EPSILON_SVR) 312 { 313 buffer_gc.setColor(colors[2]); 314 window_gc.setColor(colors[2]); 315 buffer_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p); 316 window_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p); 317 318 buffer_gc.setColor(colors[2]); 319 window_gc.setColor(colors[2]); 320 buffer_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p); 321 window_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p); 322 } 323 } 324 } 325 else 326 { 327 if(param.gamma == 0) param.gamma = 0.5; 328 prob.x = new svm_node [prob.l][2]; 329 for(int i=0;i<prob.l;i++) 330 { 331 point p = point_list.elementAt(i); 332 prob.x[i][0] = new svm_node(); 333 prob.x[i][0].index = 1; 334 prob.x[i][0].value = p.x; 335 prob.x[i][1] = new svm_node(); 336 prob.x[i][1].index = 2; 337 prob.x[i][1].value = p.y; 338 prob.y[i] = p.value; 339 } 340 341 // build model & classify 342 svm_model model = svm.svm_train(prob, param); 343 svm_node[] x = new svm_node[2]; 344 x[0] = new svm_node(); 345 x[1] = new svm_node(); 346 x[0].index = 1; 347 x[1].index = 2; 348 349 Graphics window_gc = getGraphics(); 350 for (int i = 0; i < XLEN; i++) 351 for (int j = 0; j < YLEN ; j++) { 352 x[0].value = (double) i / XLEN; 353 x[1].value = (double) j / YLEN; 354 double d = svm.svm_predict(model, x); 355 if (param.svm_type == svm_parameter.ONE_CLASS && d<0) d=2; 356 buffer_gc.setColor(colors[(int)d]); 357 window_gc.setColor(colors[(int)d]); 358 buffer_gc.drawLine(i,j,i,j); 359 window_gc.drawLine(i,j,i,j); 360 } 361 } 362 363 draw_all_points(); 364 } 365 button_clear_clicked()366 void button_clear_clicked() 367 { 368 clear_all(); 369 } 370 button_save_clicked(String args)371 void button_save_clicked(String args) 372 { 373 FileDialog dialog = new FileDialog(new Frame(),"Save",FileDialog.SAVE); 374 dialog.setVisible(true); 375 String filename = dialog.getDirectory() + dialog.getFile(); 376 if (filename == null) return; 377 try { 378 DataOutputStream fp = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); 379 380 int svm_type = svm_parameter.C_SVC; 381 int svm_type_idx = args.indexOf("-s "); 382 if(svm_type_idx != -1) 383 { 384 StringTokenizer svm_str_st = new StringTokenizer(args.substring(svm_type_idx+2).trim()); 385 svm_type = atoi(svm_str_st.nextToken()); 386 } 387 388 int n = point_list.size(); 389 if(svm_type == svm_parameter.EPSILON_SVR || svm_type == svm_parameter.NU_SVR) 390 { 391 for(int i=0;i<n;i++) 392 { 393 point p = point_list.elementAt(i); 394 fp.writeBytes(p.y+" 1:"+p.x+"\n"); 395 } 396 } 397 else 398 { 399 for(int i=0;i<n;i++) 400 { 401 point p = point_list.elementAt(i); 402 fp.writeBytes(p.value+" 1:"+p.x+" 2:"+p.y+"\n"); 403 } 404 } 405 fp.close(); 406 } catch (IOException e) { System.err.print(e); } 407 } 408 button_load_clicked()409 void button_load_clicked() 410 { 411 FileDialog dialog = new FileDialog(new Frame(),"Load",FileDialog.LOAD); 412 dialog.setVisible(true); 413 String filename = dialog.getDirectory() + dialog.getFile(); 414 if (filename == null) return; 415 clear_all(); 416 try { 417 BufferedReader fp = new BufferedReader(new FileReader(filename)); 418 String line; 419 while((line = fp.readLine()) != null) 420 { 421 StringTokenizer st = new StringTokenizer(line," \t\n\r\f:"); 422 if(st.countTokens() == 5) 423 { 424 byte value = (byte)atoi(st.nextToken()); 425 st.nextToken(); 426 double x = atof(st.nextToken()); 427 st.nextToken(); 428 double y = atof(st.nextToken()); 429 point_list.addElement(new point(x,y,value)); 430 } 431 else if(st.countTokens() == 3) 432 { 433 double y = atof(st.nextToken()); 434 st.nextToken(); 435 double x = atof(st.nextToken()); 436 point_list.addElement(new point(x,y,current_value)); 437 }else 438 break; 439 } 440 fp.close(); 441 } catch (IOException e) { System.err.print(e); } 442 draw_all_points(); 443 } 444 processMouseEvent(MouseEvent e)445 protected void processMouseEvent(MouseEvent e) 446 { 447 if(e.getID() == MouseEvent.MOUSE_PRESSED) 448 { 449 if(e.getX() >= XLEN || e.getY() >= YLEN) return; 450 point p = new point((double)e.getX()/XLEN, 451 (double)e.getY()/YLEN, 452 current_value); 453 point_list.addElement(p); 454 draw_point(p); 455 } 456 } 457 paint(Graphics g)458 public void paint(Graphics g) 459 { 460 // create buffer first time 461 if(buffer == null) { 462 buffer = this.createImage(XLEN,YLEN); 463 buffer_gc = buffer.getGraphics(); 464 buffer_gc.setColor(colors[0]); 465 buffer_gc.fillRect(0,0,XLEN,YLEN); 466 } 467 g.drawImage(buffer,0,0,this); 468 } 469 getPreferredSize()470 public Dimension getPreferredSize() { return new Dimension(XLEN,YLEN+50); } 471 setSize(Dimension d)472 public void setSize(Dimension d) { setSize(d.width,d.height); } setSize(int w,int h)473 public void setSize(int w,int h) { 474 super.setSize(w,h); 475 XLEN = w; 476 YLEN = h-50; 477 clear_all(); 478 } 479 main(String[] argv)480 public static void main(String[] argv) 481 { 482 new AppletFrame("svm_toy",new svm_toy(),500,500+50); 483 } 484 } 485 486 class AppletFrame extends Frame { AppletFrame(String title, Applet applet, int width, int height)487 AppletFrame(String title, Applet applet, int width, int height) 488 { 489 super(title); 490 this.addWindowListener(new WindowAdapter() { 491 public void windowClosing(WindowEvent e) { 492 System.exit(0); 493 } 494 }); 495 applet.init(); 496 applet.setSize(width,height); 497 applet.start(); 498 this.add(applet); 499 this.pack(); 500 this.setVisible(true); 501 } 502 } 503