Пример #1
0
/**
 * Return parameter of a Laplace distribution
 */
double SVM_SVMType_SVR::svm_svr_probability(const SVM_Problem & prob, const SVM_Parameter & param) const {
    unsigned int i;
    unsigned int nr_fold = 5;
    std::vector<double> ymv(prob.dimension);
    double mae = 0;

    SVM_Parameter newparam = param;
    newparam.probability = 0;
    svm_cross_validation(prob, newparam, nr_fold, ymv);
    for (i = 0; i < prob.dimension; i++) {
        ymv[i] = prob.labels[i] - ymv[i];
        mae += fabs(ymv[i]);
    }
    mae /= prob.dimension;
    double std = sqrt(2 * mae * mae);
    int count = 0;
    mae = 0;
    double threshold = 5 * std;
    for (unsigned i = 0; i < prob.dimension; ++i) {
        double fabsi = fabs(ymv[i]);
        if (fabsi > threshold) {
            ++count;
        } else {
            mae += fabsi;
        }
    }
    mae /= (prob.dimension - count);
    std::cout << "Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma= " << mae << "\n";
    ymv.clear();
    return mae;
}
Пример #2
0
static VALUE cModel_class_cross_validation(VALUE cls, VALUE problem, VALUE parameter, VALUE num_fold)
{
  const struct svm_problem *prob;
  const struct svm_parameter *param;
  int nr_fold, i;
  double *target_ptr;
  VALUE target;

  Data_Get_Struct(problem, struct svm_problem, prob);
  Data_Get_Struct(parameter, struct svm_parameter, param);
  
  nr_fold = NUM2INT(num_fold);

  target = rb_ary_new2(prob->l);
  target_ptr = (double *)calloc(prob->l, sizeof(double));
  if(target_ptr == 0) {
    rb_raise(rb_eNoMemError, "on cross-validation result allocation" " %s:%i", __FILE__,__LINE__);
  }

  svm_cross_validation(prob, param, nr_fold, target_ptr);

  for(i = 0; i < prob->l; ++i) {
    rb_ary_push(target, rb_float_new(*(target_ptr+i)));
  }

  free(target_ptr);

  return target;
}
Пример #3
0
svm_classifier_t *svm_finish_classifier(svm_classifier_t *svm) {
    int i, j, nr_fold=5, total_correct, best_correct=0, best_c=svm->param.C, best_g=svm->param.gamma;
    const char *error_msg;
    double *result = (double *) rs_malloc(sizeof(double)*svm->problem.l,"cross validation result");

    rs_msg("Building SVM classifier...");

    if (svm->finished)
	rs_warning("SVM classifier is already trained!");

    error_msg = svm_check_parameter(&(svm->problem),&(svm->param));
    
    if(error_msg) 
	rs_error("%s",error_msg);
    
    /* Skalierung */
    _create_scaling(svm->problem,svm->feature_dim,&(svm->max),&(svm->min));
    
    for (i=0;i<svm->problem.l;i++) 
	_scale_instance(&(svm->problem.x[i]),svm->feature_dim,svm->max,svm->min);
    
    /* Cross-Validation, um C und G zu bestimmen bei RBF-Kernel */
    if (svm->param.kernel_type == RBF) {
	svm->param.probability = 0;
	for (i=0;i<C_G_ITER;i++) {
	    total_correct=0;
	    svm->param.C=pow(2,C[i]);
	    svm->param.gamma=pow(2,G[i]);
	    svm_cross_validation(&(svm->problem),&(svm->param),nr_fold,result);
	    for(j=0;j<svm->problem.l;j++) {
		if(result[j] == svm->problem.y[j])
		    ++total_correct;
	    }
	    if (total_correct > best_correct) {
		best_correct=total_correct;
		best_c=C[i];
		best_g=G[i];
	    }
	    rs_msg("C-G-Selektion-Iteration # %d: tried c=%g and g=%g => CV rate is %g; current best c=%g and g=%g with CV rate %g",i+1,pow(2,C[i]),pow(2,G[i]),total_correct*100.0/svm->problem.l,pow(2,best_c),pow(2,best_g),best_correct*100.0/svm->problem.l);
	}
	
	/* Training */
	svm->param.C=pow(2,best_c);
	svm->param.gamma=pow(2,best_g);
	svm->param.probability = 1;
    }
    
    svm->model=svm_train(&(svm->problem),&(svm->param));
    svm->finished=1;

	// @begin_add_johannes
	rs_free (result);
	// @end_add_johannes

    return svm;
}
double do_crossvalidation(struct svm_problem * p_km)
{
			double rate;

			int i;
			int total_correct = 0;
			double total_error = 0;
			double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
			double *target = Malloc(double,prob.l);

			svm_cross_validation(p_km,&param,nr_fold,target);


			if(param.svm_type == EPSILON_SVR ||
				param.svm_type == NU_SVR)
			{
				for(i=0;i<prob.l;i++)
				{
					double y = prob.y[i];
					double v = target[i];
					total_error += (v-y)*(v-y);
					sumv += v;
					sumy += y;
					sumvv += v*v;
					sumyy += y*y;
					sumvy += v*y;
				}
				printf("Cross Validation Mean squared error = %g\n",total_error/prob.l);
				printf("Cross Validation Squared correlation coefficient = %g\n",
								((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/
								((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy))
								);
			}
			else
			{
				for(i=0;i<prob.l;i++)
					if(target[i] == prob.y[i])
						++total_correct;

				rate = (100.0*total_correct)/prob.l;


			}
			free(target);

			
			return rate;

}
Пример #5
0
/*@returns:  cross validation error
 *
 *
 */
double SVM::crossValidationSamples(struct svm_problem &strSvmProblem, struct svm_parameter &strParameters, int iNrfold)
{
	int i;
	int total_correct = 0;
	double total_error = 0;
	double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
	double *target = Malloc(double,strSvmProblem.l);
	double dCrossValError = -1;

	svm_cross_validation(&strSvmProblem,&strParameters,iNrfold,target);

	if(strParameters.svm_type == EPSILON_SVR ||	strParameters.svm_type == NU_SVR)
	{
		for(i=0;i<strSvmProblem.l;i++)
		{
			double y = strSvmProblem.y[i];
			double v = target[i];
			total_error += (v-y)*(v-y);
			sumv += v;
			sumy += y;
			sumvv += v*v;
			sumyy += y*y;
			sumvy += v*y;
		}

		dCrossValError = total_error/(double)strSvmProblem.l;

		printf("Cross Validation Mean squared error = %g\n", dCrossValError);
		printf("Cross Validation Squared correlation coefficient = %g\n",
			((strSvmProblem.l*sumvy-sumv*sumy)*(strSvmProblem.l*sumvy-sumv*sumy))/
			((strSvmProblem.l*sumvv-sumv*sumv)*(strSvmProblem.l*sumyy-sumy*sumy))
			);
	}
	else
	{
		for(i=0;i<strSvmProblem.l;i++)
			if(target[i] == strSvmProblem.y[i])
				++total_correct;

		dCrossValError = 1 - ((double)total_correct/(double)strSvmProblem.l);
		printf("Cross Validation Accuarcy = %lf%%\n", 100*(1-dCrossValError));
	}

	free(target);

	return dCrossValError;
}
Пример #6
0
    virtual void Learn(IDataSet* data) {
        vector< vector<double> > features = PreprocessFeatures(data);

        vector<int> targets;
        for (int i = 0; i < data->GetObjectCount(); i++)
            targets.push_back(data->GetTarget(i));

        train_prob = sh_ptr<svm_problem_xx>(new svm_problem_xx(features, targets));

        double c_values[] = { 2048, 32768 };
        double gamma_values[] = { 3.0517578125e-05, 0.0001220703125 };

        svm_parameter best_param;
        double best_accuracy = -1;

        // select hyperparameters (regularization coefficient C and kernel parameter gamma) by 10-fold crossvalidation
        for (int c_index = 0; c_index < ARRAY_SIZE(c_values); c_index++) {
            for (int gamma_index = 0; gamma_index < ARRAY_SIZE(gamma_values); gamma_index++) {
                svm_parameter param;
                memset(&param, 0, sizeof(param));
                param.svm_type = C_SVC;
                param.kernel_type = RBF;
                param.C = c_values[c_index];
                param.gamma = gamma_values[gamma_index];
                param.cache_size = 100;
                param.eps = 1e-3;
                param.shrinking = 1;

                vector<double> res(targets.size());
                svm_cross_validation(train_prob.get(), &param, 10, &res[0]);

                double accuracy = 0;
                for (int i = 0; i < res.size(); i++)
                    if (res[i] == targets[i])
                        accuracy += 1;
                accuracy /= res.size();

                if (accuracy > best_accuracy) {
                    best_accuracy = accuracy;
                    best_param = param;
                }
            }
        }

        model = sh_ptr<svm_model_xx>(new svm_model_xx(svm_train(train_prob.get(), &best_param)));
    }
Пример #7
0
static void cmd_cross(int nFold, double cParam, double gParam,
                      WindowFile &trainA, WindowFile &trainB)
{
    SVMProblem problem(trainA, trainB);
    SVMParam param(cParam, gParam);
    double *target = new double[problem.l];
    svm_cross_validation(&problem, &param, nFold, target);

    int correct = 0;
    for(int i = 0; i < problem.l; i++)
        if(target[i] == problem.y[i])
            ++correct;

    delete [] target;

    fprintf(stderr, "Cross Validation Accuracy = %g%%\n",(100.*correct)/problem.l);
}
Пример #8
0
double do_cross_validation()
{
	int i;
	int total_correct = 0;
	double total_error = 0;
	double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
	double *target = Malloc(double,prob.l);
	double retval = 0.0;

	svm_cross_validation(&prob,&param,nr_fold,target);
	if(param.svm_type == EPSILON_SVR ||
	   param.svm_type == NU_SVR)
	{
		for(i=0;i<prob.l;i++)
		{
			double y = prob.y[i];
			double v = target[i];
			total_error += (v-y)*(v-y);
			sumv += v;
			sumy += y;
			sumvv += v*v;
			sumyy += y*y;
			sumvy += v*y;
		}
		mexPrintf("Cross Validation Mean squared error = %g\n",total_error/prob.l);
		mexPrintf("Cross Validation Squared correlation coefficient = %g\n",
			((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/
			((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy))
			);
		retval = total_error/prob.l;
	}
	else
	{
		for(i=0;i<prob.l;i++)
			if(target[i] == prob.y[i])
				++total_correct;
		mexPrintf("Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob.l);
		retval = 100.0*total_correct/prob.l;
	}
	free(target);
	return retval;
}
void svm_do_cross_validation(const svm_parameter& param, const svm_problem& prob,int nr_fold)
{
    int i;
    int total_correct = 0;
    double total_error = 0;
    double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
    double *target = new double[prob.l];
    memset(target, 0, sizeof(double)*prob.l);
    
    svm_cross_validation(&prob, &param, nr_fold, target);
    
    if(param.svm_type == EPSILON_SVR ||
       param.svm_type == NU_SVR)
    {
        for(i=0;i<prob.l;i++)
        {
            double y = prob.y[i];
            double v = target[i];
            total_error += (v-y)*(v-y);
            sumv += v;
            sumy += y;
            sumvv += v*v;
            sumyy += y*y;
            sumvy += v*y;
        }
        printf("Cross Validation Mean squared error = %g\n",total_error/prob.l);
        printf("Cross Validation Squared correlation coefficient = %g\n",
               ((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/
               ((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy))
               );
    }
    else
    {
        for(i=0;i<prob.l;i++)
            if(target[i] == prob.y[i])
                ++total_correct;
        printf("Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob.l);
    }
    delete [] target;
}
Пример #10
0
    // does cross validation using the parameters obtained or default ones
    double ML2::do_cross_validation()
    {
	    int i;
	    int total_correct = 0;
	    double total_error = 0;
	    double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
	    double *target = Malloc(double,prob.l);
        //this uses the nr_folds set in the train method
	    svm_cross_validation(&prob,&param,nr_fold,target);
        
	    if(param.svm_type == EPSILON_SVR ||
	       param.svm_type == NU_SVR)
	    {
		    for(i=0;i<prob.l;i++)
		    {
			    double y = prob.y[i];
			    double v = target[i];
                //printf("actual y : %f, predicted value %f \n", y, v );
			    total_error += (v-y)*(v-y);
			    sumv += v;
			    sumy += y;
			    sumvv += v*v;
			    sumyy += y*y;
			    sumvy += v*y;
		    }
            //print the error rates
		    cout<<"Cross Validation Mean squared error = "<<total_error/prob.l<<endl<<flush;
            cout<<"Cross Validation Root Mean squared error = "<<sqrt(total_error/prob.l) <<endl<<flush;
		    cout<<"Cross Validation Squared correlation coefficient = "<<
			    ((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/
			    ((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy))
			     <<endl<<flush;
	    }
	    
	    free(target);

        return sqrt(total_error/prob.l);
    }
Пример #11
0
void do_cross_validation(struct svm_problem *prob, struct svm_parameter *param,int nr_fold){
	int i;
	int total_correct = 0;
	double total_error = 0;
	double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
	double *target = Malloc(double,prob->l);

	svm_cross_validation(prob,param,nr_fold,target);
	if(param->svm_type == EPSILON_SVR ||
	   param->svm_type == NU_SVR)
	{
		for(i=0;i<prob->l;i++)
		{
			double y = prob->y[i];
			double v = target[i];
			total_error += (v-y)*(v-y);
			sumv += v;
			sumy += y;
			sumvv += v*v;
			sumyy += y*y;
			sumvy += v*y;
		}
		elog(INFO,"Cross Validation Mean squared error = %g\n",total_error/prob->l);
		elog(INFO,"Cross Validation Squared correlation coefficient = %g\n",
			((prob->l*sumvy-sumv*sumy)*(prob->l*sumvy-sumv*sumy))/
			((prob->l*sumvv-sumv*sumv)*(prob->l*sumyy-sumy*sumy))
			);
	}
	else
	{
		for(i=0;i<prob->l;i++)
			if(target[i] == prob->y[i])
				++total_correct;
		elog(INFO,"Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob->l);
	}
	pgm_free(target);
}
Пример #12
0
std::vector< std::pair<size_t, size_t> > tune_params_single(
        const double* divs, size_t num_bags,
        const std::vector<label_type> &labels,
        const Kernel * const * kernels, size_t num_kernels,
        const std::vector<double> &c_vals,
        svm_parameter svm_params,
        size_t folds,
        double *final_score)
{
    typedef std::pair<size_t, size_t> config;

    // this only works for int or double label_types
    BOOST_STATIC_ASSERT((
        boost::is_same<label_type, int>::value ||
        boost::is_same<label_type, double>::value
    ));

    // keep track of the best kernel/C combos
    // keep all with same acc, to avoid bias towards ones we see earlier
    std::vector<config> best_configs;
    double best_score = -std::numeric_limits<double>::infinity();

    if (num_kernels == 0) {
        *final_score = best_score;
        return best_configs;
    }

    // make our svm_problem that we'll be reusing throughout
    size_t num_train = labels.size();
    if (num_train > num_bags) {
        throw std::invalid_argument("tune_params: more labels than bags");
    }

    svm_problem *prob = new svm_problem;
    prob->l = num_train;
    prob->y = new double[num_train];
    for (size_t i = 0; i < num_train; i++)
        prob->y[i] = (double) labels[i];

    // store un-transformed divs in the problem just so it's all allocated
    store_kernel_matrix(*prob, divs, true);

    // make a copy of divergences so we can mangle it
    double *km = new double[num_bags * num_bags];
    double *km_train = (num_train < num_bags) ?
                       new double[num_train * num_train] : km;

    // used to store labels into during CV
    double *cv_labels = new double[num_train];

    for (size_t k = 0; k < num_kernels; k++) {
        // turn into a kernel matrix
        std::copy(divs, divs + num_bags * num_bags, km);
        kernels[k]->transformDivergences(km, num_bags);
        project_to_symmetric_psd(km, num_bags);

        // is it a constant matrix or something else awful?
        if (terrible_kernel(km, num_bags)) {
            FILE_LOG(logDEBUG1) << "tuning: skipping terrible kernel "
                << kernels[k]->name();
            continue;
        }

        // copy the top-left corner into km_train if necessary
        if (km_train != km)
            copy_upper(km, km_train, num_bags, num_train);

        // store in the svm_problem
        store_kernel_matrix(*prob, km_train, false);

        // TODO: add epsilon-SVR's epsilon (svm_params.p) to the grid search
        // (preferably by generalizing this notion of parameter tuning)
        for (size_t ci = 0; ci < c_vals.size(); ci++) {
            // do SVM cross-validation with these params
            svm_params.C = c_vals[ci];
            svm_cross_validation(prob, &svm_params, folds, cv_labels);

            double score = 0;

            if (boost::is_same<label_type, int>::value) {
                // integer type; get classification accuracy
                for (size_t i = 0; i < num_train; i++)
                    if (cv_labels[i] == labels[i])
                        score++;

                FILE_LOG(logDEBUG2) << "tuning: " <<
                    score << "/" << num_train
                     << " by " << kernels[k]->name() << ", C = " << c_vals[ci];


            } else {
                // double type; get *negative* squared err (so max is best)
                for (size_t i = 0; i < num_train; i++) {
                    double diff = cv_labels[i] - labels[i];
                    score -= diff * diff;
                }

                FILE_LOG(logDEBUG2) << "tuning: " << score
                     << " by " << kernels[k]->name() << ", C = " << c_vals[ci];
            }

            if (score >= best_score) {
                if (score > best_score) {
                    best_configs.clear();
                    best_score = score;
                }
                best_configs.push_back(std::make_pair(k, ci));
            }
        }
    }

    if (km_train != km)
        delete[] km_train;
    delete[] km;
    delete[] cv_labels;

    for (size_t i = 0; i < num_train; i++)
        delete[] prob->x[i];
    delete[] prob->x;
    delete[] prob->y;
    delete prob;

    *final_score = best_score;
    return best_configs;
}
Пример #13
0
void SVMTrainModel::do_cross_validation(double &RecRate, std::vector<int> &ConfusionTable)
{
  int i;
  int total_correct = 0;
  double total_error = 0;
  double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
  double *target = Malloc(double,prob.l);
  
  svm_cross_validation(&prob,&param,nr_fold,target);
  if(param.svm_type == EPSILON_SVR ||
    param.svm_type == NU_SVR)
  {
    for(i=0;i<prob.l;i++)
    {
      double y = prob.y[i];
      double v = target[i];
      total_error += (v-y)*(v-y);
      sumv += v;
      sumy += y;
      sumvv += v*v;
      sumyy += y*y;
      sumvy += v*y;
    }
    printf("Cross Validation Mean squared error = %g\n",total_error/prob.l);
    printf("Cross Validation Squared correlation coefficient = %g\n",
           ((prob.l*sumvy-sumv*sumy)*(prob.l*sumvy-sumv*sumy))/
           ((prob.l*sumvv-sumv*sumv)*(prob.l*sumyy-sumy*sumy))
    );
  }
  else
  {
    ConfusionTable.at(0) = 0; ConfusionTable.at(1) = 0; ConfusionTable.at(2) = 0; ConfusionTable.at(3) = 0;
    for(i=0;i<prob.l;i++)
    {
      if(target[i] == prob.y[i])
      {
        ++total_correct;
        if(target[i] == 0)
        {
          ConfusionTable.at(0) += 1;
        }
        else
        {
          ConfusionTable.at(3) += 1;
        }
      }
      else
      {
        if(target[i] == 0)
        {
          ConfusionTable.at(2) += 1;
        }
        else
        {
          ConfusionTable.at(1) += 1;
        }
      }
    }
      //printf("Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob.l);
    RecRate = 100.0*total_correct/prob.l;
  }
  free(target);
}
Пример #14
0
void BagOfFeatures::trainSVM(int type = NU_SVC,
                            int kernel = RBF,
                            double degree = 0.05,
                            double gamma = 0.25,
                            double coef0 = 0.5,
                            double C = .05,
                            double cache = 300,
                            double eps = 0.000001,
                            double nu = 0.5,
                            int shrinking = 0,
                            int probability = 0,
                            int weight = 0)
{
    if(SVMModel != NULL)
    {
        svm_destroy_model(SVMModel);
        //svm_destroy_param(&SVMParam);
    }




    int i, j, k, l = -1;
    int totalData = 0;
    int size, length = dictionary->rows;
    int count;
    //Get the total number of training data
    for(i = 0; i < numClasses; i++)
        totalData += data[i].getTrainSize();

    // Set up the data
    struct svm_problem SVMProblem;
    SVMProblem.l = totalData;
    SVMProblem.y = new double [totalData];
    SVMProblem.x = new struct svm_node* [totalData];
    // Allocate memory
    //for(i = 0; i < totalData; i++)
    //{
    //    SVMProblem.x[i] = new struct svm_node [length+1];
    //}

    // For each class
    for(i = 0; i < numClasses; i++)
    {
        // Get the number of images
        size = data[i].getTrainSize();
        for(j = 0; j < size; j++)
        {
            l++;
            count = 0;
            for(k = 0; k < length; k++)
            {
                if(trainObject[i].histogramSet.histogram[j][k] != 0)
                    count++;
            }
            SVMProblem.x[l] = new struct svm_node [count+1];
            count = 0;
            for(k = 0; k < length; k++)
            {
                if(trainObject[i].histogramSet.histogram[j][k] != 0)
                {
                    SVMProblem.x[l][count].index = k;
                    SVMProblem.x[l][count].value = trainObject[i].histogramSet.histogram[j][k];
                    //cout << "(" << SVMProblem.x[l][count].index
                    //    << ", " << SVMProblem.x[l][count].value << ")" << endl;
                    count++;
                }
            }
            SVMProblem.x[l][count].index = -1;
            //cout << endl;
            //SVMProblem.x[l][count].value = -1;
            // Copy the histograms
            //for(k = 0; k < length; k++)
            //{
            //    SVMProblem.x[l][k].index = k;
            //    SVMProblem.x[l][k].value = trainObject[i].histogramSet.histogram[j][k];
            //}
            // End of the data
            //SVMProblem.x[l][length].index = -1;
            //SVMProblem.x[l][length].value = -1;
            //Attach the labels

            SVMProblem.y[l] = data[i].getLabel();
            //cout << "Label: " << SVMProblem.y[l] << endl;
        }
    }

    // Types
    SVMParam.svm_type = type;
    SVMParam.kernel_type = kernel;
    // Parameters
    SVMParam.degree = degree;
    SVMParam.gamma = gamma;
    SVMParam.coef0 = coef0;
    SVMParam.C = C;
    // For training only
    SVMParam.cache_size = cache;
    SVMParam.eps = eps;
    SVMParam.nu = nu;
    SVMParam.shrinking = shrinking;
    SVMParam.probability = probability;
    // Don't change the weights
    SVMParam.nr_weight = weight;


    double* target = new double [totalData];
    svm_check_parameter(&SVMProblem, &SVMParam);
    svm_cross_validation(&SVMProblem, &SVMParam, 10, target);
    SVMModel = svm_train(&SVMProblem, &SVMParam);
    delete [] target;

    classifierType = LIBSVM_CLASSIFIER;

}
bool SVM::trainSVM(){

    crossValidationResult = 0;

    //Erase any previous models
    if( trained ){
        svm_free_and_destroy_model(&model);
        trained = false;
    }

    //Check to make sure the problem has been set
    if( !problemSet ){
        errorLog << "trainSVM() - Problem not set!" << endl;
        return false;
    }
    
    //Verify the problem and the parameters
    if( !validateProblemAndParameters() ) return false;

    //Scale the training data if needed
    if( useScaling ){
        for(int i=0; i<prob.l; i++)
            for(UINT j=0; j<numInputDimensions; j++)
                prob.x[i][j].value = scale(prob.x[i][j].value,ranges[j].minValue,ranges[j].maxValue,SVM_MIN_SCALE_RANGE,SVM_MAX_SCALE_RANGE);
    }

    if( useCrossValidation ){
        int i;
        double total_correct = 0;
        double total_error = 0;
        double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
        double *target = new double[prob.l];

        svm_cross_validation(&prob,&param,kFoldValue,target);
        if( param.svm_type == EPSILON_SVR || param.svm_type == NU_SVR )
        {
            for(i=0;i<prob.l;i++)
            {
                double y = prob.y[i];
                double v = target[i];
                total_error += (v-y)*(v-y);
                sumv += v;
                sumy += y;
                sumvv += v*v;
                sumyy += y*y;
                sumvy += v*y;
            }
            crossValidationResult = total_error/prob.l;
        }
        else
        {
            for(i=0;i<prob.l;i++){
                if(target[i] == prob.y[i]){
                    ++total_correct;
                }
            }
            crossValidationResult = total_correct/prob.l*100.0;
        }
        delete[] target;
    }
        
    //Train the SVM - if we are running cross validation then the CV will be run first followed by a full train
    model = svm_train(&prob,&param);

    if( model == NULL ){
        errorLog << "trainSVM() - Failed to train SVM Model!" << endl;
        return false;
    }

    if( model != NULL ){
        trained = true;
        numClasses = getNumClasses();
        classLabels.resize( getNumClasses() );
        for(UINT k=0; k<getNumClasses(); k++){
            classLabels[k] = model->label[k];
        }
        classLikelihoods.resize(numClasses,DEFAULT_NULL_LIKELIHOOD_VALUE);
        classDistances.resize(numClasses,DEFAULT_NULL_DISTANCE_VALUE);
    }

    return trained;
}
Пример #16
0
bool CParameterSearch::SearchRange(ParameterResult* pResult, RangeParameters& Params)
{
	if(!m_pProblem || !m_pSvmParam || !pResult)
		return false;
	
	float fParam1 = 0;
	float fParam2 = 0;
	
	double* target = new double[m_pProblem->l];
/*	for(int i=0; i<m_pProblem->l; i++)
	{
		target[i] = 0;
	}*/
	
	for(fParam1=Params.fParam1Min; fParam1<=Params.fParam1Max; fParam1+=Params.fParam1Step)
	{
		if(Params.bParam1UseLog)
			m_pSvmParam->p = ::pow(2,fParam1);
		else
			m_pSvmParam->p = fParam1;
		
		for(fParam2=Params.fParam2Min; fParam2<=Params.fParam2Max; fParam2+=Params.fParam2Step)
		{	
			if(Params.bParam2UseLog)
				m_pSvmParam->C = ::pow(2,fParam2);
			else
				m_pSvmParam->C = fParam2;
			
			int nFolds = 2;
			svm_cross_validation(m_pProblem, m_pSvmParam, nFolds, target);
			float fError = 0;
			float fWrong = 0;
			for(int i=0; i<m_pProblem->l; i++)
			{
				fError += abs(m_pProblem->y[i] - target[i]);
				if( m_pProblem->y[i] >= 0.5 && target[i] < 0.5)
						fWrong++;
				else if( m_pProblem->y[i] < 0.5 && target[i] >= 0.5)
						fWrong++;
			}
			fError = (float)fError/m_pProblem->l;
			fWrong = (float) fWrong/m_pProblem->l;
			
			float fStdDev = 0;
			for(int i=0; i<m_pProblem->l; i++)
			{
				fStdDev += pow(fError - abs(m_pProblem->y[i] - target[i]), 2) ;
			}
			fStdDev = pow(fStdDev, (float)0.5) /  m_pProblem->l;
			
			std::cout << "\n****************" << std::endl;
			std::cout << "C = 2^" << fParam2 << ", epsilon = 2^" << fParam1 << std::endl;
			std::cout << "Avg Error: " << fError << "  Std Dev: " << fStdDev << std::endl;
			std::cout << "Percent wrong: " << fWrong << std::endl;
			
			ParameterResult* pNewResult = new ParameterResult;
			pNewResult->fError = fError;
			pNewResult->fStdDev = fStdDev;
			pNewResult->fWrong = fWrong;
			pNewResult->fParam1 = fParam1;
			pNewResult->fParam2 = fParam2;
			pNewResult->nLevel = pResult->nLevel + 1;
			m_searchResults.insert(pNewResult);
				
			const ParameterResult* pConstResult = pNewResult;
							
			*m_pOA << *pConstResult;
			m_pofs->flush();
			
			//SaveTextResults();
		}
	}
	pResult->bRefined = true;
	
	SerializeData();
	
	return true;
}
Пример #17
0
Transformation SVMTrain::analyze(const DataSet* dataset) const {
  G_INFO("Doing SVMTrain analysis...");

  QStringList sdescs = selectDescriptors(dataset->layout(), StringType, _descriptorNames, _exclude, false);

  if (!sdescs.isEmpty()) {
    throw GaiaException("SVMTrain: if you want to use string descriptors for training your SVM, "
                        "you first need to enumerate them using the 'enumerate' transform on them. "
                        "String descriptors: ", sdescs.join(", "));
  }

  QStringList descs = selectDescriptors(dataset->layout(), UndefinedType, _descriptorNames, _exclude);
  // sort descriptors in the order in which they are taken inside the libsvm dataset
  sort(descs.begin(), descs.end(), DescCompare(dataset->layout()));
  Region region = dataset->layout().descriptorLocation(descs);

  QStringList classMapping = svm::createClassMapping(dataset, _className);

  // first, convert the training data into an SVM problem structure
  // NB: all checks about fixed-length and type of descriptors are done in this function
  struct svm_problem prob = svm::dataSetToLibsvmProblem(dataset, _className, region, classMapping);

  // also get dimension (this trick works because a vector in there is the number
  // of dimensions + 1 for the sentinel, and we're not in a sparse representation)
  int dimension = prob.x[1] - prob.x[0] - 1;


  // default values
  struct svm_parameter param;
  //param.svm_type = C_SVC;
  //param.kernel_type = RBF;
  //param.degree = 3;
  //param.gamma = 0;	// 1/k
  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 = NULL;
  param.weight = NULL;

  // get parameters
  QString svmType = _params.value("type", "C-SVC").toString().toLower();
  param.svm_type = _svmTypeMap.value(svmType);
  QString kernelType = _params.value("kernel", "RBF").toString().toLower();
  param.kernel_type = _kernelTypeMap.value(kernelType);
  param.degree = _params.value("degree", 3).toInt();
  param.C = _params.value("c", 1).toDouble();
  param.gamma = _params.value("gamma", 1.0/dimension).toDouble();
  param.probability = _params.value("probability", false).toBool() ? 1 : 0;


  const char* error_msg = svm_check_parameter(&prob, &param);

  if (error_msg) {
    throw GaiaException(error_msg);
  }


  // do it!
  struct svm_model* model;

  const bool crossValidation = false;
  if (crossValidation) {
    int nr_fold = 10;
    int total_correct = 0;
    double total_error = 0;
    double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
    double* target = new double[prob.l];

    svm_cross_validation(&prob, &param, nr_fold, target);

    if (param.svm_type == EPSILON_SVR ||
        param.svm_type == NU_SVR) {
      for (int i=0; i<prob.l; i++) {
        double y = prob.y[i];
        double v = target[i];
        total_error += (v-y)*(v-y);
        sumv += v;
        sumy += y;
        sumvv += v*v;
        sumyy += y*y;
        sumvy += v*y;
      }
      G_INFO("Cross Validation Mean squared error =" << total_error/prob.l);
      G_INFO("Cross Validation Squared correlation coefficient =" <<
             ((prob.l*sumvy - sumv*sumy) * (prob.l*sumvy - sumv*sumy)) /
             ((prob.l*sumvv - sumv*sumv) * (prob.l*sumyy - sumy*sumy))
             );
    }
    else {
      for (int i=0; i<prob.l; i++)
        if (target[i] == prob.y[i])
          ++total_correct;
      G_INFO("Cross Validation Accuracy =" << 100.0*total_correct/prob.l << "%");
    }
  }
  else { // !crossValidation
    model = svm_train(&prob, &param);
  }

  // save model to a temporary file (only method available from libsvm...),
  // reload it and put it into a gaia2::Parameter
  QTemporaryFile modelFile;
  modelFile.open();
  QString modelFilename = modelFile.fileName();
  modelFile.close();

  if (svm_save_model(modelFilename.toAscii().constData(), model) == -1) {
    throw GaiaException("SVMTrain: error while saving SVM model to temp file");
  }

  modelFile.open();
  QByteArray modelData = modelFile.readAll();
  modelFile.close();


  // if we asked for the model to be output specifically, also do it
  if (_params.value("modelFilename", "").toString() != "") {
    QString filename = _params.value("modelFilename").toString();
    svm_save_model(filename.toAscii().constData(), model);
  }

  // destroy the model allocated by libsvm
  svm_destroy_model(model);

  Transformation result(dataset->layout());
  result.analyzerName = "svmtrain";
  result.analyzerParams = _params;
  result.applierName = "svmpredict";
  result.params.insert("modelData", modelData);
  result.params.insert("className", _params.value("className"));
  result.params.insert("descriptorNames", descs);
  result.params.insert("classMapping", classMapping);
  result.params.insert("probability", (param.probability == 1 && (param.svm_type == C_SVC ||
                                                                  param.svm_type == NU_SVC)));
  return result;
}
Пример #18
0
    void SVMClassifier::train()
    {
        if(class_data.size() == 0){
            printf("SVMClassifier::train() -- No training data available! Doing nothing.\n");
            return;
        }
        
        int n_classes = class_data.size();
        
        //Count the training data
        int n_data = 0;
        int dims = class_data.begin()->second[0].size();
        for(ClassMap::iterator iter = class_data.begin(); iter != class_data.end(); iter++){
            CPointList cpl = iter->second;
            if(cpl.size() == 1)
                n_data += 2;    //There's a bug in libSVM for classes with only 1 data point, so we will duplicate them later
            else
                n_data += cpl.size();
        }
        
        //Allocate space for data in an svm_problem structure
        svm_data.l = n_data;
        svm_data.y = new double[n_data];
        svm_data.x = new svm_node*[n_data]; 
        for(int i=0; i<n_data; i++)
            svm_data.x[i] = new svm_node[dims+1];
        
        //Create maps between string labels and int labels
        label_str_to_int.clear();
        label_int_to_str.clear();
        int label_n = 0;
        for(ClassMap::iterator iter = class_data.begin(); iter != class_data.end(); iter++){
            string cname = iter->first;
            label_str_to_int[cname] = label_n;
            label_int_to_str[label_n] = cname;
            //cout << "MAP: " << label_n << "   " << cname << "   Size: " << iter->second.size() << endl;
            ++label_n;
        }
                
        //Find the range of the data in each dim and calc the scaling factors to scale from 0 to 1
        scaling_factors = new double*[dims];
        for(int i=0; i<dims; i++)
            scaling_factors[i] = new double[2];
            
        //Scale each dimension separately
        for(int j=0; j<dims; j++){
            //First find the min, max, and scaling factor
            double minval = INFINITY;
            double maxval = -INFINITY;
            for(ClassMap::iterator iter = class_data.begin(); iter != class_data.end(); iter++){
                CPointList cpl = iter->second;
                for(size_t i=0; i<cpl.size(); i++){
                    if(cpl[i][j] < minval) 
                        minval = cpl[i][j];
                    if(cpl[i][j] > maxval) 
                        maxval = cpl[i][j];
                }
            }
            double factor = maxval-minval;
            double offset = minval;
            
            //Do the scaling and save the scaling factor and offset
            for(ClassMap::iterator iter = class_data.begin(); iter != class_data.end(); iter++){
                for(size_t i=0; i<iter->second.size(); i++){
                    iter->second[i][j] = (iter->second[i][j] - offset) / factor;
                }
            }
            scaling_factors[j][0] = offset;
            scaling_factors[j][1] = factor;
        }
        
        //Put the training data into the svm_problem
        int n = 0;
        for(ClassMap::iterator iter = class_data.begin(); iter != class_data.end(); iter++){
            string cname = iter->first;
            CPointList cpl = iter->second;
            
            //Account for bug in libSVM with classes with only 1 data point by duplicating it.
            if(cpl.size() == 1){
                svm_data.y[n] = label_str_to_int[cname];
                svm_data.y[n+1] = label_str_to_int[cname];
                for(int j=0; j<dims; j++){
                    svm_data.x[n][j].index = j;
                    svm_data.x[n][j].value = cpl[0][j] + 0.001;
                    svm_data.x[n+1][j].index = j;
                    svm_data.x[n+1][j].value = cpl[0][j] + 0.001;
                }
                svm_data.x[n][dims].index = -1;
                svm_data.x[n+1][dims].index = -1;
                n = n + 2;
            }
            else{
                for(size_t i=0; i<cpl.size(); i++){
                    svm_data.y[n] = label_str_to_int[cname];
                    for(int j=0; j<dims; j++){
                        svm_data.x[n][j].index = j;
                        svm_data.x[n][j].value = cpl[i][j];
                    }
                svm_data.x[n][dims].index = -1;
                n = n + 1;
                }
            }
        } 
        
        //Set the training params
        svm_parameter params;
        params.svm_type = C_SVC;
        params.kernel_type = RBF;
        params.cache_size = 100.0;  
        params.gamma = 1.0;
        params.C = 1.0;
        params.eps = 0.001;
        params.shrinking = 1;
        params.probability = 0;
        params.degree = 0;
        params.nr_weight = 0;
        //params.weight_label = 
        //params.weight = 
        
        const char *err_str = svm_check_parameter(&svm_data, &params);
        if(err_str){
            printf("SVMClassifier::train() -- Bad SVM parameters!\n");
            printf("%s\n",err_str);
            return;
        }
        
        //Grid Search for best C and gamma params
        int n_folds = min(10, n_data);  //Make sure there at least as many points as folds
        double *resp = new double[n_data];
        double best_accy = 0.0;
        double best_g = 0.0;
        double best_c = 0.0;
        
        //First, do a coarse search
        for(double c = -5.0; c <= 15.0; c += 2.0){
            for(double g = 3.0; g >= -15.0; g -= 2.0){    
                params.gamma = pow(2,g);
                params.C = pow(2,c);
                
                svm_cross_validation(&svm_data, &params, n_folds, resp);
                
                //Figure out the accuracy using these params
                int correct = 0;
                for(int i=0; i<n_data; i++){
                    if(resp[i] == svm_data.y[i])
                        ++correct;
                    double accy = double(correct) / double(n_data);
                    if(accy > best_accy){
                        best_accy = accy;
                        best_g = params.gamma;
                        best_c = params.C;
                    }
                }
            }
        }
        
        //Now do a finer grid search based on coarse results   
        double start_c = best_c - 1.0;
        double end_c = best_c + 1.0;
        double start_g = best_g + 1.0;
        double end_g = best_g - 1.0;
        for(double c = start_c; c <= end_c; c += 0.1){
            for(double g = start_g; g >= end_g; g -= 0.1){
                params.gamma = pow(2,g);
                params.C = pow(2,c);
                svm_cross_validation(&svm_data, &params, n_folds, resp);
                
                //Figure out the accuracy using these params
                int correct = 0;
                for(int i=0; i<n_data; i++){
                    if(resp[i] == svm_data.y[i])
                        ++correct;
                    double accy = double(correct) / double(n_data);
                    
                    if(accy > best_accy){
                        best_accy = accy;
                        best_g = params.gamma;
                        best_c = params.C;
                    }
                }
            }
        }

        // Set params to best found in grid search
        params.gamma = best_g;
        params.C = best_c;
    
        printf("BEST PARAMS  ncl: %i   c: %f   g: %f   accy: %f \n\n", n_classes, best_c, best_g, best_accy);
        
        //Train the SVM
        trained_model = svm_train(&svm_data, &params);
    }