public static svm_model svm_load_model(String model_file_name) throws IOException { BufferedReader fp = new BufferedReader(new FileReader(model_file_name)); // read parameters svm_model model = new svm_model(); svm_parameter param = new svm_parameter(); model.param = param; model.label = null; model.nSV = null; while(true) { String cmd = fp.readLine(); String arg = cmd.substring(cmd.indexOf(' ')+1); if(cmd.startsWith("svm_type")) { int i; for(i=0;i<svm_type_table.length;i++) { if(arg.indexOf(svm_type_table[i])!=-1) { param.svm_type=i; break; } } if(i == svm_type_table.length) { System.err.print("unknown svm type.\n"); System.exit(1); } } else if(cmd.startsWith("kernel_type")) { int i; for(i=0;i<kernel_type_table.length;i++) { if(arg.indexOf(kernel_type_table[i])!=-1) { param.kernel_type=i; break; } } if(i == kernel_type_table.length) { System.err.print("unknown kernel function.\n"); System.exit(1); } } else if(cmd.startsWith("degree")) param.degree = atof(arg); else if(cmd.startsWith("gamma")) param.gamma = atof(arg); else if(cmd.startsWith("coef0")) param.coef0 = atof(arg); else if(cmd.startsWith("nr_class")) model.nr_class = atoi(arg); else if(cmd.startsWith("total_sv")) model.l = atoi(arg); else if(cmd.startsWith("rho")) { int n = model.nr_class * (model.nr_class-1)/2; model.rho = new double[n]; StringTokenizer st = new StringTokenizer(arg); for(int i=0;i<n;i++) model.rho[i] = atof(st.nextToken()); } else if(cmd.startsWith("label")) { int n = model.nr_class; model.label = new int[n]; StringTokenizer st = new StringTokenizer(arg); for(int i=0;i<n;i++) model.label[i] = atoi(st.nextToken()); } else if(cmd.startsWith("nr_sv")) { int n = model.nr_class; model.nSV = new int[n]; StringTokenizer st = new StringTokenizer(arg); for(int i=0;i<n;i++) model.nSV[i] = atoi(st.nextToken()); } else if(cmd.startsWith("SV")) { break; } else { System.err.print("unknown text in model file\n"); System.exit(1); } } // read sv_coef and SV int m = model.nr_class - 1; int l = model.l; model.sv_coef = new double[m][l]; model.SV = new svm_node[l][]; for(int i=0;i<l;i++) { String line = fp.readLine(); StringTokenizer st = new StringTokenizer(line," \t\n\r\f:"); for(int k=0;k<m;k++) model.sv_coef[k][i] = atof(st.nextToken()); int n = st.countTokens()/2; model.SV[i] = new svm_node[n]; for(int j=0;j<n;j++) { model.SV[i][j] = new svm_node(); model.SV[i][j].index = atoi(st.nextToken()); model.SV[i][j].value = atof(st.nextToken()); } } fp.close(); return model; }
// // Interface functions // public static svm_model svm_train(svm_problem prob, svm_parameter param) { svm_model model = new svm_model(); model.param = param; if(param.svm_type == svm_parameter.ONE_CLASS || param.svm_type == svm_parameter.EPSILON_SVR || param.svm_type == svm_parameter.NU_SVR) { // regression or one-class-svm model.nr_class = 2; model.label = null; model.nSV = null; model.sv_coef = new double[1][]; decision_function f = svm_train_one(prob,param,0,0); model.rho = new double[1]; model.rho[0] = f.rho; int nSV = 0; int i; for(i=0;i<prob.l;i++) if(Math.abs(f.alpha[i]) > 0) ++nSV; model.l = nSV; model.SV = new svm_node[nSV][]; model.sv_coef[0] = new double[nSV]; int j = 0; for(i=0;i<prob.l;i++) if(Math.abs(f.alpha[i]) > 0) { model.SV[j] = prob.x[i]; model.sv_coef[0][j] = f.alpha[i]; ++j; } } else { // classification // find out the number of classes int l = prob.l; int max_nr_class = 16; int nr_class = 0; int[] label = new int[max_nr_class]; int[] count = new int[max_nr_class]; int[] index = new int[l]; int i; for(i=0;i<l;i++) { int this_label = (int)prob.y[i]; int j; for(j=0;j<nr_class;j++) if(this_label == label[j]) { ++count[j]; break; } index[i] = j; if(j == nr_class) { if(nr_class == max_nr_class) { max_nr_class *= 2; int[] new_data = new int[max_nr_class]; System.arraycopy(label,0,new_data,0,label.length); label = new_data; new_data = new int[max_nr_class]; System.arraycopy(count,0,new_data,0,count.length); count = new_data; } label[nr_class] = this_label; count[nr_class] = 1; ++nr_class; } } // group training data of the same class int[] start = new int[nr_class]; start[0] = 0; for(i=1;i<nr_class;i++) start[i] = start[i-1]+count[i-1]; svm_node[][] x = new svm_node[l][]; for(i=0;i<l;i++) { x[start[index[i]]] = prob.x[i]; ++start[index[i]]; } start[0] = 0; for(i=1;i<nr_class;i++) start[i] = start[i-1]+count[i-1]; // calculate weighted C double[] weighted_C = new double[nr_class]; for(i=0;i<nr_class;i++) weighted_C[i] = param.C; for(i=0;i<param.nr_weight;i++) { int j; for(j=0;j<nr_class;j++) if(param.weight_label[i] == label[j]) break; if(j == nr_class) System.err.print("warning: class label "+param.weight_label[i]+" specified in weight is not found\n"); else weighted_C[j] *= param.weight[i]; } // train n*(n-1)/2 models boolean[] nonzero = new boolean[l]; for(i=0;i<l;i++) nonzero[i] = false; decision_function[] f = new decision_function[nr_class*(nr_class-1)/2]; int p = 0; for(i=0;i<nr_class;i++) for(int j=i+1;j<nr_class;j++) { svm_problem sub_prob = new svm_problem(); int si = start[i], sj = start[j]; int ci = count[i], cj = count[j]; sub_prob.l = ci+cj; sub_prob.x = new svm_node[sub_prob.l][]; sub_prob.y = new double[sub_prob.l]; int k; for(k=0;k<ci;k++) { sub_prob.x[k] = x[si+k]; sub_prob.y[k] = +1; } for(k=0;k<cj;k++) { sub_prob.x[ci+k] = x[sj+k]; sub_prob.y[ci+k] = -1; } f[p] = svm_train_one(sub_prob,param,weighted_C[i],weighted_C[j]); for(k=0;k<ci;k++) if(!nonzero[si+k] && Math.abs(f[p].alpha[k]) > 0) nonzero[si+k] = true; for(k=0;k<cj;k++) if(!nonzero[sj+k] && Math.abs(f[p].alpha[ci+k]) > 0) nonzero[sj+k] = true; ++p; } // build output model.nr_class = nr_class; model.label = new int[nr_class]; for(i=0;i<nr_class;i++) model.label[i] = label[i]; model.rho = new double[nr_class*(nr_class-1)/2]; for(i=0;i<nr_class*(nr_class-1)/2;i++) model.rho[i] = f[i].rho; int nnz = 0; int[] nz_count = new int[nr_class]; model.nSV = new int[nr_class]; for(i=0;i<nr_class;i++) { int nSV = 0; for(int j=0;j<count[i];j++) if(nonzero[start[i]+j]) { ++nSV; ++nnz; } model.nSV[i] = nSV; nz_count[i] = nSV; } System.out.print("Total nSV = "+nnz+"\n"); model.l = nnz; model.SV = new svm_node[nnz][]; p = 0; for(i=0;i<l;i++) if(nonzero[i]) model.SV[p++] = x[i]; int[] nz_start = new int[nr_class]; nz_start[0] = 0; for(i=1;i<nr_class;i++) nz_start[i] = nz_start[i-1]+nz_count[i-1]; model.sv_coef = new double[nr_class-1][]; for(i=0;i<nr_class-1;i++) model.sv_coef[i] = new double[nnz]; p = 0; for(i=0;i<nr_class;i++) for(int j=i+1;j<nr_class;j++) { // classifier (i,j): coefficients with // i are in sv_coef[j-1][nz_start[i]...], // j are in sv_coef[i][nz_start[j]...] int si = start[i]; int sj = start[j]; int ci = count[i]; int cj = count[j]; int q = nz_start[i]; int k; for(k=0;k<ci;k++) if(nonzero[si+k]) model.sv_coef[j-1][q++] = f[p].alpha[k]; q = nz_start[j]; for(k=0;k<cj;k++) if(nonzero[sj+k]) model.sv_coef[i][q++] = f[p].alpha[ci+k]; ++p; } } return model; }