2015-11-30 17 views
9

Tôi đang sử dụng LIBSVM. Trong gói tải xuống là tệp svm_toy.java. Tôi không thể tìm ra cách nó hoạt động. Đây là mã nguồn:Làm thế nào để sử dụng ví dụ về 'svm_toy' Applet trong LibSVM?

import libsvm.*; 
import java.applet.*; 
import java.awt.*; 
import java.util.*; 
import java.awt.event.*; 
import java.io.*; 

/** 
* SVM package 
* @author unknown 
* 
*/ 
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); 
    } 

} 

Ai đó có thể cho tôi ví dụ hoặc giải thích? Tôi cũng muốn mở rộng dữ liệu đào tạo của mình. Đâu là nơi thích hợp để mở rộng quy mô?

Cảm ơn

Trả lời

10

SVM-Toy

SVM Toy là - như tên cho thấy - một đơn giản đồ chơi xây dựng bởi đội ngũ LIBSVM dev và là không được khuyến khích để hiển thị "sản xuất" ranh giới quyết định của SVM.

Hơn nữa, hãy xem mã nguồn của svm_toy nó trở nên rõ ràng, rằng công cụ này chỉ hỗ trợ vectơ 2D.

đoạn mã có liên quan được lấy từ Phương pháp button_load_clicked():

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

Như bạn có thể thấy, việc thực hiện svm_toy chỉ có thể xử lý vectơ 2D, có nghĩa là nó chỉ hỗ trợ vectơ, được xây dựng trên hai tính năng.

Điều đó có nghĩa, bạn chỉ có thể đọc và hiển thị các tệp được xây dựng từ chỉ hai tính năng như ví dụ: số liệu fourclass do các tác giả LIBSVM cung cấp. Tuy nhiên có vẻ như, tính năng này không được hỗ trợ trong quá trình triển khai này.

Tôi nghĩ rằng, công cụ được thiết kế để hiển thị tương tác. Bạn có thể thay đổi màu sắc và nhấp vào màn hình ứng dụng màu đen. Sau khi bạn thiết lập một số điểm (mỗi màu đại diện cho một lớp riêng), bạn có thể nhấp vào "chạy" và ranh giới quyết định được hiển thị.

Two random clicked data sets

Decision boundary is shown after clicking on "run"

Hiển thị các ranh giới desicion trong một không gian vector chiều cao thậm chí còn gần như không thể. Tôi khuyên bạn không nên sử dụng công cụ này cho bất kỳ mục đích sản xuất/khoa học nào.

Scaling

Scaling của dữ liệu huấn luyện của bạn nên được thực hiện sau khi bạn chuyển nó vào đó là đại diện số và trước khi bạn đang đi về phía trước để huấn luyện SVM của bạn với dữ liệu này.

Nói tóm lại đó có nghĩa là, bạn phải làm các bước sau đây trước khi sử dụng svm_train

  1. Xây dựng các đại diện số cho mỗi điểm dữ liệu (với sự giúp đỡ của lựa chọn tính năng, ...)
  2. Phân tích kết quả đại diện số cho mỗi điểm dữ liệu
  3. Scale dữ liệu của bạn ví dụ như [-1,1]
  4. Đi trước và đào tạo mô hình SVM của bạn. Lưu ý tốt, bạn phải lặp lại 1-3 để dự đoán các điểm dữ liệu không xác định. Sự khác biệt duy nhất là, bạn đã biết các tính năng cần thiết, vì vậy không cần lựa chọn tính năng.
+1

cảm ơn câu trả lời tuyệt vời! –

Các vấn đề liên quan