Changeset 10578:29902b555575 in orange


Ignore:
Timestamp:
03/20/12 11:22:49 (2 years ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
rebase_source:
1b7cc40545fad352f3f2a867cdaaa8fa83115be4
Message:

Map internal class values order of libsvm to orange variable's native ordering in get_decision_values and get_binary_classifier.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/classification/svm/__init__.py

    r10574 r10578  
    273273    def get_decision_values(self, example): 
    274274        example = Orange.data.Instance(self.wrapped.domain, example) 
    275         return self.wrapped.get_decision_values(example) 
    276  
     275        dec_values = self.wrapped.get_decision_values(example) 
     276        # decision values are ordred by libsvm internal class values 
     277        # i.e. the order of labels in the data 
     278        map = self._get_libsvm_labels_map() 
     279        n_class = len(self.class_var.values) 
     280        new_values = [] 
     281        for i in range(n_class - 1): 
     282            for j in range(i + 1, n_class): 
     283                # Internal indices 
     284                ni, nj = map.index(i), map.index(j) 
     285                mult = 1.0 
     286                if ni > nj: 
     287                    ni, nj = nj, ni 
     288                    # Multiply by -1 if we switch the order of the 1vs1 
     289                    # classifier. 
     290                    mult = -1.0 
     291                val_index = n_class * (n_class - 1) / 2 - (n_class - ni - 1) * (n_class - ni - 2) / 2 - (n_class - nj) 
     292                new_values.append(mult * dec_values[val_index]) 
     293        return new_values 
     294         
    277295    def get_model(self): 
    278296        return self.wrapped.get_model() 
     297     
     298    def _get_libsvm_labels_map(self): 
     299        """Get the libsvm label mapping from the model string  
     300        """ 
     301        labels = [line for line in self.get_model().splitlines() \ 
     302                  if line.startswith("label")] 
     303        labels = labels[0].split(" ")[1:] if labels else ["0"] 
     304        return [int(label) for label in labels] 
    279305 
    280306    def __reduce__(self): 
     
    292318        c1 = int(self.class_var(c1)) 
    293319        c2 = int(self.class_var(c2)) 
     320         
     321        libsvm_label = [line for line in self.get_model().splitlines() \ 
     322                        if line.startswith("label")] 
     323         
    294324        n_class = len(self.class_var.values) 
    295325         
    296326        if c1 == c2: 
    297327            raise ValueError("Different classes expected.") 
    298           
     328         
     329        bin_class_var = Orange.feature.Discrete("%s vs %s" % \ 
     330                        (self.class_var.values[c1], self.class_var.values[c2]), 
     331                        values=["0", "1"]) 
     332         
     333        # Map the libsvm labels  
     334        labels_map = self._get_libsvm_labels_map() 
     335        c1 = labels_map.index(c1) 
     336        c2 = labels_map.index(c2) 
     337         
     338        mult = 1.0 
    299339        if c1 > c2: 
    300340            c1, c2 = c2, c1 
     341            mult = -1.0 
    301342         
    302343        # Index of the 1vs1 binary classifier  
     
    309350         
    310351        coef_array = np.array(self.coef) 
    311         coef1 = coef_array[c2 - 1, c1_range] 
    312         coef2 = coef_array[c1, c2_range] 
     352        coef1 = mult * coef_array[c2 - 1, c1_range] 
     353        coef2 = mult * coef_array[c1, c2_range] 
    313354         
    314355        # Support vectors for the binary classifier 
     
    317358         
    318359        # Rho for the classifier 
    319         rho = self.rho[classifier_i] 
     360        rho = mult * self.rho[classifier_i] 
    320361         
    321362        # Filter non zero support vectors 
     
    331372        sv_indices1 = [i for i, nz in zip(c1_range, nonzero1) if nz] 
    332373        sv_indices2 = [i for i, nz in zip(c2_range, nonzero2) if nz] 
    333          
    334         bin_class_var = Orange.feature.Discrete("%s vs %s" % \ 
    335                         (self.class_var.values[c1], self.class_var.values[c2]), 
    336                         values=["0", "1"]) 
    337374         
    338375        model = self._binary_libsvm_model(bin_class_var, [coef1, coef2], 
Note: See TracChangeset for help on using the changeset viewer.