Changeset 11650:ed138a0a0d5c in orange


Ignore:
Timestamp:
08/08/13 17:21:29 (8 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Fixed an error in libsvm interface (example_to_svm function).

The 'index' did not get incremented in the presence of missing values.
I also cleaned up some old parameters, ...

Location:
source/orange
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • source/orange/libsvm_interface.cpp

    r11649 r11650  
    2222#include <sstream> 
    2323 
    24 #include "libsvm_interface.ppp" 
     24#include "libsvm_interface.hpp" 
     25#include "symmatrix.hpp" 
     26 
     27#include <algorithm> 
     28#include <cmath> 
     29 
    2530 
    2631// Defined in svm.cpp. If new svm or kernel types are added this should be updated. 
     
    137142} 
    138143 
    139  
    140 #include <algorithm> 
    141144 
    142145svm_model *svm_load_model_alt(std::istream& stream) 
     
    351354} 
    352355 
     356 
    353357svm_model *svm_load_model_alt(std::string& stream) 
    354358{ 
     
    358362 
    359363 
     364std::ostream & svm_node_vector_to_stream(std::ostream & stream, const svm_node * node) { 
     365    while (node->index != -1) { 
     366        stream << node->index << ":" << node->value << " "; 
     367        node++; 
     368    } 
     369    stream << node->index << ":" << node->value; 
     370    return stream; 
     371} 
     372 
     373std::ostream & operator << (std::ostream & stream, const svm_problem & problem) { 
     374    svm_node * node = NULL; 
     375    for (int i = 0; i < problem.l; i++) { 
     376        stream << problem.y[i] << " "; 
     377        svm_node_vector_to_stream(stream, problem.x[i]); 
     378        stream << endl; 
     379    } 
     380    return stream; 
     381} 
     382 
    360383/* 
    361384 * Return a formated string representing a svm data instance (svm_node *) 
    362385 * (useful for debugging) 
    363386 */ 
    364 string svm_node_to_string(svm_node * node) { 
     387std::string svm_node_to_string(const svm_node * node) { 
    365388    std::ostringstream strstream; 
    366389    strstream.precision(17); 
    367     while (node->index != -1) { 
    368         strstream << node->index << ":" << node->value << " "; 
    369         node++; 
    370     } 
    371     strstream << node->index << ":" << node->value << " "; 
     390    svm_node_vector_to_stream(strstream, node); 
    372391    return strstream.rdbuf()->str(); 
    373392} 
    374393 
    375394 
    376 svm_node* example_to_svm(const TExample &ex, svm_node* node, float last=0.0, int type=0){ 
    377     if(type==0){ 
    378         int index=1; 
    379         for(TExample::iterator i=ex.begin(); i!=ex.end(); i++){ 
    380             if(i->isRegular() && i!=&ex.getClass()){ 
    381                 if(i->varType==TValue::FLOATVAR) 
    382                     node->value=float(*i); 
    383                 else 
    384                     node->value=int(*i); 
    385                 node->index=index++; 
    386                 if(node->value==numeric_limits<float>::signaling_NaN() || 
    387                     node->value==numeric_limits<int>::max() ||  
    388                     node->value == 0) 
    389                     node--; 
     395#ifdef _MSC_VER 
     396    #include <float.h> 
     397    #define isfinite _finite 
     398#endif 
     399 
     400/*! 
     401 * Check if the value is valid (not a special value in 'TValue'). 
     402 */ 
     403 
     404inline bool is_valid(double value) { 
     405    return isfinite(value) && value != numeric_limits<int>::max(); 
     406} 
     407 
     408 
     409svm_node* example_to_svm(const TExample &ex, svm_node* node, double last=0.0) { 
     410    int index = 1; 
     411    double value = 0.0; 
     412    TExample::iterator values_end; 
     413 
     414    if (ex.domain->classVar) { 
     415        values_end = ex.end() - 1; 
     416    } else { 
     417        values_end = ex.end(); 
     418    } 
     419 
     420    for(TExample::iterator iter = ex.begin(); iter != values_end; iter++, index++) { 
     421        if(iter->isRegular()) { 
     422            if(iter->varType == TValue::FLOATVAR) { 
     423                value = iter->floatV; 
     424            } else if (iter->varType == TValue::INTVAR) { 
     425                value = iter->intV; 
     426            } else { 
     427                continue; 
     428            } 
     429 
     430            // Only add non zero values (speedup due to sparseness) 
     431            if (value != 0 && is_valid(value)) { 
     432                node->index = index; 
     433                node->value = value; 
    390434                node++; 
    391435            } 
    392436        } 
    393437    } 
    394     if(type == 1){ /*one dummy attr so we can pickle the classifier and keep the SV index in the training table*/ 
    395         node->index=1; 
    396         node->value=last; 
    397         node++; 
    398     } 
    399     //cout<<(node-1)->index<<endl<<(node-2)->index<<endl; 
    400     node->index=-1; 
    401     node->value=last; 
     438 
     439    // Sentinel 
     440    node->index = -1; 
     441    node->value = last; 
    402442    node++; 
    403443    return node; 
     
    406446class SVM_NodeSort{ 
    407447public: 
    408     bool operator() (const svm_node &lhs, const svm_node &rhs){ 
     448    bool operator() (const svm_node &lhs, const svm_node &rhs) { 
    409449        return lhs.index < rhs.index; 
    410450    } 
    411451}; 
    412452 
    413 svm_node* example_to_svm_sparse(const TExample &ex, svm_node* node, float last=0.0, bool useNonMeta=false){ 
    414     svm_node *first=node; 
    415     int j=1; 
    416     int index=1; 
    417     if(useNonMeta) 
    418         for(TExample::iterator i=ex.begin(); i!=ex.end(); i++){ 
    419             if(i->isRegular() && i!=&ex.getClass()){ 
    420                 if(i->varType==TValue::FLOATVAR) 
    421                     node->value=float(*i); 
    422                 else 
    423                     node->value=int(*i); 
    424                 node->index=index; 
    425                 if(node->value==numeric_limits<float>::signaling_NaN() || 
    426                     node->value==numeric_limits<int>::max() || 
    427                     node->value == 0) 
    428                     node--; 
     453svm_node* example_to_svm_sparse(const TExample &ex, svm_node* node, double last=0.0, bool include_regular=false) { 
     454    svm_node *first = node; 
     455    int index = 1; 
     456    double value; 
     457 
     458    if (include_regular) { 
     459        node = example_to_svm(ex, node); 
     460        // Rewind the sentinel 
     461        node--; 
     462        assert(node->index == -1); 
     463        index += ex.domain->variables->size(); 
     464    } 
     465 
     466    for (TMetaValues::const_iterator iter=ex.meta.begin(); iter!=ex.meta.end(); iter++) { 
     467        if(iter->second.isRegular()) { 
     468            if(iter->second.varType == TValue::FLOATVAR) { 
     469                value = iter->second.floatV; 
     470            } else if (iter->second.varType == TValue::INTVAR) { 
     471                value = iter->second.intV; 
     472            } else { 
     473                continue; 
     474            } 
     475 
     476            if (value != 0 && is_valid(value)) { 
     477                // add the (- meta_id) to index; meta_ids are negative 
     478                node->index = index - iter->first; 
     479                node->value = value; 
    429480                node++; 
    430481            } 
    431             index++; 
    432         } 
    433     for(TMetaValues::const_iterator i=ex.meta.begin(); i!=ex.meta.end();i++,j++){ 
    434         if(i->second.isRegular()){ 
    435             if(i->second.varType==TValue::FLOATVAR) 
    436                 node->value=float(i->second); 
    437             else 
    438                 node->value=int(i->second); 
    439             node->index = index - i->first; 
    440  
    441             if(node->value==numeric_limits<float>::signaling_NaN() || 
    442                 node->value==numeric_limits<int>::max()) 
    443                 node--; 
    444             node++; 
    445         } 
    446     } 
     482        } 
     483    } 
     484 
     485    // sort the nodes by index (metas are not ordered) 
    447486    sort(first, node, SVM_NodeSort()); 
    448     //cout<<first->index<<endl<<(first+1)->index<<endl; 
    449     node->index=-1; 
    450     node->value=last; 
     487 
     488    // Sentinel 
     489    node->index = -1; 
     490    node->value = last; 
    451491    node++; 
    452492    return node; 
     
    457497 * Used for prediction when using the PRECOMPUTED kernel. 
    458498 */ 
    459 svm_node* example_to_svm_precomputed(const TExample &ex, PExampleGenerator examples, PKernelFunc kernel, svm_node* node){ 
     499svm_node* example_to_svm_precomputed(const TExample &ex, PExampleGenerator examples, PKernelFunc kernel, svm_node* node) { 
     500    // Required node with index 0 
    460501    node->index = 0; 
    461502    node->value = 0.0; // Can be any value. 
     
    464505    PEITERATE(iter, examples){ 
    465506        node->index = ++k; 
    466         node->value = kernel.getReference()(*iter, ex); 
     507        node->value = kernel->operator()(*iter, ex); 
    467508        node++; 
    468509    } 
    469     node->index = -1; // sentry 
     510 
     511    // Sentinel 
     512    node->index = -1; 
    470513    node++; 
    471514    return node; 
     
    473516 
    474517int getNumOfElements(const TExample &ex, bool meta=false, bool useNonMeta=false){ 
    475     if(!meta) 
    476         return std::max(ex.domain->attributes->size()+1, 2); 
    477     else{ 
    478         int count=1; //we need one to indicate the end of a sequence 
    479         if(useNonMeta) 
    480             count+=ex.domain->attributes->size(); 
    481         for(TMetaValues::const_iterator i=ex.meta.begin(); i!=ex.meta.end();i++) 
    482             if(i->second.isRegular()) 
     518    if (!meta) 
     519        return std::max(ex.domain->attributes->size() + 1, 2); 
     520    else { 
     521        int count = 1; // we need one to indicate the end of a sequence 
     522        if (useNonMeta) 
     523            count += ex.domain->attributes->size(); 
     524        for (TMetaValues::const_iterator iter=ex.meta.begin(); iter!=ex.meta.end();iter++) 
     525            if(iter->second.isRegular()) 
    483526                count++; 
    484527        return std::max(count,2); 
     
    486529} 
    487530 
    488 int getNumOfElements(PExampleGenerator &examples, bool meta=false, bool useNonMeta=false){ 
    489     if(!meta) 
    490         return getNumOfElements(*(examples->begin()), meta)*examples->numberOfExamples(); 
    491     else{ 
    492         int count=0; 
     531int getNumOfElements(PExampleGenerator &examples, bool meta=false, bool useNonMeta=false) { 
     532    if (!meta) 
     533        return getNumOfElements(*(examples->begin()), meta) * examples->numberOfExamples(); 
     534    else { 
     535        int count = 0; 
    493536        for(TExampleGenerator::iterator ex(examples->begin()); ex!=examples->end(); ++ex){ 
    494             count+=getNumOfElements(*ex, meta, useNonMeta); 
     537            count += getNumOfElements(*ex, meta, useNonMeta); 
    495538        } 
    496539        return count; 
     
    498541} 
    499542 
    500 #include "symmatrix.hpp" 
    501543svm_node* init_precomputed_problem(svm_problem &problem, PExampleTable examples, TKernelFunc &kernel){ 
    502544    int n_examples = examples->numberOfExamples(); 
     
    506548        for (j = 0; j <= i; j++){ 
    507549            matrix->getref(i, j) = kernel(examples->at(i), examples->at(j)); 
    508 //          cout << i << " " << j << " " << matrix->getitem(i, j) << endl; 
    509550        } 
    510551    svm_node *x_space = Malloc(svm_node, n_examples * (n_examples + 2)); 
     
    701742        x_space = init_precomputed_problem(prob, train_data, kernelFunc.getReference()); 
    702743 
    703     if (param.gamma==0) 
    704         param.gamma=1.0f/(float(numElements)/float(prob.l)-1); 
    705  
    706     const char* error=svm_check_parameter(&prob, &param); 
     744    if (param.gamma == 0) 
     745        param.gamma = 1.0f / (float(numElements) / float(prob.l) - 1); 
     746 
     747    const char* error = svm_check_parameter(&prob, &param); 
    707748    if (error){ 
    708749        free(x_space); 
     
    750791} 
    751792 
    752 svm_node* TSVMLearner::example_to_svm(const TExample &ex, svm_node* node, float last, int type){ 
    753     return ::example_to_svm(ex, node, last, type); 
     793svm_node* TSVMLearner::example_to_svm(const TExample &ex, svm_node* node, double last){ 
     794    return ::example_to_svm(ex, node, last); 
    754795} 
    755796 
    756797svm_node* TSVMLearner::init_problem(svm_problem &problem, PExampleTable examples, int n_elements){ 
    757798    problem.l = examples->numberOfExamples(); 
    758     problem.y = Malloc(double ,problem.l); 
     799    problem.y = Malloc(double, problem.l); 
    759800    problem.x = Malloc(svm_node*, problem.l); 
    760801    svm_node *x_space = Malloc(svm_node, n_elements); 
     
    770811                problem.y[i] = examples->at(i).getClass().intV; 
    771812    } 
     813 
     814//  cout << problem << endl; 
     815 
    772816    return x_space; 
    773817} 
     
    799843} 
    800844 
    801 svm_node* TSVMLearnerSparse::example_to_svm(const TExample &ex, svm_node* node, float last, int type){ 
     845svm_node* TSVMLearnerSparse::example_to_svm(const TExample &ex, svm_node* node, double last){ 
    802846    return ::example_to_svm_sparse(ex, node, last, useNonMeta); 
    803847} 
     
    10141058} 
    10151059 
    1016 svm_node *TSVMClassifier::example_to_svm(const TExample &ex, svm_node *node, float last, int type){ 
    1017     return ::example_to_svm(ex, node, last, type); 
     1060svm_node *TSVMClassifier::example_to_svm(const TExample &ex, svm_node *node, double last){ 
     1061    return ::example_to_svm(ex, node, last); 
    10181062} 
    10191063 
     
    10211065    return ::getNumOfElements(example); 
    10221066} 
    1023 svm_node *TSVMClassifierSparse::example_to_svm(const TExample &ex, svm_node *node, float last, int){ 
     1067svm_node *TSVMClassifierSparse::example_to_svm(const TExample &ex, svm_node *node, double last){ 
    10241068    return ::example_to_svm_sparse(ex, node, last, useNonMeta); 
    10251069} 
     
    10301074 
    10311075 
     1076#include "libsvm_interface.ppp" 
  • source/orange/libsvm_interface.hpp

    r11607 r11650  
    103103 
    104104protected: 
    105     virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, float last=0.0, int type=0); 
     105    virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, double last=0.0); 
    106106    virtual svm_node* init_problem(svm_problem &problem, PExampleTable examples, int n_elements); 
    107107    virtual int getNumOfElements(PExampleGenerator examples); 
     
    115115    bool useNonMeta; //P include non meta attributes in the learning process 
    116116protected: 
    117     virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, float last=0.0, int type=0); 
     117    virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, double last=0.0); 
    118118    virtual int getNumOfElements(PExampleGenerator examples); 
    119119    virtual TSVMClassifier* createClassifier( 
     
    155155 
    156156protected: 
    157     virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, float last=0.0, int type=0); 
     157    virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, double last=0.0); 
    158158    virtual int getNumOfElements(const TExample& example); 
    159159 
     
    179179 
    180180protected: 
    181     virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, float last=0.0, int type=0); 
     181    virtual svm_node* example_to_svm(const TExample &ex, svm_node* node, double last=0.0); 
    182182    virtual int getNumOfElements(const TExample& example); 
    183183}; 
Note: See TracChangeset for help on using the changeset viewer.