https://www.csie.ntu.edu.tw/~cjlin/libsvm/
http://ntu.csie.org/~piaip/svm/svm_tutorial.html
https://www.csie.ntu.edu.tw/~cjlin/libsvm/#download
實作一 參數
protected void onCreate(Bundle savedInstanceState) { _param = new svm_parameter(); _param.svm_type = svm_parameter.C_SVC; _param.kernel_type = svm_parameter.LINEAR; _param.degree = 3; _param.gamma = 0; // 1/num_features _param.coef0 = 0; _param.nu = 0.5; _param.cache_size = 100; _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];
實作二 訓練
protected void training(){ loadData(true); //這邊呼叫loadData(),使用true參數是因為在training階段 //透過loadData,將資料庫的資料儲存在全域變數_prob裡面 System.out.print("Training..."); _model_file = "/sdcard/svm_model.txt"; //指定SVM model儲存的檔案名稱 svm_model model = svm.svm_train(_prob, _param); //訓練SVM model System.out.println("Done!!(training)"); textView.setText("svm_model loaded"); try { svm.svm_save_model(_model_file, model); //將訓練結果寫入檔案 }catch (IOException e){ } } protected void loadData(boolean is_training){ String limit; if(is_training){ //訓練階段 System.out.print("Loading training data..."); limit = " WHERE id <= 4700"; }else{ //測試階段 System.out.print("Loading testing data..."); limit = " WHERE id > 4700"; } int max_index = 0; //紀錄資料中最大的維度(用來產生gamma參數) _prob = new svm_problem(); Vector vy = new Vector(); Vector vx = new Vector(); vy.add("1"); vy.add("2");//labal為資料的標籤,為-1或+1 //SVM通常就是解決是好(+1)或壞(-1)的問題 //讀取兩個維度的資料,這裡只有「有這個維度(true)」與「沒有這個維度(false)」 //因此兩個欄位只填寫維度的index,例如填寫30,就代表第30維有資料 //假設rdk1=30,rdk2=2789,則這個node只有這兩個維的值是true, //其他2998維(比如第31, 32...維)的值都是false svm_node[] x = new svm_node[3]; //建立SVM node的陣列 x[0] = new svm_node(); x[0].index = color_r; //維度的index例如30 x[0].value = 15.0; //有值,為true x[1] = new svm_node(); x[1].index = color_g; //維度的index例如2789 x[1].value = 163.0; x[2] = new svm_node(); x[2].index = color_b; //維度的index例如2789 x[2].value = 15.0; vx.add(x); //儲存SVM node的陣列 svm_node[] y = new svm_node[3]; y[0] = new svm_node(); y[0].index = color_r; //維度的index例如30 y[0].value = 255.0; //有值,為true y[1] = new svm_node(); y[1].index = color_g; //維度的index例如2789 y[1].value = 42.0; y[2] = new svm_node(); y[2].index = color_b; //維度的index例如2789 y[2].value = 0.0; vx.add(y); svm_node[] z = new svm_node[3]; z[0] = new svm_node(); z[0].index = color_r; //維度的index例如30 z[0].value = 255.0; //有值,為true z[1] = new svm_node(); z[1].index = color_g; //維度的index例如2789 z[1].value = 255.0; z[2] = new svm_node(); z[2].index = color_b; //維度的index例如2789 z[2].value = 255.0; vx.add(z); _prob.l = vy.size(); //svm node的數量 _prob.x = new svm_node[_prob.l][]; _prob.x[0] = (svm_node[]) vx.get(0); _prob.x[1] = (svm_node[]) vx.get(1); // for(int i=0;i<_prob.l;i++) _prob.x[i] = (svm_node[]) vx.elementAt(i); //儲存每個node的向量 _prob.y = new double[_prob.l]; // for(int i=0;i<_prob.l;i++) _prob.y[i] =(double) vy.elementAt(i); //儲存每個node的label / _prob.y[0]=1.01; _prob.y[1]=2.02; System.out.println("Done!!(ReadData)"); }實作三 測試
protected int touch_testing(){ // loadData(false); //讀取剩下的300分資料,轉換成SVM問題(存在_prob裡) double v; svm_model model; int correct = 0, total = 0; try { model = svm.svm_load_model(_model_file); //載入model textView.setText("svm_model loaded"); textView.setText("_prob = " + _prob.l); svm_node[] x = new svm_node[3]; //建立SVM node的陣列 x[0] = new svm_node(); x[0].index = color_r; //維度的index例如30 x[0].value = r; //有值,為true x[1] = new svm_node(); x[1].index = color_g; //維度的index例如2789 x[1].value = g; x[2] = new svm_node(); x[2].index = color_b; //維度的index例如2789 x[2].value = b; Log.i(TAG, "Texting color: (" + r + ", " + g + ", " + b + ")"); v = svm.svm_predict(model, x); //把node餵給預測器 Log.i(TAG, "svm_predict: (" + v + ")"); //這時預測器會依照model與node內的向量資訊,產生預測的數值(-1或1) int v_to_int = (int) v ; switch (v_to_int){ case 1: return 1; default: return 0; }