Ignore:
Files:
6 added
3 deleted
36 edited

Legend:

Unmodified
Added
Removed
  • .hgignore

    r10545 r10614  
    66syntax: glob 
    77 
     8# Ignore dot files. 
     9.* 
     10 
     11# Ignore backup files 
     12*.orig 
     13 
     14# Ignore temporary editor files. 
     15*.swp 
     16*~ 
     17 
     18# Ignore binaries. 
     19*.py[cod] 
     20*.so 
     21*.dll 
     22 
     23# Ignore files created by make 
    824*.o 
    925*.a 
     
    2137Orange.egg-info 
    2238Orange/version.py 
    23  
    24 # Ignore dot files. 
    25 .* 
    26  
    27 # Ignore binaries. 
    28 *.py[cod] 
    29 *.so 
    30 *.dll 
    31  
    32 # Ignore temporary editor files. 
    33 *.swp 
    34 *~ 
    3539 
    3640# Built documentation. 
  • Orange/__init__.py

    r10581 r10636  
    144144    pass 
    145145 
     146del _import 
     147del alreadyWarned 
     148del disabledMsg 
  • Orange/classification/svm/__init__.py

    r10585 r10642  
    22 
    33from collections import defaultdict 
     4from operator import add 
    45 
    56import Orange.core 
     
    1516from Orange.core import LinearClassifier, \ 
    1617                        LinearLearner, \ 
    17                         SVMClassifier, \ 
    18                         SVMClassifierSparse 
     18                        SVMClassifier as _SVMClassifier, \ 
     19                        SVMClassifierSparse as _SVMClassifierSparse 
    1920 
    2021from Orange.data import preprocess 
     
    177178            data = self._normalize(data) 
    178179        svm = self.learner(data) 
    179         return SVMClassifierWrapper(svm) 
     180        return SVMClassifier(svm) 
    180181 
    181182    @Orange.utils.deprecated_keywords({"progressCallback": "progress_callback"}) 
     
    253254    wrap_methods=["__init__", "tune_parameters"])(SVMLearner) 
    254255 
    255 class SVMClassifierWrapper(Orange.core.SVMClassifier): 
    256     def __new__(cls, wrapped): 
    257         return Orange.core.SVMClassifier.__new__(cls, name=wrapped.name) 
     256class SVMClassifier(_SVMClassifier): 
     257    def __new__(cls, *args, **kwargs): 
     258        if args and isinstance(args[0], _SVMClassifier): 
     259            # Will wrap a C++ object  
     260            return _SVMClassifier.__new__(cls, name=args[0].name) 
     261        elif args and isinstance(args[0], variable.Descriptor): 
     262            # The constructor call for the C++ object. 
     263            # This is a hack to support loading of old pickled classifiers   
     264            return _SVMClassifier.__new__(_SVMClassifier, *args, **kwargs) 
     265        else: 
     266            raise ValueError 
    258267 
    259268    def __init__(self, wrapped): 
    260         self.wrapped = wrapped 
    261         for name, val in wrapped.__dict__.items(): 
    262             self.__dict__[name] = val 
    263  
    264     def __call__(self, example, what=Orange.core.GetValue): 
    265         example = Orange.data.Instance(self.wrapped.domain, example) 
    266         return self.wrapped(example, what) 
    267  
    268     def class_distribution(self, example): 
    269         example = Orange.data.Instance(self.wrapped.domain, example) 
    270         return self.wrapped.class_distribution(example) 
    271  
    272     def get_decision_values(self, example): 
    273         example = Orange.data.Instance(self.wrapped.domain, example) 
    274         dec_values = self.wrapped.get_decision_values(example) 
    275         # decision values are ordred by libsvm internal class values 
    276         # i.e. the order of labels in the data 
    277         map = self._get_libsvm_labels_map() 
     269        self.class_var = wrapped.class_var 
     270        self.domain = wrapped.domain 
     271        self.computes_probabilities = wrapped.computes_probabilities 
     272        self.examples = wrapped.examples 
     273        self.svm_type = wrapped.svm_type 
     274        self.kernel_func = wrapped.kernel_func 
     275        self.kernel_type = wrapped.kernel_type 
     276        self.__wrapped = wrapped 
     277         
     278        assert(type(wrapped) in [_SVMClassifier, _SVMClassifierSparse]) 
     279         
     280        if self.svm_type in [SVMLearner.C_SVC, SVMLearner.Nu_SVC]: 
     281            # Reorder the support vectors 
     282            label_map = self._get_libsvm_labels_map() 
     283            start = 0 
     284            support_vectors = [] 
     285            for n in wrapped.n_SV: 
     286                support_vectors.append(wrapped.support_vectors[start: start + n]) 
     287                start += n 
     288            support_vectors = [support_vectors[i] for i in label_map] 
     289            self.support_vectors = Orange.data.Table(reduce(add, support_vectors)) 
     290        else: 
     291            self.support_vectors = wrapped.support_vectors 
     292     
     293    @property 
     294    def coef(self): 
     295        """Coefficients of the underlying svm model. 
     296         
     297        If this is a classification model then this is a list of 
     298        coefficients for each binary 1vs1 classifiers, i.e. 
     299        #Classes * (#Classses - 1) list of lists where 
     300        each sublist contains tuples of (coef, support_vector_index) 
     301         
     302        For regression models it is still a list of lists (for consistency) 
     303        but of length 1 e.g. [[(coef, support_vector_index), ... ]]  
     304            
     305        """ 
     306        if isinstance(self.class_var, variable.Discrete): 
     307            # We need to reorder the coef values 
     308            # see http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f804 
     309            # for more information on how the coefs are stored by libsvm 
     310            # internally. 
     311            import numpy as np 
     312            c_map = self._get_libsvm_bin_classifier_map() 
     313            label_map = self._get_libsvm_labels_map() 
     314            libsvm_coef = self.__wrapped.coef 
     315            coef = [] #[None] * len(c_map) 
     316            n_class = len(label_map) 
     317            n_SV = self.__wrapped.n_SV 
     318            coef_array = np.array(self.__wrapped.coef) 
     319            p = 0 
     320            libsvm_class_indices = np.cumsum([0] + list(n_SV), dtype=int) 
     321            class_indices = np.cumsum([0] + list(self.n_SV), dtype=int) 
     322            for i in range(n_class - 1): 
     323                for j in range(i + 1, n_class): 
     324                    ni = label_map[i] 
     325                    nj = label_map[j] 
     326                    bc_index, mult = c_map[p] 
     327                     
     328                    if ni > nj: 
     329                        ni, nj = nj, ni 
     330                     
     331                    # Original class indices 
     332                    c1_range = range(libsvm_class_indices[ni], 
     333                                     libsvm_class_indices[ni + 1]) 
     334                    c2_range = range(libsvm_class_indices[nj],  
     335                                     libsvm_class_indices[nj + 1]) 
     336                     
     337                    coef1 = mult * coef_array[nj - 1, c1_range] 
     338                    coef2 = mult * coef_array[ni, c2_range] 
     339                     
     340                    # Mapped class indices 
     341                    c1_range = range(class_indices[i], 
     342                                     class_indices[i + 1]) 
     343                    c2_range = range(class_indices[j],  
     344                                     class_indices[j + 1]) 
     345                    if mult == -1.0: 
     346                        c1_range, c2_range = c2_range, c1_range 
     347                         
     348                    nonzero1 = np.abs(coef1) > 0.0 
     349                    nonzero2 = np.abs(coef2) > 0.0 
     350                     
     351                    coef1 = coef1[nonzero1] 
     352                    coef2 = coef2[nonzero2] 
     353                     
     354                    c1_range = [sv_i for sv_i, nz in zip(c1_range, nonzero1) if nz] 
     355                    c2_range = [sv_i for sv_i, nz in zip(c2_range, nonzero2) if nz] 
     356                     
     357                    coef.append(list(zip(coef1, c1_range)) + list(zip(coef2, c2_range))) 
     358                     
     359                    p += 1 
     360        else: 
     361            coef = [zip(self.__wrapped.coef[0], range(len(self.support_vectors)))] 
     362             
     363        return coef 
     364     
     365    @property 
     366    def rho(self): 
     367        """Constant (bias) terms of the svm model. 
     368         
     369        For classification models this is a list of bias terms  
     370        for each binary 1vs1 classifier. 
     371         
     372        For regression models it is a list with a single value. 
     373          
     374        """ 
     375        rho = self.__wrapped.rho 
     376        if isinstance(self.class_var, variable.Discrete): 
     377            c_map = self._get_libsvm_bin_classifier_map() 
     378            return [rho[i] * m for i, m in c_map] 
     379        else: 
     380            return list(rho) 
     381     
     382    @property 
     383    def n_SV(self): 
     384        """Number of support vectors for each class. 
     385        For regression models this is `None`. 
     386         
     387        """ 
     388        if self.__wrapped.n_SV is not None: 
     389            c_map = self._get_libsvm_labels_map() 
     390            n_SV= self.__wrapped.n_SV 
     391            return [n_SV[i] for i in c_map] 
     392        else: 
     393            return None 
     394     
     395    # Pairwise probability is expresed as: 
     396    #   1.0 / (1.0 + exp(dec_val[i] * prob_a[i] + prob_b[i]))  
     397    # Since dec_val already changes signs if we switch the  
     398    # classifier direction only prob_b must change signs 
     399    @property 
     400    def prob_a(self): 
     401        if self.__wrapped.prob_a is not None: 
     402            if isinstance(self.class_var, variable.Discrete): 
     403                c_map = self._get_libsvm_bin_classifier_map() 
     404                prob_a = self.__wrapped.prob_a 
     405                return [prob_a[i] for i, _ in c_map] 
     406            else: 
     407                # A single value for regression 
     408                return list(self.__wrapped.prob_a) 
     409        else: 
     410            return None 
     411     
     412    @property 
     413    def prob_b(self): 
     414        if self.__wrapped.prob_b is not None: 
     415            c_map = self._get_libsvm_bin_classifier_map() 
     416            prob_b = self.__wrapped.prob_b 
     417            # Change sign when changing the classifier direction 
     418            return [prob_b[i] * m for i, m in c_map] 
     419        else: 
     420            return None 
     421     
     422    def __call__(self, instance, what=Orange.core.GetValue): 
     423        """Classify a new ``instance`` 
     424        """ 
     425        instance = Orange.data.Instance(self.domain, instance) 
     426        return self.__wrapped(instance, what) 
     427 
     428    def class_distribution(self, instance): 
     429        """Return a class distribution for the ``instance`` 
     430        """ 
     431        instance = Orange.data.Instance(self.domain, instance) 
     432        return self.__wrapped.class_distribution(instance) 
     433 
     434    def get_decision_values(self, instance): 
     435        """Return the decision values of the binary 1vs1 
     436        classifiers for the ``instance`` (:class:`~Orange.data.Instance`). 
     437         
     438        """ 
     439        instance = Orange.data.Instance(self.domain, instance) 
     440        dec_values = self.__wrapped.get_decision_values(instance) 
     441        if isinstance(self.class_var, variable.Discrete): 
     442            # decision values are ordered by libsvm internal class values 
     443            # i.e. the order of labels in the data 
     444            c_map = self._get_libsvm_bin_classifier_map() 
     445            return [dec_values[i] * m for i, m in c_map] 
     446        else: 
     447            return list(dec_values) 
     448         
     449    def get_model(self): 
     450        """Return a string representing the model in the libsvm model format. 
     451        """ 
     452        return self.__wrapped.get_model() 
     453     
     454    def _get_libsvm_labels_map(self): 
     455        """Get the internal libsvm label mapping.  
     456        """ 
     457        labels = [line for line in self.__wrapped.get_model().splitlines() \ 
     458                  if line.startswith("label")] 
     459        labels = labels[0].split(" ")[1:] if labels else ["0"] 
     460        labels = [int(label) for label in labels] 
     461        return [labels.index(i) for i in range(len(labels))] 
     462 
     463    def _get_libsvm_bin_classifier_map(self): 
     464        """Return the libsvm binary classifier mapping (due to label ordering). 
     465        """ 
     466        if not isinstance(self.class_var, variable.Discrete): 
     467            raise TypeError("SVM classification model expected") 
     468        label_map = self._get_libsvm_labels_map() 
     469        bin_c_map = [] 
    278470        n_class = len(self.class_var.values) 
    279         new_values = [] 
     471        p = 0 
    280472        for i in range(n_class - 1): 
    281473            for j in range(i + 1, n_class): 
    282                 # Internal indices 
    283                 ni, nj = map.index(i), map.index(j) 
    284                 mult = 1.0 
     474                ni = label_map[i] 
     475                nj = label_map[j] 
     476                mult = 1 
    285477                if ni > nj: 
    286478                    ni, nj = nj, ni 
    287                     # Multiply by -1 if we switch the order of the 1vs1 
    288                     # classifier. 
    289                     mult = -1.0 
    290                 val_index = n_class * (n_class - 1) / 2 - (n_class - ni - 1) * (n_class - ni - 2) / 2 - (n_class - nj) 
    291                 new_values.append(mult * dec_values[val_index]) 
    292         return Orange.core.FloatList(new_values) 
    293          
    294     def get_model(self): 
    295         return self.wrapped.get_model() 
    296      
    297     def _get_libsvm_labels_map(self): 
    298         """Get the libsvm label mapping from the model string  
    299         """ 
    300         labels = [line for line in self.get_model().splitlines() \ 
    301                   if line.startswith("label")] 
    302         labels = labels[0].split(" ")[1:] if labels else ["0"] 
    303         return [int(label) for label in labels] 
    304  
     479                    mult = -1 
     480                # classifier index 
     481                cls_index = n_class * (n_class - 1) / 2 - (n_class - ni - 1) * (n_class - ni - 2) / 2 - (n_class - nj) 
     482                bin_c_map.append((cls_index, mult)) 
     483        return bin_c_map 
     484                 
    305485    def __reduce__(self): 
    306         return SVMClassifierWrapper, (self.wrapped,), dict([(name, val) \ 
    307             for name, val in self.__dict__.items() \ 
    308             if name not in self.wrapped.__dict__]) 
    309          
     486        return SVMClassifier, (self.__wrapped,), dict(self.__dict__) 
     487     
    310488    def get_binary_classifier(self, c1, c2): 
    311489        """Return a binary classifier for classes `c1` and `c2`. 
     
    317495        c1 = int(self.class_var(c1)) 
    318496        c2 = int(self.class_var(c2)) 
    319          
    320         libsvm_label = [line for line in self.get_model().splitlines() \ 
    321                         if line.startswith("label")] 
    322          
     497                 
    323498        n_class = len(self.class_var.values) 
    324499         
     
    329504                        (self.class_var.values[c1], self.class_var.values[c2]), 
    330505                        values=["0", "1"]) 
    331          
    332         # Map the libsvm labels  
    333         labels_map = self._get_libsvm_labels_map() 
    334         c1 = labels_map.index(c1) 
    335         c2 = labels_map.index(c2) 
    336506         
    337507        mult = 1.0 
     
    339509            c1, c2 = c2, c1 
    340510            mult = -1.0 
    341          
    342         # Index of the 1vs1 binary classifier  
     511             
    343512        classifier_i = n_class * (n_class - 1) / 2 - (n_class - c1 - 1) * (n_class - c1 - 2) / 2 - (n_class - c2) 
    344513         
    345         # Indices for classes in the coef structure. 
    346         class_indices = np.cumsum([0] + list(self.n_SV), dtype=int) 
    347         c1_range = range(class_indices[c1], class_indices[c1 + 1]) 
    348         c2_range = range(class_indices[c2], class_indices[c2 + 1]) 
    349          
    350         coef_array = np.array(self.coef) 
    351         coef1 = mult * coef_array[c2 - 1, c1_range] 
    352         coef2 = mult * coef_array[c1, c2_range] 
    353          
    354         # Support vectors for the binary classifier 
    355         sv1 = [self.support_vectors[i] for i in c1_range] 
    356         sv2 = [self.support_vectors[i] for i in c2_range] 
    357          
    358         # Rho for the classifier 
     514        coef = self.coef[classifier_i] 
     515         
     516        coef1 = [(mult * alpha, sv_i) for alpha, sv_i in coef \ 
     517                 if int(self.support_vectors[sv_i].get_class()) == c1] 
     518        coef2 = [(mult * alpha, sv_i) for alpha, sv_i in coef \ 
     519                 if int(self.support_vectors[sv_i].get_class()) == c2]  
     520         
    359521        rho = mult * self.rho[classifier_i] 
    360522         
    361         # Filter non zero support vectors 
    362         nonzero1 = np.abs(coef1) > 0.0 
    363         nonzero2 = np.abs(coef2) > 0.0 
    364          
    365         coef1 = coef1[nonzero1] 
    366         coef2 = coef2[nonzero2] 
    367          
    368         sv1 = [sv for sv, nz in zip(sv1, nonzero1) if nz] 
    369         sv2 = [sv for sv, nz in zip(sv2, nonzero2) if nz] 
    370          
    371         sv_indices1 = [i for i, nz in zip(c1_range, nonzero1) if nz] 
    372         sv_indices2 = [i for i, nz in zip(c2_range, nonzero2) if nz] 
    373          
    374         model = self._binary_libsvm_model(bin_class_var, [coef1, coef2], 
    375                                           [rho], sv_indices1 + sv_indices2) 
    376          
    377         all_sv = Orange.data.Table(sv1 + sv2) 
     523        model = self._binary_libsvm_model_string(bin_class_var,  
     524                                                 [coef1, coef2], 
     525                                                 [rho]) 
     526         
     527        all_sv = [self.support_vectors[sv_i] \ 
     528                  for c, sv_i in coef1 + coef2]  
     529                   
     530        all_sv = Orange.data.Table(all_sv) 
     531         
     532        svm_classifier_type = type(self.__wrapped) 
     533         
     534        # Build args for svm_classifier_type constructor 
     535        args = (bin_class_var, self.examples, all_sv, model) 
     536         
     537        if isinstance(svm_classifier_type, _SVMClassifierSparse): 
     538            args = args + (int(self.__wrapped.use_non_meta),) 
     539         
    378540        if self.kernel_type == kernels.Custom: 
    379             classifier = SVMClassifier(bin_class_var, self.examples, 
    380                                        all_sv, model, self.kernel_func) 
    381         else: 
    382             classifier = SVMClassifier(bin_class_var, self.examples, 
    383                                        all_sv, model) 
     541            args = args + (self.kernel_func,) 
    384542             
    385         return SVMClassifierWrapper(classifier) 
    386      
    387     def _binary_libsvm_model(self, class_var, coefs, rho, sv_indices): 
    388         """Return a libsvm formated model string for binary subclassifier 
     543        native_classifier = svm_classifier_type(*args) 
     544        return SVMClassifier(native_classifier) 
     545     
     546    def _binary_libsvm_model_string(self, class_var, coef, rho): 
     547        """Return a libsvm formated model string for binary classifier 
    389548        """ 
    390549        import itertools 
    391550         
     551        if not isinstance(self.class_var, variable.Discrete): 
     552            raise TypeError("SVM classification model expected") 
     553         
    392554        model = [] 
    393555         
    394556        # Take the model up to nr_classes 
    395         for line in self.get_model().splitlines(): 
     557        libsvm_model = self.__wrapped.get_model() 
     558        for line in libsvm_model.splitlines(): 
    396559            if line.startswith("nr_class"): 
    397560                break 
     
    400563         
    401564        model.append("nr_class %i" % len(class_var.values)) 
    402         model.append("total_sv %i" % len(sv_indices)) 
     565        model.append("total_sv %i" % reduce(add, [len(c) for c in coef])) 
    403566        model.append("rho " + " ".join(str(r) for r in rho)) 
    404567        model.append("label " + " ".join(str(i) for i in range(len(class_var.values)))) 
    405568        # No probA and probB 
    406569         
    407         model.append("nr_sv " + " ".join(str(len(c)) for c in coefs)) 
     570        model.append("nr_sv " + " ".join(str(len(c)) for c in coef)) 
    408571        model.append("SV") 
    409572         
     
    414577            return " ".join("%i:%f" % (i + 1, v) for i, v in values) 
    415578         
     579        def sparse_instance_to_svm(inst): 
     580            non_meta = [] 
     581            base = 1 
     582            if self.__wrapped.use_non_meta: 
     583                non_meta = [instance_to_svm(inst)] 
     584                base += len(inst.domain) 
     585            metas = [] 
     586            for m_id, value in sorted(inst.get_metas().items(), reverse=True): 
     587                if not value.isSpecial() and float(value) != 0: 
     588                    metas.append("%i:%f" % (base - m_id, float(value))) 
     589            return " ".join(non_meta + metas) 
     590                 
     591        if isinstance(self.__wrapped, _SVMClassifierSparse): 
     592            converter = sparse_instance_to_svm 
     593        else: 
     594            converter = instance_to_svm 
     595         
    416596        if self.kernel_type == kernels.Custom: 
    417             SV = self.get_model().split("SV\n", 1)[1] 
    418             # Get the sv indices (the last entry in the SV entrys) 
     597            SV = libsvm_model.split("SV\n", 1)[1] 
     598            # Get the sv indices (the last entry in the SV lines) 
    419599            indices = [int(s.split(":")[-1]) for s in SV.splitlines() if s.strip()] 
    420             for c, sv_i in zip(itertools.chain(*coefs), itertools.chain(sv_indices)): 
     600             
     601            # Reorder the indices  
     602            label_map = self._get_libsvm_labels_map() 
     603            start = 0 
     604            reordered_indices = [] 
     605            for n in self.__wrapped.n_SV: 
     606                reordered_indices.append(indices[start: start + n]) 
     607                start += n 
     608            reordered_indices = [reordered_indices[i] for i in label_map] 
     609            indices = reduce(add, reordered_indices) 
     610             
     611            for (c, sv_i) in itertools.chain(*coef): 
    421612                model.append("%f 0:%i" % (c, indices[sv_i])) 
    422613        else: 
    423             for c, sv_i in zip(itertools.chain(*coefs), itertools.chain(sv_indices)): 
    424                 model.append("%f %s" % (c, instance_to_svm(self.support_vectors[sv_i]))) 
     614            for (c, sv_i) in itertools.chain(*coef): 
     615                model.append("%f %s" % (c, converter(self.support_vectors[sv_i]))) 
    425616                 
    426617        model.append("") 
     
    428619         
    429620 
    430 SVMClassifierWrapper = Orange.utils.deprecated_members({ 
     621SVMClassifier = Orange.utils.deprecated_members({ 
    431622    "classDistribution": "class_distribution", 
    432623    "getDecisionValues": "get_decision_values", 
    433624    "getModel" : "get_model", 
    434     })(SVMClassifierWrapper) 
     625    }, wrap_methods=[])(SVMClassifier) 
     626     
     627# Backwards compatibility (pickling) 
     628SVMClassifierWrapper = SVMClassifier 
    435629 
    436630class SVMLearnerSparse(SVMLearner): 
     
    499693            parameters.append(("gamma", [2 ** a for a in range(-5, 5, 2)] + [0])) 
    500694        import orngWrap 
    501         tunedLearner = orngWrap.TuneMParameters(object=self.learner, 
     695        tunedLearner = orngWrap.TuneMParameters(learner=self.learner, 
    502696                                                parameters=parameters, 
    503697                                                folds=self.folds) 
    504698 
    505         return SVMClassifierWrapper(tunedLearner(newexamples, 
    506                                                  verbose=self.verbose)) 
    507  
    508 class SVMLearnerSparseClassEasy(SVMLearnerEasy, SVMLearnerSparse): 
     699        return tunedLearner(newexamples, verbose=self.verbose) 
     700 
     701class SVMLearnerSparseEasy(SVMLearnerEasy): 
    509702    def __init__(self, **kwds): 
    510         SVMLearnerSparse.__init__(self, **kwds) 
     703        SVMLearnerEasy.__init__(self, **kwds) 
     704        self.learner = SVMLearnerSparse(**kwds) 
    511705 
    512706def default_preprocessor(): 
     
    612806 
    613807    SVs = classifier.support_vectors 
    614     weights = [] 
    615  
    616808    class_var = SVs.domain.class_var 
    617     if classifier.svm_type not in [SVMLearner.C_SVC, SVMLearner.Nu_SVC]: 
    618         raise TypeError("SVM classification model expected.") 
    619      
    620     classes = classifier.class_var.values 
    621      
    622     for i in range(len(classes) - 1): 
    623         for j in range(i + 1, len(classes)): 
    624             # Get the coef and rho values from the binary sub-classifier 
    625             # Easier then using the full coef matrix (due to libsvm internal 
    626             # class  reordering) 
    627             bin_classifier = classifier.get_binary_classifier(i, j) 
    628             n_sv0 = bin_classifier.n_SV[0] 
    629             SVs = bin_classifier.support_vectors 
    630             w = {} 
    631              
    632             for SV, alpha in zip(SVs, bin_classifier.coef[0]): 
    633                 attributes = SVs.domain.attributes + \ 
    634                 SV.getmetas(False, Orange.feature.Descriptor).keys() 
    635                 for attr in attributes: 
    636                     if attr.varType == Orange.feature.Type.Continuous: 
    637                         update_weights(w, attr, to_float(SV[attr]), alpha) 
     809     
     810    if classifier.svm_type in [SVMLearner.C_SVC, SVMLearner.Nu_SVC]: 
     811        weights = []     
     812        classes = classifier.class_var.values 
     813        for i in range(len(classes) - 1): 
     814            for j in range(i + 1, len(classes)): 
     815                # Get the coef and rho values from the binary sub-classifier 
     816                # Easier then using the full coef matrix (due to libsvm internal 
     817                # class  reordering) 
     818                bin_classifier = classifier.get_binary_classifier(i, j) 
     819                n_sv0 = bin_classifier.n_SV[0] 
     820                SVs = bin_classifier.support_vectors 
     821                w = {} 
    638822                 
    639             weights.append(w) 
    640              
    641     if sum: 
    642         scores = defaultdict(float) 
    643  
    644         for w in weights: 
    645             for attr, w_attr in w.items(): 
    646                 scores[attr] += w_attr ** 2 
    647         for key in scores: 
    648             scores[key] = math.sqrt(scores[key]) 
    649         return dict(scores) 
     823                for coef, sv_ind in bin_classifier.coef[0]: 
     824                    SV = SVs[sv_ind] 
     825                    attributes = SVs.domain.attributes + \ 
     826                    SV.getmetas(False, Orange.feature.Descriptor).keys() 
     827                    for attr in attributes: 
     828                        if attr.varType == Orange.feature.Type.Continuous: 
     829                            update_weights(w, attr, to_float(SV[attr]), coef) 
     830                     
     831                weights.append(w) 
     832        if sum: 
     833            scores = defaultdict(float) 
     834            for w in weights: 
     835                for attr, w_attr in w.items(): 
     836                    scores[attr] += w_attr ** 2 
     837            for key in scores: 
     838                scores[key] = math.sqrt(scores[key]) 
     839            weights = dict(scores) 
    650840    else: 
    651         return weights 
    652  
     841#        raise TypeError("SVM classification model expected.") 
     842        weights = {} 
     843        for coef, sv_ind in classifier.coef[0]: 
     844            SV = SVs[sv_ind] 
     845            attributes = SVs.domain.attributes + \ 
     846            SV.getmetas(False, Orange.feature.Descriptor).keys() 
     847            for attr in attributes: 
     848                if attr.varType == Orange.feature.Type.Continuous: 
     849                    update_weights(weights, attr, to_float(SV[attr]), coef) 
     850            
     851    return weights  
     852     
    653853getLinearSVMWeights = get_linear_svm_weights 
    654854 
  • Orange/clustering/hierarchical.py

    r10581 r10633  
    368368 
    369369from Orange.utils import progress_bar_milestones, deprecated_keywords 
    370                          
     370 
    371371import sys 
    372372 
     
    408408    matrix = Orange.misc.SymMatrix(len(data)) 
    409409    for i in range(len(data)): 
    410         for j in range(i+1): 
     410        for j in range(i + 1): 
    411411            matrix[i, j] = distance(data[i], data[j]) 
    412     root = HierarchicalClustering(matrix, linkage=linkage, progress_callback=(lambda value, obj=None: progress_callback(value*100.0/(2 if order else 1))) if progress_callback else None) 
     412    root = HierarchicalClustering(matrix, linkage=linkage, progress_callback=(lambda value, obj=None: progress_callback(value * 100.0 / (2 if order else 1))) if progress_callback else None) 
    413413    if order: 
    414         order_leaves(root, matrix, progress_callback=(lambda value: progress_callback(50.0 + value/2)) if progress_callback else None) 
     414        order_leaves(root, matrix, progress_callback=(lambda value: progress_callback(50.0 + value / 2)) if progress_callback else None) 
    415415    return root 
    416416 
     
    447447        for a2 in range(a1): 
    448448            matrix[a1, a2] = (1.0 - orange.PearsonCorrelation(a1, a2, data, 0).r) / 2.0 
    449     root = orange.HierarchicalClustering(matrix, linkage=linkage, progress_callback=(lambda value, obj=None: progress_callback(value*100.0/(2 if order else 1))) if progress_callback else None) 
     449    root = orange.HierarchicalClustering(matrix, linkage=linkage, progress_callback=(lambda value, obj=None: progress_callback(value * 100.0 / (2 if order else 1))) if progress_callback else None) 
    450450    if order: 
    451         order_leaves(root, matrix, progressCallback=(lambda value: progress_callback(50.0 + value/2)) if progress_callback else None) 
     451        order_leaves(root, matrix, progressCallback=(lambda value: progress_callback(50.0 + value / 2)) if progress_callback else None) 
    452452    return root 
    453453 
    454454clustering_features = \ 
    455455    deprecated_keywords({"progressCallback":"progress_callback"})(clustering_features) 
    456      
    457      
     456 
     457 
    458458def cluster_to_list(node, prune=None): 
    459459    """ Return a list of clusters down from the node of hierarchical clustering. 
     
    470470    if prune: 
    471471        if len(node) <= prune: 
    472             return []  
     472            return [] 
    473473    if node.branches: 
    474474        return [node] + cluster_to_list(node.left, prune) + cluster_to_list(node.right, prune) 
     
    528528     
    529529    """ 
    530      
     530 
    531531    objects = getattr(tree.mapping, "objects", None) 
    532532    tree.mapping.setattr("objects", range(len(tree))) 
     
    534534    ordering = {} 
    535535    visited_clusters = set() 
    536      
     536 
    537537#    def opt_ordering_recursive(tree): 
    538538#        if len(tree)==1: 
     
    588588#    with recursion_limit(sys.getrecursionlimit() + len(tree)): 
    589589#        opt_ordering_recursive(tree) 
    590          
     590 
    591591    def opt_ordering_iterative(tree): 
    592         if len(tree)==1: 
     592        if len(tree) == 1: 
    593593            for leaf in tree: 
    594594                M[tree, leaf, leaf] = 0 
     
    596596#            _optOrdering(tree.left) 
    597597#            _optOrdering(tree.right) 
    598              
     598 
    599599            Vl = set(tree.left) 
    600600            Vr = set(tree.right) 
     
    612612                        ordered_k = sorted(other(w, Vrl, Vrr), key=lambda k: M[tree_right, w, k]) 
    613613                        k0 = ordered_k[0] 
    614                         cur_min = 1e30000  
     614                        cur_min = 1e30000 
    615615                        cur_m = cur_k = None 
    616616                        for m in ordered_m: 
     
    639639#                progressCallback(100.0 * len(visited_clusters) / len(tree.mapping)) 
    640640#                visited_clusters.add(tree) 
    641      
     641 
    642642    subtrees = postorder(tree) 
    643643    milestones = progress_bar_milestones(len(subtrees), 1000) 
    644      
     644 
    645645    for i, subtree in enumerate(subtrees): 
    646646        opt_ordering_iterative(subtree) 
     
    661661#            right.swap() 
    662662#        order_recursive(right, k, w) 
    663          
     663 
    664664    def order_iterative(tree, u, w): 
    665665        """ Order the tree based on the computed optimal ordering.  
     
    672672                opt_uw[left] = (u, m) 
    673673                opt_uw[right] = (k, w) 
    674                  
     674 
    675675                if left.branches and m not in left.right: 
    676676                    left.swap() 
    677                  
     677 
    678678                if right.branches and k not in right.left: 
    679679                    right.swap() 
    680      
     680 
    681681    u, w = min([(u, w) for u in tree.left for w in tree.right], key=lambda (u, w): M[tree, u, w]) 
    682      
     682 
    683683##    print "M(v) =", M[tree, u, w] 
    684      
     684 
    685685#    with recursion_limit(sys.getrecursionlimit() + len(tree)): 
    686686#        order_recursive(tree, u, w) 
    687              
     687 
    688688    order_iterative(tree, u, w) 
    689              
     689 
    690690 
    691691#    def _check(tree, u, w): 
     
    722722    """ 
    723723    node_count = iter(range(len(tree))) 
    724      
     724 
    725725    if progress_callback is not None: 
    726726        def p(*args): 
     
    728728    else: 
    729729        p = None 
    730      
     730 
    731731    Orange.core.HierarchicalClusterOrdering(tree, matrix, progress_callback=p) 
    732732 
     
    735735 
    736736order_leaves = order_leaves_cpp 
    737      
     737 
    738738""" 
    739739Matplotlib dendrogram ploting. This is mostly untested, 
     
    774774 
    775775    def add_cell(self, row, col, *args, **kwargs): 
    776         xy = (0,0) 
     776        xy = (0, 0) 
    777777 
    778778        cell = TableCell(xy, *args, **kwargs) 
     
    798798        cells = numpy.array([[self._cells.get((row, col), None) for col in range(max(keys[:, 1] + 1))] \ 
    799799                             for row in range(max(keys[:, 0] + 1))]) 
    800          
     800 
    801801        widths = self._get_column_widths(renderer) 
    802802        x = self.xy[0] + numpy.array([numpy.sum(widths[:i]) for i in range(len(widths))]) 
    803803        y = self.xy[1] - numpy.arange(cells.shape[0]) - 0.5 
    804          
     804 
    805805        for i in range(cells.shape[0]): 
    806806            for j in range(cells.shape[1]): 
     
    816816    def _get_column_widths(self, renderer): 
    817817        keys = numpy.array(self._cells.keys()) 
    818         widths = numpy.zeros(len(keys)).reshape((numpy.max(keys[:,0]+1), numpy.max(keys[:,1]+1))) 
     818        widths = numpy.zeros(len(keys)).reshape((numpy.max(keys[:, 0] + 1), numpy.max(keys[:, 1] + 1))) 
    819819        fontSize = self._calc_fontsize(renderer) 
    820820        for (row, col), cell in self._cells.items(): 
     
    823823            transform = self._axes.transData.inverted() 
    824824            x1, _ = transform.transform_point((0, 0)) 
    825             x2, _ = transform.transform_point((w + w*TableCell.PAD + 10, 0)) 
     825            x2, _ = transform.transform_point((w + w * TableCell.PAD + 10, 0)) 
    826826            w = abs(x1 - x2) 
    827827            widths[row, col] = w 
     
    832832        _, y1 = transform.transform_point((0, 0)) 
    833833        _, y2 = transform.transform_point((0, 1)) 
    834         return min(max(int(abs(y1 - y2)*0.85) ,4), self.max_fontsize) 
     834        return min(max(int(abs(y1 - y2) * 0.85) , 4), self.max_fontsize) 
    835835 
    836836    def get_children(self): 
     
    867867                    points.append(center) 
    868868                self.plt.plot([tree.height, tree.height], [points[0][1], points[-1][1]], color="black") 
    869                 return (tree.height, (points[0][1] + points[-1][1])/2.0) 
     869                return (tree.height, (points[0][1] + points[-1][1]) / 2.0) 
    870870            else: 
    871871                return (0.0, tree.first) 
    872872        draw_tree(self.root) 
    873          
     873 
    874874    def plotHeatMap(self): 
    875875        import numpy.ma as ma 
    876876        import numpy 
    877877        dx, dy = self.root.height, 0 
    878         fx, fy = self.root.height/len(self.data.domain.attributes), 1.0 
     878        fx, fy = self.root.height / len(self.data.domain.attributes), 1.0 
    879879        data, c, w = self.data.toNumpyMA() 
    880         data = (data - ma.min(data))/(ma.max(data) - ma.min(data)) 
    881         x = numpy.arange(data.shape[1] + 1)/float(numpy.max(data.shape)) 
    882         y = numpy.arange(data.shape[0] + 1)/float(numpy.max(data.shape))*len(self.root) 
     880        data = (data - ma.min(data)) / (ma.max(data) - ma.min(data)) 
     881        x = numpy.arange(data.shape[1] + 1) / float(numpy.max(data.shape)) 
     882        y = numpy.arange(data.shape[0] + 1) / float(numpy.max(data.shape)) * len(self.root) 
    883883        self.heatmap_width = numpy.max(x) 
    884884 
     
    892892        if self.plot_attr_names: 
    893893            names = [attr.name for attr in self.data.domain.attributes] 
    894             self.plt.xticks(numpy.arange(data.shape[1] + 1)/float(numpy.max(data.shape)), names) 
     894            self.plt.xticks(numpy.arange(data.shape[1] + 1) / float(numpy.max(data.shape)), names) 
    895895        self.plt.gca().xaxis.tick_top() 
    896896        for label in self.plt.gca().xaxis.get_ticklabels(): 
     
    909909##            tick.label2On = True 
    910910##        text = TableTextLayout(xy=(self.meshXOffset+1, len(self.root)), tableText=[[label] for label in self.labels]) 
    911         text = TableTextLayout(xy=(self.meshXOffset*1.005, len(self.root) - 1), tableText=[[label] for label in self.labels]) 
     911        text = TableTextLayout(xy=(self.meshXOffset * 1.005, len(self.root) - 1), tableText=[[label] for label in self.labels]) 
    912912        text.set_figure(self.plt.gcf()) 
    913913        self.plt.gca().add_artist(text) 
     
    916916    def plotLabels(self): 
    917917##        table = TablePlot(xy=(self.meshXOffset*1.005, len(self.root) -1), axes=self.plt.gca()) 
    918         table = TablePlot(xy=(0, len(self.root) -1), axes=self.plt.gca()) 
     918        table = TablePlot(xy=(0, len(self.root) - 1), axes=self.plt.gca()) 
    919919        table.set_figure(self.plt.gcf()) 
    920         for i,label in enumerate(self.labels): 
     920        for i, label in enumerate(self.labels): 
    921921            table.add_cell(i, 0, width=1, height=1, text=label, loc="left", edgecolor="w") 
    922922        table.set_zorder(0) 
    923923        self.plt.gca().add_artist(table) 
    924924        self.plt.gca()._set_artist_props(table) 
    925      
     925 
    926926    def plot(self, filename=None, show=False): 
    927927        self.plt.rcParams.update(self.params) 
     
    930930        space = 0.01 if self.space_width == None else self.space_width 
    931931        border = self.border_width 
    932         width = 1.0 - 2*border 
    933         height = 1.0 - 2*border 
    934         textLineHeight = min(max(h/len(self.labels), 4), self.plt.rcParams.get("font.size", 12)) 
    935         maxTextLineWidthEstimate = textLineHeight*labelLen 
     932        width = 1.0 - 2 * border 
     933        height = 1.0 - 2 * border 
     934        textLineHeight = min(max(h / len(self.labels), 4), self.plt.rcParams.get("font.size", 12)) 
     935        maxTextLineWidthEstimate = textLineHeight * labelLen 
    936936##        print maxTextLineWidthEstimate 
    937         textAxisWidthRatio = 2.0*maxTextLineWidthEstimate/w 
     937        textAxisWidthRatio = 2.0 * maxTextLineWidthEstimate / w 
    938938##        print textAxisWidthRatio 
    939939        labelsAreaRatio = min(textAxisWidthRatio, 0.4) if self.label_width == None else self.label_width 
    940940        x, y = len(self.data.domain.attributes), len(self.data) 
    941941 
    942         heatmapAreaRatio = min(1.0*y/h*x/w, 0.3) if self.heatmap_width == None else self.heatmap_width 
    943         dendrogramAreaRatio = 1.0 - labelsAreaRatio - heatmapAreaRatio - 2*space if self.dendrogram_width == None else self.dendrogram_width 
     942        heatmapAreaRatio = min(1.0 * y / h * x / w, 0.3) if self.heatmap_width == None else self.heatmap_width 
     943        dendrogramAreaRatio = 1.0 - labelsAreaRatio - heatmapAreaRatio - 2 * space if self.dendrogram_width == None else self.dendrogram_width 
    944944 
    945945        self.fig = self.plt.figure() 
    946         self.labels_offset = self.root.height/20.0 
    947         dendrogramAxes = self.plt.axes([border, border, width*dendrogramAreaRatio, height]) 
     946        self.labels_offset = self.root.height / 20.0 
     947        dendrogramAxes = self.plt.axes([border, border, width * dendrogramAreaRatio, height]) 
    948948        dendrogramAxes.xaxis.grid(True) 
    949949        import matplotlib.ticker as ticker 
     
    953953        dendrogramAxes.invert_xaxis() 
    954954        self.plotDendrogram() 
    955         heatmapAxes = self.plt.axes([border + width*dendrogramAreaRatio + space, border, width*heatmapAreaRatio, height], sharey=dendrogramAxes) 
     955        heatmapAxes = self.plt.axes([border + width * dendrogramAreaRatio + space, border, width * heatmapAreaRatio, height], sharey=dendrogramAxes) 
    956956 
    957957        heatmapAxes.xaxis.set_major_locator(ticker.NullLocator()) 
     
    959959        heatmapAxes.yaxis.set_major_locator(ticker.NullLocator()) 
    960960        heatmapAxes.yaxis.set_minor_locator(ticker.NullLocator()) 
    961          
     961 
    962962        self.plotHeatMap() 
    963         labelsAxes = self.plt.axes([border + width*(dendrogramAreaRatio + heatmapAreaRatio + 2*space), border, width*labelsAreaRatio, height], sharey=dendrogramAxes) 
     963        labelsAxes = self.plt.axes([border + width * (dendrogramAreaRatio + heatmapAreaRatio + 2 * space), border, width * labelsAreaRatio, height], sharey=dendrogramAxes) 
    964964        self.plotLabels() 
    965965        labelsAxes.set_axis_off() 
     
    974974        if show: 
    975975            self.plt.show() 
    976          
    977          
     976 
     977 
    978978""" 
    979979Dendrogram ploting using Orange.utils.render 
     
    994994         
    995995    """ 
    996     def __init__(self, tree, attr_tree = None, labels=None, data=None, width=None, height=None, tree_height=None, heatmap_width=None, text_width=None,  
     996    def __init__(self, tree, attr_tree=None, labels=None, data=None, width=None, height=None, tree_height=None, heatmap_width=None, text_width=None, 
    997997                 spacing=2, cluster_colors={}, color_palette=ColorPalette([(255, 0, 0), (0, 255, 0)]), maxv=None, minv=None, gamma=None, renderer=EPSRenderer, **kwargs): 
    998998        self.tree = tree 
     
    10061006                labels = [""] * len(tree) 
    10071007        self.labels = labels 
    1008          
     1008 
    10091009#        self.attr_labels = [str(attr.name) for attr in data.domain.attributes] if not attr_labels and data else attr_labels or [] 
    10101010        self.data = data 
     
    10251025        self.set_matrix_color_schema(color_palette, minv, maxv, gamma) 
    10261026        self.renderer = renderer 
    1027          
     1027 
    10281028    def set_matrix_color_schema(self, color_palette, minv, maxv, gamma=None): 
    10291029        """ Set the matrix color scheme. 
     
    10361036        self.maxv = maxv 
    10371037        self.gamma = gamma 
    1038          
     1038 
    10391039    def color_shema(self): 
    1040         vals = [float(val) for ex in self.data for val in ex if not val.isSpecial() and val.variable.varType==orange.VarTypes.Continuous] or [0] 
    1041         avg = sum(vals)/len(vals) 
    1042          
     1040        vals = [float(val) for ex in self.data for val in ex if not val.isSpecial() and val.variable.varType == orange.VarTypes.Continuous] or [0] 
     1041        avg = sum(vals) / len(vals) 
     1042 
    10431043        maxVal = self.maxv if self.maxv else max(vals) 
    10441044        minVal = self.minv if self.minv else min(vals) 
    1045          
     1045 
    10461046        def _colorSchema(val): 
    10471047            if val.isSpecial(): 
    10481048                return self.color_palette(None) 
    1049             elif val.variable.varType==orange.VarTypes.Continuous: 
     1049            elif val.variable.varType == orange.VarTypes.Continuous: 
    10501050                r, g, b = self.color_palette((float(val) - minVal) / abs(maxVal - minVal), gamma=self.gamma) 
    1051             elif val.variable.varType==orange.VarTypes.Discrete: 
    1052                 r = g = b = int(255.0*float(val)/len(val.variable.values)) 
     1051            elif val.variable.varType == orange.VarTypes.Discrete: 
     1052                r = g = b = int(255.0 * float(val) / len(val.variable.values)) 
    10531053            return (r, g, b) 
    10541054        return _colorSchema 
    1055      
     1055 
    10561056    def layout(self): 
    10571057        height_final = False 
     
    10611061            height, height_final = self.height, True 
    10621062            heatmap_height = height - (tree_height + self.spacing if self.attr_tree else 0) - 2 * self.horizontal_margin 
    1063             font_size =  heatmap_height / len(self.labels) #self.font_size or (height - (tree_height + self.spacing if self.attr_tree else 0) - 2 * self.horizontal_margin) / len(self.labels) 
     1063            font_size = heatmap_height / len(self.labels) #self.font_size or (height - (tree_height + self.spacing if self.attr_tree else 0) - 2 * self.horizontal_margin) / len(self.labels) 
    10641064        else: 
    10651065            font_size = self.font_size 
    10661066            heatmap_height = font_size * len(self.labels) 
    10671067            height = heatmap_height + (tree_height + self.spacing if self.attr_tree else 0) + 2 * self.horizontal_margin 
    1068               
     1068 
    10691069        text_width = self.text_width or max([len(label) for label in self.labels] + [0]) * font_size #max([self.renderer.string_size_hint(label) for label in self.labels]) 
    1070          
     1070 
    10711071        if self.width: 
    10721072            width = self.width 
     
    10751075            heatmap_width = len(self.data.domain.attributes) * heatmap_height / len(self.data) if self.data else 0 
    10761076            width = 2 * self.vertical_margin + tree_height + (heatmap_width + self.spacing if self.data else 0) + self.spacing + text_width 
    1077              
     1077 
    10781078        return width, height, tree_height, heatmap_width, heatmap_height, text_width, font_size 
    1079      
     1079 
    10801080    def plot(self, filename="graph.eps", **kwargs): 
    10811081        width, height, tree_height, heatmap_width, heatmap_height, text_width, font_size = self.layout() 
     
    10831083 
    10841084        heatmap_cell_width = 0.0 if not self.data else heatmap_width / len(self.data.domain.attributes) 
    1085          
     1085 
    10861086        self.renderer = self.renderer(width, height) 
    1087          
     1087 
    10881088        def draw_tree(cluster, root, treeheight, treewidth, color): 
    10891089            height = treeheight * cluster.height / root.height 
     
    10931093                    center = draw_tree(branch, root, treeheight, treewidth, self.cluster_colors.get(branch, color)) 
    10941094                    centers.append(center) 
    1095                     self.renderer.draw_line(center[0], center[1], center[0], height, stroke_color = self.cluster_colors.get(branch, color)) 
    1096                      
    1097                 self.renderer.draw_line(centers[0][0], height, centers[-1][0], height, stroke_color = self.cluster_colors.get(cluster, color)) 
     1095                    self.renderer.draw_line(center[0], center[1], center[0], height, stroke_color=self.cluster_colors.get(branch, color)) 
     1096 
     1097                self.renderer.draw_line(centers[0][0], height, centers[-1][0], height, stroke_color=self.cluster_colors.get(cluster, color)) 
    10981098                return (centers[0][0] + centers[-1][0]) / 2.0, height 
    10991099            else: 
     
    11031103        self.renderer.rotate(90) 
    11041104#        print self.renderer.transform() 
    1105         draw_tree(self.tree, self.tree, tree_height, heatmap_height, self.cluster_colors.get(self.tree, (0,0,0))) 
     1105        draw_tree(self.tree, self.tree, tree_height, heatmap_height, self.cluster_colors.get(self.tree, (0, 0, 0))) 
    11061106        self.renderer.restore_render_state() 
    11071107        if self.attr_tree: 
     
    11101110            self.renderer.scale(1.0, -1.0) 
    11111111#            print self.renderer.transform() 
    1112             draw_tree(self.attr_tree, self.attr_tree, tree_height, heatmap_width, self.cluster_colors.get(self.attr_tree, (0,0,0))) 
     1112            draw_tree(self.attr_tree, self.attr_tree, tree_height, heatmap_width, self.cluster_colors.get(self.attr_tree, (0, 0, 0))) 
    11131113            self.renderer.restore_render_state() 
    1114          
     1114 
    11151115        self.renderer.save_render_state() 
    11161116        self.renderer.translate(self.vertical_margin + tree_height + self.spacing, self.horizontal_margin + (tree_height + self.spacing if self.attr_tree else 0)) 
     
    11231123                    r, g, b = colorSchema(ex[jj]) 
    11241124                    self.renderer.draw_rect(j * heatmap_cell_width, i * heatmap_cell_height, heatmap_cell_width, heatmap_cell_height, fill_color=(r, g, b), stroke_color=(255, 255, 255)) 
    1125          
     1125 
    11261126        self.renderer.translate(heatmap_width + self.spacing, heatmap_cell_height) 
    11271127#        print self.renderer.transform() 
     
    11321132        self.renderer.restore_render_state() 
    11331133        self.renderer.save(filename, **kwargs) 
    1134          
    1135          
     1134 
     1135 
    11361136def dendrogram_draw(file, cluster, attr_cluster=None, labels=None, data=None, 
    11371137                    width=None, height=None, tree_height=None, 
    1138                     heatmap_width=None, text_width=None,  spacing=2, 
     1138                    heatmap_width=None, text_width=None, spacing=2, 
    11391139                    cluster_colors={}, 
    11401140                    color_palette=ColorPalette([(255, 0, 0), (0, 255, 0)]), 
     
    11931193        name, ext = os.path.splitext(file) 
    11941194        format = ext.lower().lstrip(".") or format 
    1195          
     1195 
    11961196    if format is None: 
    11971197        format = "png" 
    1198          
     1198 
    11991199    renderer = {"eps":EPSRenderer, "svg":SVGRenderer, "png":PILRenderer}.get(format, "png") 
    1200      
     1200 
    12011201    d = DendrogramPlot(cluster, attr_cluster, labels, data, width, height, 
    12021202                       tree_height, heatmap_width, text_width, spacing, 
     
    12071207    else: 
    12081208        d.plot(file) 
    1209      
     1209 
    12101210def postorder(cluster): 
    12111211    """ Return a post order list of clusters. 
     
    12221222    while stack: 
    12231223        cluster = stack.pop(0) 
    1224          
     1224 
    12251225        if cluster.branches: 
    12261226            if cluster in visited: 
     
    12331233            visited.add(cluster) 
    12341234    return order 
    1235      
    1236      
     1235 
     1236 
    12371237def preorder(cluster): 
    12381238    """ Return a pre order list of clusters. 
     
    12521252            stack = cluster.branches + stack 
    12531253    return order 
    1254      
    1255      
     1254 
     1255 
    12561256def dendrogram_layout(cluster, expand_leaves=False): 
    12571257    """ Return a layout of the cluster dendrogram on a 2D plane. The return  
     
    12921292            cluster_geometry[cluster] = (start, center, end) 
    12931293            result.append((cluster, (start, center, end))) 
    1294              
     1294 
    12951295    return result 
    1296      
     1296 
    12971297def clone(cluster): 
    12981298    """ Clone a cluster, including it's subclusters. 
     
    13131313        node_clone.mapping = mapping 
    13141314        clones[node] = node_clone 
    1315          
     1315 
    13161316    return clones[cluster] 
    1317      
     1317 
    13181318def pruned(cluster, level=None, height=None, condition=None): 
    13191319    """ Return a new pruned clustering instance.     
     
    13421342    prune(cluster, level, height, condition) 
    13431343    return cluster 
    1344      
    1345      
     1344 
     1345 
    13461346def prune(cluster, level=None, height=None, condition=None): 
    13471347    """ Prune the clustering instance ``cluster`` in place. 
     
    13651365    if not any(arg is not None for arg in [level, height, condition]): 
    13661366        raise ValueError("At least one pruning argument must be supplied") 
    1367      
     1367 
    13681368    level_check = height_check = condition_check = lambda cl: False 
    13691369    cluster_depth = cluster_depths(cluster) 
    1370      
     1370 
    13711371    if level is not None: 
    13721372        level_check = lambda cl: cluster_depth[cl] >= level 
    1373          
     1373 
    13741374    if height is not None: 
    13751375        height_check = lambda cl: cl.height <= height 
     
    13771377    if condition is not None: 
    13781378        condition_check = condition 
    1379          
     1379 
    13801380    pruned_set = set() 
    1381      
     1381 
    13821382    def check_all(cl): 
    13831383        return any([check(cl) for check in [level_check, height_check, 
    13841384                                            condition_check]]) 
    1385          
     1385 
    13861386    for cluster in preorder(cluster): 
    13871387        if cluster not in pruned_set: 
     
    13911391            else: 
    13921392                pass 
    1393      
    1394      
     1393 
     1394 
    13951395def cluster_depths(cluster): 
    13961396    """ Return a dictionary mapping :class:`HierarchicalCluster` instances to 
     
    14341434    iter_count = matrix.dim * (matrix.dim - 1) / 2 
    14351435    milestones = progress_bar_milestones(iter_count, 100) 
    1436      
     1436 
    14371437    for count, ((i, a1), (j, a2)) in enumerate(_pairs(enumerate(attributes))): 
    14381438        matrix[i, j] = (1.0 - orange.PearsonCorrelation(a1, a2, data, 0).r) / 2.0 
    14391439        if progress_callback and count in milestones: 
    14401440            progress_callback(100.0 * count / iter_count) 
    1441              
     1441 
    14421442    return matrix 
    14431443 
    14441444 
    1445 def _pairs(seq, same = False): 
     1445def _pairs(seq, same=False): 
    14461446    """ Return all pairs from elements of `seq`. 
    14471447    """ 
     
    14511451        for j in range(i + same, len(seq)): 
    14521452            yield seq[i], seq[j] 
    1453      
    1454      
     1453 
     1454 
    14551455def joining_cluster(cluster, item1, item2): 
    14561456    """ Return the cluster where `item1` and `item2` are first joined 
     
    14741474        else: 
    14751475            return cluster 
    1476          
     1476 
    14771477 
    14781478def cophenetic_distances(cluster): 
     
    14881488    """ 
    14891489 
    1490     mapping = cluster.mapping   
     1490    mapping = cluster.mapping 
    14911491    matrix = Orange.misc.SymMatrix(len(mapping)) 
    14921492    for cluster in postorder(cluster): 
     
    14961496                    for idx2 in mapping[branch2.first: branch2.last]: 
    14971497                        matrix[idx1, idx2] = cluster.height 
    1498                  
     1498 
    14991499        else: 
    15001500            for ind1, ind2 in _pairs(mapping[cluster.first: cluster.last]): 
    15011501                matrix[ind1, ind2] = cluster.height 
    1502      
     1502 
    15031503    return matrix 
    15041504 
    1505      
     1505 
    15061506def cophenetic_correlation(cluster, matrix): 
    15071507    """ Return the `cophenetic correlation coefficient 
     
    15251525    original = numpy.ravel(original) 
    15261526    return numpy.corrcoef(cophenetic, original)[0, 1] 
    1527      
    1528      
     1527 
     1528 
  • Orange/doc/reference/c45.py

    r9671 r10634  
    1919    print tree(i), i.getclass() 
    2020 
    21 print "\n\nC4.5 with minObjs=100" 
    22 tree = orange.C45Learner(data, minObjs=100) 
     21print "\n\nC4.5 with min_objs=100" 
     22tree = orange.C45Learner(data, min_objs=100) 
    2323for i in data[:5]: 
    2424    print tree(i), i.getclass() 
  • Orange/evaluation/reliability.py

    r10393 r10633  
    5555 
    5656def get_prediction_error_list(res): 
    57     return [result.actualClass - result.classes[0] for result in res.results] 
     57    return [result.actual_class - result.classes[0] for result in res.results] 
    5858 
    5959def get_description_list(res, i): 
     
    124124    sig = [0 for _ in xrange(number_of_estimates)] 
    125125    method_list = [0 for _ in xrange(number_of_estimates)] 
    126      
     126 
    127127    for res in results_by_fold: 
    128128        prediction_error = get_prediction_error_list(res) 
     
    139139            sig[i] = signed_or_absolute 
    140140            method_list[i] = method 
    141      
     141 
    142142    # Calculate p-values 
    143143    results = [float(res) / number_of_folds for res in results] 
    144144    ps = [p_value_from_r(r, number_of_instances) for r in results] 
    145      
     145 
    146146    return zip(results, ps, sig, method_list) 
    147147 
     
    151151    """ 
    152152    df = n - 2 
    153     t = r * (df /((-r + 1.0 + 1e-30) * (r + 1.0 + 1e-30)) )**0.5 
    154     return statc.betai (df * 0.5, 0.5, df/(df + t*t)) 
     153    t = r * (df / ((-r + 1.0 + 1e-30) * (r + 1.0 + 1e-30))) ** 0.5 
     154    return statc.betai (df * 0.5, 0.5, df / (df + t * t)) 
    155155 
    156156class Estimate: 
     
    188188 
    189189    """ 
    190     def __init__(self, estimate, signed_or_absolute, method, icv_method = -1): 
     190    def __init__(self, estimate, signed_or_absolute, method, icv_method= -1): 
    191191        self.estimate = estimate 
    192192        self.signed_or_absolute = signed_or_absolute 
     
    202202        self.procentage = procentage 
    203203        self.estimator = estimator 
    204      
     204 
    205205    def __call__(self, instances, weight=None, **kwds): 
    206          
     206 
    207207        # Calculate borders using cross validation 
    208208        res = Orange.evaluation.testing.cross_validation([self.estimator], instances) 
     
    210210        for i in xrange(len(res.results[0].probabilities[0].reliability_estimate)): 
    211211            estimates, signed_or_absolute, method = get_reliability_estimation_list(res, i) 
    212             sorted_estimates = sorted( abs(x) for x in estimates) 
    213             borders = [sorted_estimates[int(len(estimates)*p)-1]  for p in self.procentage] 
     212            sorted_estimates = sorted(abs(x) for x in estimates) 
     213            borders = [sorted_estimates[int(len(estimates) * p) - 1]  for p in self.procentage] 
    214214            all_borders.append(borders) 
    215          
     215 
    216216        # Learn on whole train data 
    217217        estimator_classifier = self.estimator(instances) 
    218          
     218 
    219219        return DescriptiveAnalysisClassifier(estimator_classifier, all_borders, self.desc) 
    220220 
     
    224224        self.all_borders = all_borders 
    225225        self.desc = desc 
    226      
     226 
    227227    def __call__(self, instance, result_type=Orange.core.GetValue): 
    228228        predicted, probabilities = self.estimator_classifier(instance, Orange.core.GetBoth) 
    229          
     229 
    230230        for borders, estimate in zip(self.all_borders, probabilities.reliability_estimate): 
    231231            estimate.text_description = self.desc[0] 
     
    233233                if estimate.estimate >= lower_border: 
    234234                    estimate.text_description = text_desc 
    235          
     235 
    236236        # Return the appropriate type of result 
    237237        if result_type == Orange.core.GetValue: 
     
    269269    def __init__(self, e=[0.01, 0.1, 0.5, 1.0, 2.0]): 
    270270        self.e = e 
    271      
     271 
    272272    def __call__(self, instances, learner): 
    273273        min_value = max_value = instances[0].getclass().value 
     
    278278                min_value = ex.getclass().value 
    279279        return SensitivityAnalysisClassifier(self.e, instances, min_value, max_value, learner) 
    280      
     280 
    281281class SensitivityAnalysisClassifier: 
    282282    def __init__(self, e, instances, min_value, max_value, learner): 
     
    286286        self.min_value = min_value 
    287287        self.learner = learner 
    288      
     288 
    289289    def __call__(self, instance, predicted, probabilities): 
    290290        # Create new dataset 
    291291        r_data = Orange.data.Table(self.instances) 
    292          
     292 
    293293        # Create new instance 
    294294        modified_instance = Orange.data.Instance(instance) 
    295          
     295 
    296296        # Append it to the data 
    297297        r_data.append(modified_instance) 
    298          
     298 
    299299        # Calculate SAvar & SAbias 
    300300        SAvar = SAbias = 0 
    301          
     301 
    302302        for eps in self.e: 
    303303            # +epsilon 
    304             r_data[-1].setclass(predicted.value + eps*(self.max_value - self.min_value)) 
     304            r_data[-1].setclass(predicted.value + eps * (self.max_value - self.min_value)) 
    305305            c = self.learner(r_data) 
    306306            k_plus = c(instance, Orange.core.GetValue) 
    307              
     307 
    308308            # -epsilon 
    309             r_data[-1].setclass(predicted.value - eps*(self.max_value - self.min_value)) 
     309            r_data[-1].setclass(predicted.value - eps * (self.max_value - self.min_value)) 
    310310            c = self.learner(r_data) 
    311311            k_minus = c(instance, Orange.core.GetValue) 
     
    316316            # calculate part SAvar and SAbias 
    317317            SAvar += k_plus.value - k_minus.value 
    318             SAbias += k_plus.value + k_minus.value - 2*predicted.value 
    319          
     318            SAbias += k_plus.value + k_minus.value - 2 * predicted.value 
     319 
    320320        SAvar /= len(self.e) 
    321         SAbias /= 2*len(self.e) 
    322          
     321        SAbias /= 2 * len(self.e) 
     322 
    323323        return [Estimate(SAvar, ABSOLUTE, SAVAR_ABSOLUTE), 
    324324                Estimate(SAbias, SIGNED, SABIAS_SIGNED), 
    325325                Estimate(abs(SAbias), ABSOLUTE, SABIAS_ABSOLUTE)] 
    326      
     326 
    327327class BaggingVariance: 
    328328    """ 
     
    345345    def __init__(self, m=50): 
    346346        self.m = m 
    347      
     347 
    348348    def __call__(self, instances, learner): 
    349349        classifiers = [] 
    350          
     350 
    351351        # Create bagged classifiers using sampling with replacement 
    352352        for _ in xrange(self.m): 
     
    359359    def __init__(self, classifiers): 
    360360        self.classifiers = classifiers 
    361      
     361 
    362362    def __call__(self, instance, *args): 
    363363        BAGV = 0 
    364          
     364 
    365365        # Calculate the bagging variance 
    366366        bagged_values = [c(instance, Orange.core.GetValue).value for c in self.classifiers if c is not None] 
    367          
     367 
    368368        k = sum(bagged_values) / len(bagged_values) 
    369          
    370         BAGV = sum( (bagged_value - k)**2 for bagged_value in bagged_values) / len(bagged_values) 
    371          
     369 
     370        BAGV = sum((bagged_value - k) ** 2 for bagged_value in bagged_values) / len(bagged_values) 
     371 
    372372        return [Estimate(BAGV, ABSOLUTE, BAGV_ABSOLUTE)] 
    373          
     373 
    374374class LocalCrossValidation: 
    375375    """ 
     
    397397    def __init__(self, k=0): 
    398398        self.k = k 
    399      
     399 
    400400    def __call__(self, instances, learner): 
    401401        nearest_neighbours_constructor = Orange.classification.knn.FindNearestConstructor() 
    402402        nearest_neighbours_constructor.distanceConstructor = Orange.distance.Euclidean() 
    403          
     403 
    404404        distance_id = Orange.feature.Descriptor.new_meta_id() 
    405405        nearest_neighbours = nearest_neighbours_constructor(instances, 0, distance_id) 
    406          
     406 
    407407        if self.k == 0: 
    408             self.k = max(5, len(instances)/20) 
    409          
     408            self.k = max(5, len(instances) / 20) 
     409 
    410410        return LocalCrossValidationClassifier(distance_id, nearest_neighbours, self.k, learner) 
    411411 
     
    416416        self.k = k 
    417417        self.learner = learner 
    418      
     418 
    419419    def __call__(self, instance, *args): 
    420420        LCVer = 0 
    421421        LCVdi = 0 
    422          
     422 
    423423        # Find k nearest neighbors 
    424          
     424 
    425425        knn = [ex for ex in self.nearest_neighbours(instance, self.k)] 
    426          
     426 
    427427        # leave one out of prediction error 
    428428        for i in xrange(len(knn)): 
    429429            train = knn[:] 
    430430            del train[i] 
    431              
     431 
    432432            classifier = self.learner(Orange.data.Table(train)) 
    433              
     433 
    434434            returned_value = classifier(knn[i], Orange.core.GetValue) 
    435              
     435 
    436436            e = abs(knn[i].getclass().value - returned_value.value) 
    437              
     437 
    438438            LCVer += e * math.exp(-knn[i][self.distance_id]) 
    439439            LCVdi += math.exp(-knn[i][self.distance_id]) 
    440          
     440 
    441441        LCV = LCVer / LCVdi if LCVdi != 0 else 0 
    442442        if math.isnan(LCV): 
     
    464464    def __init__(self, k=5): 
    465465        self.k = k 
    466      
     466 
    467467    def __call__(self, instances, learner): 
    468468        nearest_neighbours_constructor = Orange.classification.knn.FindNearestConstructor() 
    469469        nearest_neighbours_constructor.distanceConstructor = Orange.distance.Euclidean() 
    470          
     470 
    471471        distance_id = Orange.feature.Descriptor.new_meta_id() 
    472472        nearest_neighbours = nearest_neighbours_constructor(instances, 0, distance_id) 
     
    477477        self.nearest_neighbours = nearest_neighbours 
    478478        self.k = k 
    479      
     479 
    480480    def __call__(self, instance, predicted, probabilities): 
    481481        CNK = 0 
    482          
     482 
    483483        # Find k nearest neighbors 
    484          
     484 
    485485        knn = [ex for ex in self.nearest_neighbours(instance, self.k)] 
    486          
     486 
    487487        # average label of neighbors 
    488488        for ex in knn: 
    489489            CNK += ex.getclass().value 
    490          
     490 
    491491        CNK /= self.k 
    492492        CNK -= predicted.value 
    493          
     493 
    494494        return [Estimate(CNK, SIGNED, CNK_SIGNED), 
    495495                Estimate(abs(CNK), ABSOLUTE, CNK_ABSOLUTE)] 
    496      
     496 
    497497class Mahalanobis: 
    498498    """ 
     
    511511    def __init__(self, k=3): 
    512512        self.k = k 
    513      
     513 
    514514    def __call__(self, instances, *args): 
    515515        nnm = Orange.classification.knn.FindNearestConstructor() 
    516516        nnm.distanceConstructor = Orange.distance.Mahalanobis() 
    517          
     517 
    518518        mid = Orange.feature.Descriptor.new_meta_id() 
    519519        nnm = nnm(instances, 0, mid) 
     
    525525        self.nnm = nnm 
    526526        self.mid = mid 
    527      
     527 
    528528    def __call__(self, instance, *args): 
    529529        mahalanobis_distance = 0 
    530          
     530 
    531531        mahalanobis_distance = sum(ex[self.mid].value for ex in self.nnm(instance, self.k)) 
    532          
     532 
    533533        return [ Estimate(mahalanobis_distance, ABSOLUTE, MAHAL_ABSOLUTE) ] 
    534534 
     
    545545    def __init__(self): 
    546546        pass 
    547      
     547 
    548548    def __call__(self, instances, *args): 
    549549        dc = Orange.core.DomainContinuizer() 
     
    551551        dc.continuousTreatment = Orange.core.DomainContinuizer.NormalizeBySpan 
    552552        dc.multinomialTreatment = Orange.core.DomainContinuizer.NValues 
    553          
     553 
    554554        new_domain = dc(instances) 
    555555        new_instances = instances.translate(new_domain) 
    556          
     556 
    557557        X, _, _ = new_instances.to_numpy() 
    558558        instance_avg = numpy.average(X, 0) 
    559          
     559 
    560560        distance_constructor = Orange.distance.Mahalanobis() 
    561561        distance = distance_constructor(new_instances) 
    562          
     562 
    563563        average_instance = Orange.data.Instance(new_instances.domain, list(instance_avg) + ["?"]) 
    564          
     564 
    565565        return MahalanobisToCenterClassifier(distance, average_instance, new_domain) 
    566566 
     
    570570        self.average_instance = average_instance 
    571571        self.new_domain = new_domain 
    572      
     572 
    573573    def __call__(self, instance, *args): 
    574          
     574 
    575575        inst = Orange.data.Instance(self.new_domain, instance) 
    576          
     576 
    577577        mahalanobis_to_center = self.distance(inst, self.average_instance) 
    578          
     578 
    579579        return [ Estimate(mahalanobis_to_center, ABSOLUTE, MAHAL_TO_CENTER_ABSOLUTE) ] 
    580580 
     
    598598        self.bagv = bagv 
    599599        self.cnk = cnk 
    600      
     600 
    601601    def __call__(self, instances, learner): 
    602602        bagv_classifier = self.bagv(instances, learner) 
     
    608608        self.bagv_classifier = bagv_classifier 
    609609        self.cnk_classifier = cnk_classifier 
    610      
     610 
    611611    def __call__(self, instance, predicted, probabilities): 
    612612        bagv_estimates = self.bagv_classifier(instance, predicted, probabilities) 
    613613        cnk_estimates = self.cnk_classifier(instance, predicted, probabilities) 
    614          
    615         bvck_value = (bagv_estimates[0].estimate + cnk_estimates[1].estimate)/2 
     614 
     615        bvck_value = (bagv_estimates[0].estimate + cnk_estimates[1].estimate) / 2 
    616616        bvck_estimates = [ Estimate(bvck_value, ABSOLUTE, BVCK_ABSOLUTE) ] 
    617617        bvck_estimates.extend(bagv_estimates) 
     
    622622    def __init__(self): 
    623623        pass 
    624      
     624 
    625625    def __call__(self, instances, learner): 
    626626        res = Orange.evaluation.testing.cross_validation([learner], instances) 
    627627        prediction_errors = get_prediction_error_list(res) 
    628          
     628 
    629629        new_domain = Orange.data.Domain(instances.domain.attributes, Orange.core.FloatVariable("pe")) 
    630630        new_dataset = Orange.data.Table(new_domain, instances) 
    631          
     631 
    632632        for instance, prediction_error in izip(new_dataset, prediction_errors): 
    633633            instance.set_class(prediction_error) 
    634          
     634 
    635635        rf = Orange.ensemble.forest.RandomForestLearner() 
    636636        rf_classifier = rf(new_dataset) 
    637          
     637 
    638638        return ErrorPredictingClassification(rf_classifier, new_domain) 
    639          
     639 
    640640class ErrorPredictingClassification: 
    641641    def __init__(self, rf_classifier, new_domain): 
    642642        self.rf_classifier = rf_classifier 
    643643        self.new_domain = new_domain 
    644      
     644 
    645645    def __call__(self, instance, predicted, probabilities): 
    646646        new_instance = Orange.data.Instance(self.new_domain, instance) 
    647647        value = self.rf_classifier(new_instance, Orange.core.GetValue) 
    648          
     648 
    649649        return [Estimate(value.value, SIGNED, SABIAS_SIGNED)] 
    650650 
     
    682682        self.box_learner = box_learner 
    683683        self.blending = False 
    684          
    685      
     684 
     685 
    686686    def __call__(self, instances, weight=None, **kwds): 
    687687        """Learn from the given table of data instances. 
     
    693693        :rtype: :class:`Orange.evaluation.reliability.Classifier` 
    694694        """ 
    695          
     695 
    696696        blending_classifier = None 
    697697        new_domain = None 
    698          
     698 
    699699        if instances.domain.class_var.var_type != Orange.feature.Continuous.Continuous: 
    700700            raise Exception("This method only works on data with continuous class.") 
    701          
     701 
    702702        return Classifier(instances, self.box_learner, self.estimators, self.blending, new_domain, blending_classifier) 
    703      
     703 
    704704    def internal_cross_validation(self, instances, folds=10): 
    705705        """ Perform the internal cross validation for getting the best 
     
    720720        sorted_results = sorted(results) 
    721721        return sorted_results[-1][3] 
    722      
     722 
    723723    def internal_cross_validation_testing(self, instances, folds=10): 
    724724        """ Perform internal cross validation (as in Automatic selection of 
     
    735735        """ 
    736736        cv_indices = Orange.core.MakeRandomIndicesCV(instances, folds) 
    737          
     737 
    738738        list_of_rs = [] 
    739          
     739 
    740740        sum_of_rs = defaultdict(float) 
    741          
     741 
    742742        for fold in xrange(folds): 
    743743            data = instances.select(cv_indices, fold) 
     
    751751        sorted_sum_of_rs = sorted(sum_of_rs.items(), key=lambda estimate: estimate[1], reverse=True) 
    752752        return sorted_sum_of_rs[0][0] 
    753      
     753 
    754754    labels = ["SAvar", "SAbias", "BAGV", "CNK", "LCV", "BVCK", "Mahalanobis", "ICV"] 
    755755 
     
    774774        self.blending_domain = blending_domain 
    775775        self.rf_classifier = rf_classifier 
    776          
     776 
    777777        # Train the learner with original data 
    778778        self.classifier = box_learner(instances) 
    779          
     779 
    780780        # Train all the estimators and create their classifiers 
    781781        self.estimation_classifiers = [estimator(instances, box_learner) for estimator in estimators] 
    782      
     782 
    783783    def __call__(self, instance, result_type=Orange.core.GetValue): 
    784784        """ 
     
    802802        """ 
    803803        predicted, probabilities = self.classifier(instance, Orange.core.GetBoth) 
    804          
     804 
    805805        # Create a place holder for estimates 
    806806        if probabilities is None: 
     
    809809        #    warnings.simplefilter("ignore") 
    810810        probabilities.setattr('reliability_estimate', []) 
    811          
     811 
    812812        # Calculate all the estimates and add them to the results 
    813813        for estimate in self.estimation_classifiers: 
    814814            probabilities.reliability_estimate.extend(estimate(instance, predicted, probabilities)) 
    815          
     815 
    816816        # Return the appropriate type of result 
    817817        if result_type == Orange.core.GetValue: 
  • Orange/evaluation/scoring.py

    r10580 r10633  
    5050    if res.number_of_iterations < 2: 
    5151        return [res] 
    52          
     52 
    5353    ress = [Orange.evaluation.testing.ExperimentResults( 
    5454                1, res.classifier_names, res.class_values, 
     
    6868        r = Orange.evaluation.testing.ExperimentResults(res.numberOfIterations, 
    6969                    [res.classifierNames[i]], res.classValues, 
    70                     weights=res.weights, baseClass=res.baseClass, 
     70                    weights=res.weights, base_class=res.base_class, 
    7171                    classifiers=[res.classifiers[i]] if res.classifiers else [], 
    7272                    test_type=res.test_type, labels=res.labels) 
     
    118118    if not stats[0]: 
    119119        raise ValueError, "Cannot compute the score: no examples or sum of weights is 0." 
    120      
     120 
    121121    if report_se: 
    122122        return [(statc.mean(x), statc.sterr(x)) for x in stats] 
    123123    else: 
    124124        return [statc.mean(x) for x in stats] 
    125      
     125 
    126126def ME(res, **argkw): 
    127127    MEs = [0.] * res.number_of_learners 
     
    129129    if argkw.get("unweighted", 0) or not res.weights: 
    130130        for tex in res.results: 
    131             MEs = map(lambda res, cls, ac = float(tex.actual_class): 
     131            MEs = map(lambda res, cls, ac=float(tex.actual_class): 
    132132                      res + abs(float(cls) - ac), MEs, tex.classes) 
    133133        totweight = gettotsize(res) 
     
    216216                    norm[tex.iteration_number] += abs(ai - a[tex.iteration_number]) 
    217217                elif argkw.get("norm-sqr", 0): 
    218                     norm[tex.iteration_number] += (ai - a[tex.iteration_number])**2 
     218                    norm[tex.iteration_number] += (ai - a[tex.iteration_number]) ** 2 
    219219 
    220220                # iterate accross results of different regressors 
     
    223223                        scores[i][tex.iteration_number] += abs(float(cls) - ai) 
    224224                    else: 
    225                         scores[i][tex.iteration_number] += (float(cls) - ai)**2 
     225                        scores[i][tex.iteration_number] += (float(cls) - ai) ** 2 
    226226        else: # unweighted != 0 
    227227            raise NotImplementedError, "weighted error scores with SE not implemented yet" 
     
    239239 
    240240        return [(statc.mean(x), statc.std(x)) for x in scores] 
    241          
     241 
    242242    else: # single iteration (testing on a single test set) 
    243243        scores = [0.] * res.number_of_learners 
     
    253253                else: 
    254254                    scores = map(lambda res, cls, ac=float(tex.actual_class): 
    255                                  res + (float(cls) - ac)**2, scores, tex.classes) 
     255                                 res + (float(cls) - ac) ** 2, scores, tex.classes) 
    256256 
    257257                if argkw.get("norm-abs", 0): 
    258258                    norm += abs(tex.actual_class - a) 
    259259                elif argkw.get("norm-sqr", 0): 
    260                     norm += (tex.actual_class - a)**2 
     260                    norm += (tex.actual_class - a) ** 2 
    261261            totweight = gettotsize(res) 
    262262        else: 
     
    266266                MSEs = map(lambda res, cls, ac=float(tex.actual_class), 
    267267                           tw=tex.weight: 
    268                            res + tw * (float(cls) - ac)**2, MSEs, tex.classes) 
     268                           res + tw * (float(cls) - ac) ** 2, MSEs, tex.classes) 
    269269            totweight = gettotweight(res) 
    270270 
     
    285285    """Compute mean-squared error.""" 
    286286    return regression_error(res, **argkw) 
    287      
     287 
    288288def RMSE(res, **argkw): 
    289289    """Compute root mean-squared error.""" 
     
    330330                nIter[tex.iteration_number] += 1 
    331331                for i, cls in enumerate(tex.classes): 
    332                     MSEs[i][tex.iteration_number] += (float(cls) - ac)**2 
     332                    MSEs[i][tex.iteration_number] += (float(cls) - ac) ** 2 
    333333        else: 
    334334            raise ValueError, "weighted RMSE with SE not implemented yet" 
     
    337337            MSEs = [[math.sqrt(x) for x in y] for y in MSEs] 
    338338        return [(statc.mean(x), statc.std(x)) for x in MSEs] 
    339          
     339 
    340340    else: 
    341341        MSEs = [0.] * res.number_of_learners 
     
    343343            for tex in res.results: 
    344344                MSEs = map(lambda res, cls, ac=float(tex.actual_class): 
    345                            res + (float(cls) - ac)**2, MSEs, tex.classes) 
     345                           res + (float(cls) - ac) ** 2, MSEs, tex.classes) 
    346346            totweight = gettotsize(res) 
    347347        else: 
    348348            for tex in res.results: 
    349349                MSEs = map(lambda res, cls, ac=float(tex.actual_class), 
    350                            tw=tex.weight: res + tw * (float(cls) - ac)**2, 
     350                           tw=tex.weight: res + tw * (float(cls) - ac) ** 2, 
    351351                           MSEs, tex.classes) 
    352352            totweight = gettotweight(res) 
     
    386386    @deprecated_keywords({"reportSE": "report_se", 
    387387                          "unweighted": "ignore_weights"}) 
    388     def __init__(self, test_results, report_se = False, ignore_weights=False): 
     388    def __init__(self, test_results, report_se=False, ignore_weights=False): 
    389389        super(CA, self).__init__() 
    390390        self.report_se = report_se 
     
    449449            w = 1. if self.ignore_weights else tex.weight 
    450450            for lrn in range(test_results.number_of_learners): 
    451                 CAsByFold[lrn][tex.iteration_number] += (tex.classes[lrn] ==  
     451                CAsByFold[lrn][tex.iteration_number] += (tex.classes[lrn] == 
    452452                    tex.actual_class) and w 
    453453            foldN[tex.iteration_number] += w 
     
    472472    """Compute the average probability assigned to the correct class.""" 
    473473    if res.number_of_iterations == 1: 
    474         APs=[0.] * res.number_of_learners 
     474        APs = [0.] * res.number_of_learners 
    475475        if ignore_weights or not res.weights: 
    476476            for tex in res.results: 
     
    525525 
    526526    if res.number_of_iterations == 1: 
    527         MSEs=[0.] * res.number_of_learners 
     527        MSEs = [0.] * res.number_of_learners 
    528528        if ignore_weights or not res.weights: 
    529529            totweight = 0. 
    530530            for tex in res.results: 
    531531                MSEs = map(lambda res, probs: res + reduce( 
    532                     lambda s, pi: s + pi**2, probs, 0) -  
     532                    lambda s, pi: s + pi ** 2, probs, 0) - 
    533533                    2 * probs[tex.actual_class], MSEs, tex.probabilities) 
    534534                totweight += tex.weight 
     
    536536            for tex in res.results: 
    537537                MSEs = map(lambda res, probs: res + tex.weight * reduce( 
    538                     lambda s, pi: s + pi**2, probs, 0) -  
     538                    lambda s, pi: s + pi ** 2, probs, 0) - 
    539539                    2 * probs[tex.actual_class], MSEs, tex.probabilities) 
    540540            totweight = gettotweight(res) 
     
    553553        for tex in res.results: 
    554554            BSs[tex.iteration_number] = map(lambda rr, probs: rr + reduce( 
    555                 lambda s, pi: s + pi**2, probs, 0) - 
     555                lambda s, pi: s + pi ** 2, probs, 0) - 
    556556                2 * probs[tex.actual_class], BSs[tex.iteration_number], 
    557557                tex.probabilities) 
     
    560560        for tex in res.results: 
    561561            BSs[tex.iteration_number] = map(lambda res, probs: 
    562                 res + tex.weight * reduce(lambda s, pi: s + pi**2, probs, 0) - 
     562                res + tex.weight * reduce(lambda s, pi: s + pi ** 2, probs, 0) - 
    563563                2 * probs[tex. actual_class], BSs[tex.iteration_number], 
    564564                tex.probabilities) 
     
    572572 
    573573def BSS(res, **argkw): 
    574     return [1 - x / 2 for x in apply(Brier_score, (res, ), argkw)] 
     574    return [1 - x / 2 for x in apply(Brier_score, (res,), argkw)] 
    575575 
    576576def IS_ex(Pc, P): 
     
    614614            return [IS / totweight for IS in ISs] 
    615615 
    616          
     616 
    617617    ISs = [[0.] * res.number_of_iterations 
    618618           for _ in range(res.number_of_learners)] 
     
    636636 
    637637    return statistics_by_folds(ISs, foldN, report_se, False) 
    638      
     638 
    639639 
    640640def Wilcoxon(res, statistics, **argkw): 
     
    664664                      "classIndex": "class_index", 
    665665                      "unweighted": "ignore_weights"}) 
    666 def confusion_matrices(test_results, class_index=-1, 
     666def confusion_matrices(test_results, class_index= -1, 
    667667                       ignore_weights=False, cutoff=.5): 
    668668    """ 
     
    678678    """ 
    679679    tfpns = [ConfusionMatrix() for _ in range(test_results.number_of_learners)] 
    680      
     680 
    681681    if class_index < 0: 
    682682        numberOfClasses = len(test_results.class_values) 
     
    699699                            cm[li][trueClass][predClass] += tex.weight 
    700700            return cm 
    701              
    702         elif test_results.baseClass >= 0: 
    703             class_index = test_results.baseClass 
     701 
     702        elif test_results.base_class >= 0: 
     703            class_index = test_results.base_class 
    704704        else: 
    705705            class_index = 1 
     
    708708        if ignore_weights or not test_results.weights: 
    709709            for lr in test_results.results: 
    710                 isPositive=(lr.actual_class==class_index) 
     710                isPositive = (lr.actual_class == class_index) 
    711711                for i in range(test_results.number_of_learners): 
    712712                    tfpns[i].addTFPosNeg(lr.probabilities[i][class_index] > 
     
    714714        else: 
    715715            for lr in test_results.results: 
    716                 isPositive=(lr.actual_class == class_index) 
     716                isPositive = (lr.actual_class == class_index) 
    717717                for i in range(test_results.number_of_learners): 
    718                     tfpns[i].addTFPosNeg(lr.probabilities[i][class_index] >  
     718                    tfpns[i].addTFPosNeg(lr.probabilities[i][class_index] > 
    719719                                         cutoff, isPositive, lr.weight) 
    720720    else: 
     
    766766            if not e: 
    767767                return -1, -1, -1 
    768             ss += (o - e)**2 / e 
    769     df = (dim - 1)**2 
     768            ss += (o - e) ** 2 / e 
     769    df = (dim - 1) ** 2 
    770770    return ss, df, statc.chisqprob(ss, df) 
    771771 
     
    807807    @classmethod 
    808808    def compute(self, confusion_matrix): 
    809         tot = confusion_matrix.TP+confusion_matrix.FN 
     809        tot = confusion_matrix.TP + confusion_matrix.FN 
    810810        if tot < 1e-6: 
    811811            import warnings 
     
    831831    @classmethod 
    832832    def compute(self, confusion_matrix): 
    833         tot = confusion_matrix.FP+confusion_matrix.TN 
     833        tot = confusion_matrix.FP + confusion_matrix.TN 
    834834        if tot < 1e-6: 
    835835            import warnings 
     
    851851            warnings.warn("Can't compute PPV: one or both classes have no instances") 
    852852            return None 
    853         return confusion_matrix.TP/tot 
     853        return confusion_matrix.TP / tot 
    854854 
    855855 
     
    885885        p = Precision.compute(confusion_matrix) 
    886886        r = Recall.compute(confusion_matrix) 
    887         if p is not None and r is not None and (p+r) != 0: 
     887        if p is not None and r is not None and (p + r) != 0: 
    888888            return 2. * p * r / (p + r) 
    889889        else: 
     
    918918        # code by Boris Gorelik 
    919919        TP, TN, FP, FN = cm.TP, cm.TN, cm.FP, cm.FN 
    920            
     920 
    921921        try: 
    922             return (TP*TN - FP*FN) /\ 
    923                  math.sqrt((TP+FP) * (TP+FN) * (TN+ FP) * (TN+FN)) 
     922            return (TP * TN - FP * FN) / \ 
     923                 math.sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN)) 
    924924        except ZeroDivisionError: 
    925925            # Zero division occurs when there is either no true positives 
     
    991991@deprecated_keywords({"classIndex": "class_index", 
    992992                      "unweighted": "ignore_weights"}) 
    993 def AUCWilcoxon(res, class_index=-1, ignore_weights=False, **argkw): 
     993def AUCWilcoxon(res, class_index= -1, ignore_weights=False, **argkw): 
    994994    """Compute the area under ROC (AUC) and its standard error using 
    995995    Wilcoxon's approach proposed by Hanley and McNeal (1982). If  
     
    10151015            highPos -= thisPos 
    10161016            W += thisNeg * (highPos + thisPos / 2.) 
    1017             Q2 += thisPos * (lowNeg**2  + lowNeg*thisNeg  + thisNeg**2 / 3.) 
    1018             Q1 += thisNeg * (highPos**2 + highPos*thisPos + thisPos**2 / 3.) 
     1017            Q2 += thisPos * (lowNeg ** 2 + lowNeg * thisNeg + thisNeg ** 2 / 3.) 
     1018            Q1 += thisNeg * (highPos ** 2 + highPos * thisPos + thisPos ** 2 / 3.) 
    10191019 
    10201020            lowNeg += thisNeg 
    10211021 
    1022         W  /= (totPos*totNeg) 
    1023         Q1 /= (totNeg*totPos**2) 
    1024         Q2 /= (totPos*totNeg**2) 
    1025  
    1026         SE = math.sqrt((W * (1 - W) + (totPos - 1) * (Q1 - W**2) + 
    1027                        (totNeg - 1) * (Q2 - W**2)) / (totPos * totNeg)) 
     1022        W /= (totPos * totNeg) 
     1023        Q1 /= (totNeg * totPos ** 2) 
     1024        Q2 /= (totPos * totNeg ** 2) 
     1025 
     1026        SE = math.sqrt((W * (1 - W) + (totPos - 1) * (Q1 - W ** 2) + 
     1027                       (totNeg - 1) * (Q2 - W ** 2)) / (totPos * totNeg)) 
    10281028        results.append((W, SE)) 
    10291029    return results 
     
    10341034@deprecated_keywords({"classIndex": "class_index", 
    10351035                      "unweighted": "ignore_weights"}) 
    1036 def compare_2_AUCs(res, lrn1, lrn2, class_index=-1, 
     1036def compare_2_AUCs(res, lrn1, lrn2, class_index= -1, 
    10371037                   ignore_weights=False, **argkw): 
    10381038    return corn.compare2ROCs(res, lrn1, lrn2, class_index, 
     
    10401040 
    10411041# for backward compatibility, compare_2_AROCs is obsolete 
    1042 compare_2_AROCs = compare_2_AUCs  
     1042compare_2_AROCs = compare_2_AUCs 
    10431043 
    10441044 
    10451045@deprecated_keywords({"classIndex": "class_index"}) 
    1046 def compute_ROC(res, class_index=-1): 
     1046def compute_ROC(res, class_index= -1): 
    10471047    """Compute a ROC curve as a list of (x, y) tuples, where x is  
    10481048    1-specificity and y is sensitivity. 
     
    10541054 
    10551055    for plist in problists: 
    1056         curve=[(1., 1.)] 
     1056        curve = [(1., 1.)] 
    10571057        TP, TN = totPos, 0. 
    10581058        FN, FP = 0., totNeg 
     
    10711071        results.append(curve) 
    10721072 
    1073     return results     
     1073    return results 
    10741074 
    10751075## TC's implementation of algorithms, taken from: 
     
    11031103@deprecated_keywords({"classIndex": "class_index", 
    11041104                      "keepConcavities": "keep_concavities"}) 
    1105 def TC_compute_ROC(res, class_index=-1, keep_concavities=1): 
     1105def TC_compute_ROC(res, class_index= -1, keep_concavities=1): 
    11061106    problists, tots = corn.computeROCCumulative(res, class_index) 
    11071107 
     
    11141114        TP = 0. 
    11151115        FP = 0. 
    1116         curve=[] 
     1116        curve = [] 
    11171117        fPrev = 10e300 # "infinity" score at 0., 0. 
    11181118        for prob in plist: 
     
    11701170        else: 
    11711171            if abs(d - mind) <= 0.0001: ## close enough 
    1172                 closestPoints.append( (x, y, fscore) ) 
    1173     return closestPoints           
     1172                closestPoints.append((x, y, fscore)) 
     1173    return closestPoints 
    11741174 
    11751175def frange(start, end=None, inc=None): 
     
    11931193            break 
    11941194        L.append(next) 
    1195          
     1195 
    11961196    return L 
    11971197 
     
    12031203## returns the average ROC curve and an array of (vertical) standard deviations 
    12041204@deprecated_keywords({"ROCcurves": "roc_curves"}) 
    1205 def TC_vertical_average_ROC(roc_curves, samples = 10): 
     1205def TC_vertical_average_ROC(roc_curves, samples=10): 
    12061206    def INTERPOLATE((P1x, P1y, P1fscore), (P2x, P2y, P2fscore), X): 
    12071207        if (P1x == P2x) or P1x < X > P2x or P1x > X < P2x: 
     
    13101310            else: 
    13111311                stdv = 0. 
    1312             TPstdV.append( stdv ) 
     1312            TPstdV.append(stdv) 
    13131313            ## horizontal standard deviation 
    13141314            if len(FPsum) > 1: 
     
    13161316            else: 
    13171317                stdh = 0. 
    1318             TPstdH.append( stdh ) 
     1318            TPstdH.append(stdh) 
    13191319 
    13201320        average.append(TPavg) 
     
    13311331##  - noClassRugPoints is an array of (x, 0) points 
    13321332@deprecated_keywords({"classIndex": "class_index"}) 
    1333 def compute_calibration_curve(res, class_index=-1): 
     1333def compute_calibration_curve(res, class_index= -1): 
    13341334    ## merge multiple iterations into one 
    13351335    mres = Orange.evaluation.testing.ExperimentResults(1, res.classifier_names, 
     
    13461346 
    13471347    for plist in problists: 
    1348         yesClassRugPoints = []  
     1348        yesClassRugPoints = [] 
    13491349        noClassRugPoints = [] 
    13501350 
     
    13551355            noClassRugPoints.append((f, thisNeg)) # 1. 
    13561356 
    1357             index = int(f * bins ) 
     1357            index = int(f * bins) 
    13581358            index = min(index, bins - 1) ## just in case for value 1. 
    13591359            yesBinsVals[index] += thisPos 
     
    13681368            if allVal == 0.: continue 
    13691369            y = float(yesVal) / float(allVal) 
    1370             curve.append((f,  y)) 
     1370            curve.append((f, y)) 
    13711371 
    13721372        ## smooth the curve 
     
    13971397##    on the Lift Curve 
    13981398@deprecated_keywords({"classIndex": "class_index"}) 
    1399 def compute_lift_curve(res, class_index=-1): 
     1399def compute_lift_curve(res, class_index= -1): 
    14001400    ## merge multiple iterations into one 
    14011401    mres = Orange.evaluation.testing.ExperimentResults(1, res.classifier_names, 
     
    14281428  def __init__(self, C=0., D=0., T=0.): 
    14291429    self.C, self.D, self.T = C, D, T 
    1430     
     1430 
    14311431def is_CDT_empty(cdt): 
    14321432    return cdt.C + cdt.D + cdt.T < 1e-20 
     
    14351435@deprecated_keywords({"classIndex": "class_index", 
    14361436                      "unweighted": "ignore_weights"}) 
    1437 def compute_CDT(res, class_index=-1, ignore_weights=False, **argkw): 
     1437def compute_CDT(res, class_index= -1, ignore_weights=False, **argkw): 
    14381438    """Obsolete, don't use.""" 
    14391439    if class_index < 0: 
    1440         if res.baseClass >= 0: 
    1441             class_index = res.baseClass 
     1440        if res.base_class >= 0: 
     1441            class_index = res.base_class 
    14421442        else: 
    14431443            class_index = 1 
    1444              
     1444 
    14451445    useweights = res.weights and not ignore_weights 
    14461446    weightByClasses = argkw.get("weightByClasses", True) 
    14471447 
    1448     if res.number_of_iterations>1: 
     1448    if res.number_of_iterations > 1: 
    14491449        CDTs = [CDT() for _ in range(res.number_of_learners)] 
    14501450        iterationExperiments = split_by_iterations(res) 
     
    14581458            if is_CDT_empty(CDTs[0]): 
    14591459                return corn.computeCDT(res, class_index, useweights) 
    1460          
     1460 
    14611461        return CDTs 
    14621462    else: 
     
    15261526        super(AUC, self).__init__() 
    15271527 
    1528         self.ignore_weights=ignore_weights 
    1529         self.method=multiclass 
     1528        self.ignore_weights = ignore_weights 
     1529        self.method = multiclass 
    15301530 
    15311531        if test_results is not None: 
     
    16001600 
    16011601        if usefulClassPairs > 0: 
    1602             sum_aucs = [x/usefulClassPairs for x in sum_aucs] 
     1602            sum_aucs = [x / usefulClassPairs for x in sum_aucs] 
    16031603 
    16041604        return sum_aucs 
     
    16141614        subsum_aucs = [0.] * iterations[0].number_of_learners 
    16151615        for ite in iterations: 
    1616             aucs, foldsUsed = auc_computer(*(ite, ) + computer_args) 
     1616            aucs, foldsUsed = auc_computer(*(ite,) + computer_args) 
    16171617            if not aucs: 
    16181618                import warnings 
     
    16861686        Compute AUC using a :obj:`cdt_computer`. 
    16871687        """ 
    1688         cdts = cdt_computer(*(ite, ) + computer_args) 
     1688        cdts = cdt_computer(*(ite,) + computer_args) 
    16891689        if not is_CDT_empty(cdts[0]): 
    16901690            return [(cdt.C + cdt.T / 2) / (cdt.C + cdt.D + cdt.T) / 
     
    16921692 
    16931693        if all_ite: 
    1694             cdts = cdt_computer(*(all_ite, ) + computer_args) 
     1694            cdts = cdt_computer(*(all_ite,) + computer_args) 
    16951695            if not is_CDT_empty(cdts[0]): 
    16961696                return [(cdt.C + cdt.T / 2) / (cdt.C + cdt.D + cdt.T) 
     
    17041704    out and all other classes are treated as a single class. 
    17051705    """ 
    1706     def __init__(self, test_results=None, class_index=-1, ignore_weights=False): 
     1706    def __init__(self, test_results=None, class_index= -1, ignore_weights=False): 
    17071707        if class_index < 0: 
    17081708            if test_results and test_results.base_class >= 0: 
     
    18581858            su = mcm[l1][l2] + mcm[l2][l1] 
    18591859            if su: 
    1860                 mcm[l2][l1] = (abs(mcm[l1][l2] - mcm[l2][l1]) - 1)**2 / su 
     1860                mcm[l2][l1] = (abs(mcm[l1][l2] - mcm[l2][l1]) - 1) ** 2 / su 
    18611861            else: 
    18621862                mcm[l2][l1] = 0 
    18631863 
    18641864    for l1 in range(nLearners): 
    1865         mcm[l1]=mcm[l1][:l1] 
     1865        mcm[l1] = mcm[l1][:l1] 
    18661866 
    18671867    return mcm 
     
    18931893    su = tf + ft 
    18941894    if su: 
    1895         return (abs(tf - ft) - 1)**2 / su 
     1895        return (abs(tf - ft) - 1) ** 2 / su 
    18961896    else: 
    18971897        return 0 
     
    19051905    res_split = split_by_iterations(res) 
    19061906    res = [stat(r) for r in res_split] 
    1907      
     1907 
    19081908    N = len(res) 
    19091909    k = len(res[0]) 
     
    19181918    sums = [x / N for x in sums] 
    19191919 
    1920     F = 12. / (N * k * (k + 1)) * T  - 3 * N * (k + 1) 
     1920    F = 12. / (N * k * (k + 1)) * T - 3 * N * (k + 1) 
    19211921 
    19221922    return F, statc.chisqprob(F, k - 1), sums 
     
    19411941        for m2 in range(m1 + 1, k): 
    19421942            t, p = statc.wilcoxont([r[m1] for r in res], [r[m2] for r in res]) 
    1943             if avgranks[m1]<avgranks[m2]: 
     1943            if avgranks[m1] < avgranks[m2]: 
    19441944                nl.append(p) 
    1945             elif avgranks[m2]<avgranks[m1]: 
     1945            elif avgranks[m2] < avgranks[m1]: 
    19461946                nl.append(-p) 
    19471947            else: 
     
    19691969        file = open(file, "wt") 
    19701970        fopened = 1 
    1971          
     1971 
    19721972    file.write("set yrange [0:1]\n") 
    19731973    file.write("set xrange [%f:%f]\n" % (proportions[0], proportions[-1])) 
     
    19781978    for i in range(len(legend) - 1): 
    19791979        if not no_confidence: 
    1980             file.write("'-' title '' with yerrorbars pointtype %i,\\\n" % (i+1)) 
    1981         file.write("'-' title '%s' with linespoints pointtype %i,\\\n" % (legend[i], i+1)) 
     1980            file.write("'-' title '' with yerrorbars pointtype %i,\\\n" % (i + 1)) 
     1981        file.write("'-' title '%s' with linespoints pointtype %i,\\\n" % (legend[i], i + 1)) 
    19821982    if not no_confidence: 
    19831983        file.write("'-' title '' with yerrorbars pointtype %i,\\\n" % (len(legend))) 
     
    19871987        if not no_confidence: 
    19881988            for p in range(len(proportions)): 
    1989                 file.write("%f\t%f\t%f\n" % (proportions[p], CAs[p][i][0], 1.96*CAs[p][i][1])) 
     1989                file.write("%f\t%f\t%f\n" % (proportions[p], CAs[p][i][0], 1.96 * CAs[p][i][1])) 
    19901990            file.write("e\n\n") 
    19911991 
     
    20002000def print_single_ROC_curve_coordinates(file, curve): 
    20012001    import types 
    2002     fopened=0 
    2003     if type(file)==types.StringType: 
    2004         file=open(file, "wt") 
    2005         fopened=1 
     2002    fopened = 0 
     2003    if type(file) == types.StringType: 
     2004        file = open(file, "wt") 
     2005        fopened = 1 
    20062006 
    20072007    for coord in curve: 
     
    20142014def plot_ROC_learners(file, curves, learners): 
    20152015    plot_ROC(file, curves, [Orange.misc.getobjectname(learners[i], "Learner %i" % i) for i in range(len(learners))]) 
    2016      
     2016 
    20172017def plot_ROC(file, curves, legend): 
    20182018    import types 
    2019     fopened=0 
    2020     if type(file)==types.StringType: 
    2021         file=open(file, "wt") 
    2022         fopened=1 
     2019    fopened = 0 
     2020    if type(file) == types.StringType: 
     2021        file = open(file, "wt") 
     2022        fopened = 1 
    20232023 
    20242024    file.write("set yrange [0:1]\n") 
     
    20362036        file.write("e\n\n") 
    20372037 
    2038     file.write("1.0\t1.0\n0.0\t0.0e\n\n")           
     2038    file.write("1.0\t1.0\n0.0\t0.0e\n\n") 
    20392039 
    20402040    if fopened: 
     
    20432043 
    20442044@deprecated_keywords({"allResults": "all_results"}) 
    2045 def plot_McNemar_curve_learners(file, all_results, proportions, learners, reference=-1): 
     2045def plot_McNemar_curve_learners(file, all_results, proportions, learners, reference= -1): 
    20462046    plot_McNemar_curve(file, all_results, proportions, [Orange.misc.getobjectname(learners[i], "Learner %i" % i) for i in range(len(learners))], reference) 
    20472047 
    20482048 
    20492049@deprecated_keywords({"allResults": "all_results"}) 
    2050 def plot_McNemar_curve(file, all_results, proportions, legend, reference=-1): 
    2051     if reference<0: 
    2052         reference=len(legend)-1 
    2053          
     2050def plot_McNemar_curve(file, all_results, proportions, legend, reference= -1): 
     2051    if reference < 0: 
     2052        reference = len(legend) - 1 
     2053 
    20542054    import types 
    2055     fopened=0 
    2056     if type(file)==types.StringType: 
    2057         file=open(file, "wt") 
    2058         fopened=1 
    2059          
     2055    fopened = 0 
     2056    if type(file) == types.StringType: 
     2057        file = open(file, "wt") 
     2058        fopened = 1 
     2059 
    20602060    #file.write("set yrange [0:1]\n") 
    20612061    #file.write("set xrange [%f:%f]\n" % (proportions[0], proportions[-1])) 
    20622062    file.write("set multiplot\n\n") 
    20632063    file.write("plot \\\n") 
    2064     tmap=range(reference)+range(reference+1, len(legend)) 
     2064    tmap = range(reference) + range(reference + 1, len(legend)) 
    20652065    for i in tmap[:-1]: 
    2066         file.write("'-' title '%s' with linespoints pointtype %i,\\\n" % (legend[i], i+1)) 
     2066        file.write("'-' title '%s' with linespoints pointtype %i,\\\n" % (legend[i], i + 1)) 
    20672067    file.write("'-' title '%s' with linespoints pointtype %i\n" % (legend[tmap[-1]], tmap[-1])) 
    20682068    file.write("\n") 
     
    20762076        file.close() 
    20772077 
    2078 default_point_types=("{$\\circ$}", "{$\\diamond$}", "{$+$}", "{$\\times$}", "{$|$}")+tuple([chr(x) for x in range(97, 122)]) 
    2079 default_line_types=("\\setsolid", "\\setdashpattern <4pt, 2pt>", "\\setdashpattern <8pt, 2pt>", "\\setdashes", "\\setdots") 
     2078default_point_types = ("{$\\circ$}", "{$\\diamond$}", "{$+$}", "{$\\times$}", "{$|$}") + tuple([chr(x) for x in range(97, 122)]) 
     2079default_line_types = ("\\setsolid", "\\setdashpattern <4pt, 2pt>", "\\setdashpattern <8pt, 2pt>", "\\setdashes", "\\setdots") 
    20802080 
    20812081@deprecated_keywords({"allResults": "all_results"}) 
     
    20872087def learning_curve_to_PiCTeX(file, all_results, proportions, **options): 
    20882088    import types 
    2089     fopened=0 
    2090     if type(file)==types.StringType: 
    2091         file=open(file, "wt") 
    2092         fopened=1 
    2093  
    2094     nexamples=len(all_results[0].results) 
     2089    fopened = 0 
     2090    if type(file) == types.StringType: 
     2091        file = open(file, "wt") 
     2092        fopened = 1 
     2093 
     2094    nexamples = len(all_results[0].results) 
    20952095    CAs = [CA(x, report_se=True) for x in all_results] 
    20962096 
    2097     graphsize=float(options.get("graphsize", 10.0)) #cm 
    2098     difprop=proportions[-1]-proportions[0] 
    2099     ntestexamples=nexamples*proportions[-1] 
    2100     xunit=graphsize/ntestexamples 
    2101  
    2102     yshift=float(options.get("yshift", -ntestexamples/20.)) 
    2103      
    2104     pointtypes=options.get("pointtypes", default_point_types) 
    2105     linetypes=options.get("linetypes", default_line_types) 
     2097    graphsize = float(options.get("graphsize", 10.0)) #cm 
     2098    difprop = proportions[-1] - proportions[0] 
     2099    ntestexamples = nexamples * proportions[-1] 
     2100    xunit = graphsize / ntestexamples 
     2101 
     2102    yshift = float(options.get("yshift", -ntestexamples / 20.)) 
     2103 
     2104    pointtypes = options.get("pointtypes", default_point_types) 
     2105    linetypes = options.get("linetypes", default_line_types) 
    21062106 
    21072107    if options.has_key("numberedx"): 
    2108         numberedx=options["numberedx"] 
    2109         if type(numberedx)==types.IntType: 
    2110             if numberedx>0: 
    2111                 numberedx=[nexamples*proportions[int(i/float(numberedx)*len(proportions))] for i in range(numberedx)]+[proportions[-1]*nexamples] 
    2112             elif numberedx<0: 
     2108        numberedx = options["numberedx"] 
     2109        if type(numberedx) == types.IntType: 
     2110            if numberedx > 0: 
     2111                numberedx = [nexamples * proportions[int(i / float(numberedx) * len(proportions))] for i in range(numberedx)] + [proportions[-1] * nexamples] 
     2112            elif numberedx < 0: 
    21132113                numberedx = -numberedx 
    2114                 newn=[] 
    2115                 for i in range(numberedx+1): 
    2116                     wanted=proportions[0]+float(i)/numberedx*difprop 
    2117                     best=(10, 0) 
     2114                newn = [] 
     2115                for i in range(numberedx + 1): 
     2116                    wanted = proportions[0] + float(i) / numberedx * difprop 
     2117                    best = (10, 0) 
    21182118                    for t in proportions: 
    2119                         td=abs(wanted-t) 
    2120                         if td<best[0]: 
    2121                             best=(td, t) 
     2119                        td = abs(wanted - t) 
     2120                        if td < best[0]: 
     2121                            best = (td, t) 
    21222122                    if not best[1] in newn: 
    21232123                        newn.append(best[1]) 
    21242124                newn.sort() 
    2125                 numberedx=[nexamples*x for x in newn] 
    2126         elif type(numberedx[0])==types.FloatType: 
    2127             numberedx=[nexamples*x for x in numberedx] 
     2125                numberedx = [nexamples * x for x in newn] 
     2126        elif type(numberedx[0]) == types.FloatType: 
     2127            numberedx = [nexamples * x for x in numberedx] 
    21282128    else: 
    2129         numberedx=[nexamples*x for x in proportions] 
     2129        numberedx = [nexamples * x for x in proportions] 
    21302130 
    21312131    file.write("\\mbox{\n") 
    21322132    file.write("  \\beginpicture\n") 
    2133     file.write("  \\setcoordinatesystem units <%10.8fcm, %5.3fcm>\n\n" % (xunit, graphsize))     
    2134     file.write("  \\setplotarea x from %5.3f to %5.3f, y from 0 to 1\n" % (0, ntestexamples))     
     2133    file.write("  \\setcoordinatesystem units <%10.8fcm, %5.3fcm>\n\n" % (xunit, graphsize)) 
     2134    file.write("  \\setplotarea x from %5.3f to %5.3f, y from 0 to 1\n" % (0, ntestexamples)) 
    21352135    file.write("  \\axis bottom invisible\n")# label {#examples}\n") 
    2136     file.write("      ticks short at %s /\n" % reduce(lambda x,y:x+" "+y, ["%i"%(x*nexamples+0.5) for x in proportions])) 
     2136    file.write("      ticks short at %s /\n" % reduce(lambda x, y:x + " " + y, ["%i" % (x * nexamples + 0.5) for x in proportions])) 
    21372137    if numberedx: 
    2138         file.write("            long numbered at %s /\n" % reduce(lambda x,y:x+y, ["%i " % int(x+0.5) for x in numberedx])) 
     2138        file.write("            long numbered at %s /\n" % reduce(lambda x, y:x + y, ["%i " % int(x + 0.5) for x in numberedx])) 
    21392139    file.write("  /\n") 
    21402140    file.write("  \\axis left invisible\n")# label {classification accuracy}\n") 
     
    21462146        file.write("  \\setdashpattern<1pt, 1pt>\n") 
    21472147        file.write("  \\plot %5.3f %5.3f %5.3f %5.3f /\n" % (0., options["default"], ntestexamples, options["default"])) 
    2148      
     2148 
    21492149    for i in range(len(CAs[0])): 
    2150         coordinates=reduce(lambda x,y:x+" "+y, ["%i %5.3f" % (proportions[p]*nexamples, CAs[p][i][0]) for p in range(len(proportions))]) 
     2150        coordinates = reduce(lambda x, y:x + " " + y, ["%i %5.3f" % (proportions[p] * nexamples, CAs[p][i][0]) for p in range(len(proportions))]) 
    21512151        if linetypes: 
    21522152            file.write("  %s\n" % linetypes[i]) 
     
    21642164def legend_learners_to_PiCTeX(file, learners, **options): 
    21652165  return apply(legend_to_PiCTeX, (file, [Orange.misc.getobjectname(learners[i], "Learner %i" % i) for i in range(len(learners))]), options) 
    2166      
     2166 
    21672167def legend_to_PiCTeX(file, legend, **options): 
    21682168    import types 
    2169     fopened=0 
    2170     if type(file)==types.StringType: 
    2171         file=open(file, "wt") 
    2172         fopened=1 
    2173  
    2174     pointtypes=options.get("pointtypes", default_point_types) 
    2175     linetypes=options.get("linetypes", default_line_types) 
     2169    fopened = 0 
     2170    if type(file) == types.StringType: 
     2171        file = open(file, "wt") 
     2172        fopened = 1 
     2173 
     2174    pointtypes = options.get("pointtypes", default_point_types) 
     2175    linetypes = options.get("linetypes", default_line_types) 
    21762176 
    21772177    file.write("\\mbox{\n") 
     
    21832183        if linetypes: 
    21842184            file.write("  %s\n" % linetypes[i]) 
    2185             file.write("  \\plot %5.3f 6 %5.3f 6 /\n" % (i, i+0.2)) 
     2185            file.write("  \\plot %5.3f 6 %5.3f 6 /\n" % (i, i + 0.2)) 
    21862186        if pointtypes: 
    2187             file.write("  \\put {%s} at %5.3f 6\n" % (pointtypes[i], i+0.1)) 
    2188         file.write("  \\put {%s} [lb] at %5.3f 0\n" % (legend[i], i+0.25)) 
     2187            file.write("  \\put {%s} at %5.3f 6\n" % (pointtypes[i], i + 0.1)) 
     2188        file.write("  \\put {%s} [lb] at %5.3f 0\n" % (legend[i], i + 0.25)) 
    21892189 
    21902190    file.write("  \\endpicture\n") 
     
    22052205 
    22062206    def friedman(N, k, ranks): 
    2207         return 12*N*(sum([rank**2.0 for rank in ranks]) - (k*(k+1)*(k+1)/4.0) )/(k*(k+1)) 
     2207        return 12 * N * (sum([rank ** 2.0 for rank in ranks]) - (k * (k + 1) * (k + 1) / 4.0)) / (k * (k + 1)) 
    22082208 
    22092209    def iman(fried, N, k): 
    2210         return (N-1)*fried/(N*(k-1) - fried) 
     2210        return (N - 1) * fried / (N * (k - 1) - fried) 
    22112211 
    22122212    f = friedman(N, k, avranks) 
    22132213    im = iman(f, N, k) 
    2214     fdistdof = (k-1, (k-1)*(N-1)) 
    2215  
    2216     return (f, k-1), (im, fdistdof) 
     2214    fdistdof = (k - 1, (k - 1) * (N - 1)) 
     2215 
     2216    return (f, k - 1), (im, fdistdof) 
    22172217 
    22182218def compute_CD(avranks, N, alpha="0.05", type="nemenyi"): 
     
    22242224 
    22252225    k = len(avranks) 
    2226     
     2226 
    22272227    d = {("nemenyi", "0.05"): [0, 0, 1.959964, 2.343701, 2.569032, 2.727774, 
    22282228                               2.849705, 2.94832, 3.030879, 3.101730, 3.163684, 
     
    22432243    q = d[(type, alpha)] 
    22442244 
    2245     cd = q[k]*(k*(k+1)/(6.0*N))**0.5 
     2245    cd = q[k] * (k * (k + 1) / (6.0 * N)) ** 0.5 
    22462246 
    22472247    return cd 
    2248   
     2248 
    22492249 
    22502250def graph_ranks(filename, avranks, names, cd=None, cdmethod=None, lowv=None, highv=None, width=6, textspace=1, reverse=False, **kwargs): 
     
    22822282    textspace = float(textspace) 
    22832283 
    2284     def nth(l,n): 
     2284    def nth(l, n): 
    22852285        """ 
    22862286        Returns only nth elemnt in a list. 
    22872287        """ 
    2288         n = lloc(l,n) 
     2288        n = lloc(l, n) 
    22892289        return [ a[n] for a in l ] 
    22902290 
    2291     def lloc(l,n): 
     2291    def lloc(l, n): 
    22922292        """ 
    22932293        List location in list of list structure. 
     
    22962296        """ 
    22972297        if n < 0: 
    2298             return len(l[0])+n 
    2299         else: 
    2300             return n  
     2298            return len(l[0]) + n 
     2299        else: 
     2300            return n 
    23012301 
    23022302    def mxrange(lr): 
     
    23342334    sums = avranks 
    23352335 
    2336     tempsort =  sorted([ (a,i) for i,a in  enumerate(sums) ], reverse=reverse) 
     2336    tempsort = sorted([ (a, i) for i, a in  enumerate(sums) ], reverse=reverse) 
    23372337    ssums = nth(tempsort, 0) 
    23382338    sortidx = nth(tempsort, 1) 
    23392339    nnames = [ names[x] for x in sortidx ] 
    2340      
     2340 
    23412341    if lowv is None: 
    23422342        lowv = min(1, int(math.floor(min(ssums)))) 
     
    23512351 
    23522352    linesblank = 0 
    2353     scalewidth = width - 2*textspace 
     2353    scalewidth = width - 2 * textspace 
    23542354 
    23552355    def rankpos(rank): 
     
    23582358        else: 
    23592359            a = highv - rank 
    2360         return textspace+scalewidth/(highv-lowv)*a 
     2360        return textspace + scalewidth / (highv - lowv) * a 
    23612361 
    23622362    distanceh = 0.25 
    23632363 
    23642364    if cd and cdmethod is None: 
    2365      
     2365 
    23662366        #get pairs of non significant methods 
    23672367 
     
    23702370            #get all pairs 
    23712371            lsums = len(sums) 
    2372             allpairs = [ (i,j) for i,j in mxrange([[lsums], [lsums]]) if j > i ] 
     2372            allpairs = [ (i, j) for i, j in mxrange([[lsums], [lsums]]) if j > i ] 
    23732373            #remove not significant 
    2374             notSig = [ (i,j) for i,j in allpairs if abs(sums[i]-sums[j]) <= hsd ] 
     2374            notSig = [ (i, j) for i, j in allpairs if abs(sums[i] - sums[j]) <= hsd ] 
    23752375            #keep only longest 
    2376              
    2377             def no_longer((i,j), notSig): 
    2378                 for i1,j1 in notSig: 
     2376 
     2377            def no_longer((i, j), notSig): 
     2378                for i1, j1 in notSig: 
    23792379                    if (i1 <= i and j1 > j) or (i1 < i and j1 >= j): 
    23802380                        return False 
    23812381                return True 
    23822382 
    2383             longest = [ (i,j) for i,j in notSig if no_longer((i,j),notSig) ] 
    2384              
     2383            longest = [ (i, j) for i, j in notSig if no_longer((i, j), notSig) ] 
     2384 
    23852385            return longest 
    23862386 
    23872387        lines = get_lines(ssums, cd) 
    2388         linesblank = 0.2 + 0.2 + (len(lines)-1)*0.1 
     2388        linesblank = 0.2 + 0.2 + (len(lines) - 1) * 0.1 
    23892389 
    23902390        #add scale 
     
    23932393 
    23942394    #calculate height needed height of an image 
    2395     minnotsignificant = max(2*0.2, linesblank) 
    2396     height = cline + ((k+1)/2)*0.2 + minnotsignificant 
     2395    minnotsignificant = max(2 * 0.2, linesblank) 
     2396    height = cline + ((k + 1) / 2) * 0.2 + minnotsignificant 
    23972397 
    23982398    fig = Figure(figsize=(width, height)) 
    2399     ax = fig.add_axes([0,0,1,1]) #reverse y axis 
     2399    ax = fig.add_axes([0, 0, 1, 1]) #reverse y axis 
    24002400    ax.set_axis_off() 
    24012401 
    2402     hf = 1./height # height factor 
    2403     wf = 1./width 
    2404  
    2405     def hfl(l):  
    2406         return [ a*hf for a in l ] 
    2407  
    2408     def wfl(l):  
    2409         return [ a*wf for a in l ] 
     2402    hf = 1. / height # height factor 
     2403    wf = 1. / width 
     2404 
     2405    def hfl(l): 
     2406        return [ a * hf for a in l ] 
     2407 
     2408    def wfl(l): 
     2409        return [ a * wf for a in l ] 
    24102410 
    24112411 
    24122412    # Upper left corner is (0,0). 
    24132413 
    2414     ax.plot([0,1], [0,1], c="w") 
     2414    ax.plot([0, 1], [0, 1], c="w") 
    24152415    ax.set_xlim(0, 1) 
    24162416    ax.set_ylim(1, 0) 
     
    24202420        Input is a list of pairs of points. 
    24212421        """ 
    2422         ax.plot(wfl(nth(l,0)), hfl(nth(l,1)), color=color, **kwargs) 
     2422        ax.plot(wfl(nth(l, 0)), hfl(nth(l, 1)), color=color, **kwargs) 
    24232423 
    24242424    def text(x, y, s, *args, **kwargs): 
    2425         ax.text(wf*x, hf*y, s, *args, **kwargs) 
    2426  
    2427     line([(textspace, cline), (width-textspace, cline)], linewidth=0.7) 
    2428      
     2425        ax.text(wf * x, hf * y, s, *args, **kwargs) 
     2426 
     2427    line([(textspace, cline), (width - textspace, cline)], linewidth=0.7) 
     2428 
    24292429    bigtick = 0.1 
    24302430    smalltick = 0.05 
     
    24362436        tick = smalltick 
    24372437        if a == int(a): tick = bigtick 
    2438         line([(rankpos(a), cline-tick/2),(rankpos(a), cline)], linewidth=0.7) 
    2439  
    2440     for a in range(lowv, highv+1): 
    2441         text(rankpos(a), cline-tick/2-0.05, str(a), ha="center", va="bottom") 
     2438        line([(rankpos(a), cline - tick / 2), (rankpos(a), cline)], linewidth=0.7) 
     2439 
     2440    for a in range(lowv, highv + 1): 
     2441        text(rankpos(a), cline - tick / 2 - 0.05, str(a), ha="center", va="bottom") 
    24422442 
    24432443    k = len(ssums) 
    24442444 
    2445     for i in range((k+1)/2): 
    2446         chei = cline+ minnotsignificant + i *0.2 
    2447         line([(rankpos(ssums[i]), cline), (rankpos(ssums[i]), chei), (textspace-0.1, chei)], linewidth=0.7) 
    2448         text(textspace-0.2, chei, nnames[i], ha="right", va="center") 
    2449  
    2450     for i in range((k+1)/2, k): 
    2451         chei = cline + minnotsignificant + (k-i-1)*0.2 
    2452         line([(rankpos(ssums[i]), cline), (rankpos(ssums[i]), chei), (textspace+scalewidth+0.1, chei)], linewidth=0.7) 
    2453         text(textspace+scalewidth+0.2, chei, nnames[i], ha="left", va="center") 
     2445    for i in range((k + 1) / 2): 
     2446        chei = cline + minnotsignificant + i * 0.2 
     2447        line([(rankpos(ssums[i]), cline), (rankpos(ssums[i]), chei), (textspace - 0.1, chei)], linewidth=0.7) 
     2448        text(textspace - 0.2, chei, nnames[i], ha="right", va="center") 
     2449 
     2450    for i in range((k + 1) / 2, k): 
     2451        chei = cline + minnotsignificant + (k - i - 1) * 0.2 
     2452        line([(rankpos(ssums[i]), cline), (rankpos(ssums[i]), chei), (textspace + scalewidth + 0.1, chei)], linewidth=0.7) 
     2453        text(textspace + scalewidth + 0.2, chei, nnames[i], ha="left", va="center") 
    24542454 
    24552455    if cd and cdmethod is None: 
     
    24572457        #upper scale 
    24582458        if not reverse: 
    2459             begin, end = rankpos(lowv), rankpos(lowv+cd) 
     2459            begin, end = rankpos(lowv), rankpos(lowv + cd) 
    24602460        else: 
    24612461            begin, end = rankpos(highv), rankpos(highv - cd) 
    2462              
     2462 
    24632463        line([(begin, distanceh), (end, distanceh)], linewidth=0.7) 
    2464         line([(begin, distanceh + bigtick/2), (begin, distanceh - bigtick/2)], linewidth=0.7) 
    2465         line([(end, distanceh + bigtick/2), (end, distanceh - bigtick/2)], linewidth=0.7) 
    2466         text((begin+end)/2, distanceh - 0.05, "CD", ha="center", va="bottom") 
     2464        line([(begin, distanceh + bigtick / 2), (begin, distanceh - bigtick / 2)], linewidth=0.7) 
     2465        line([(end, distanceh + bigtick / 2), (end, distanceh - bigtick / 2)], linewidth=0.7) 
     2466        text((begin + end) / 2, distanceh - 0.05, "CD", ha="center", va="bottom") 
    24672467 
    24682468        #non significance lines     
    24692469        def draw_lines(lines, side=0.05, height=0.1): 
    24702470            start = cline + 0.2 
    2471             for l,r in lines:   
    2472                 line([(rankpos(ssums[l])-side, start), (rankpos(ssums[r])+side, start)], linewidth=2.5)  
     2471            for l, r in lines: 
     2472                line([(rankpos(ssums[l]) - side, start), (rankpos(ssums[r]) + side, start)], linewidth=2.5) 
    24732473                start += height 
    24742474 
     
    24762476 
    24772477    elif cd: 
    2478         begin = rankpos(avranks[cdmethod]-cd) 
    2479         end = rankpos(avranks[cdmethod]+cd) 
    2480         line([(begin, cline), (end, cline)], linewidth=2.5)  
    2481         line([(begin, cline + bigtick/2), (begin, cline - bigtick/2)], linewidth=2.5) 
    2482         line([(end, cline + bigtick/2), (end, cline - bigtick/2)], linewidth=2.5) 
    2483   
     2478        begin = rankpos(avranks[cdmethod] - cd) 
     2479        end = rankpos(avranks[cdmethod] + cd) 
     2480        line([(begin, cline), (end, cline)], linewidth=2.5) 
     2481        line([(begin, cline + bigtick / 2), (begin, cline - bigtick / 2)], linewidth=2.5) 
     2482        line([(end, cline + bigtick / 2), (end, cline - bigtick / 2)], linewidth=2.5) 
     2483 
    24842484    print_figure(fig, filename, **kwargs) 
    24852485 
     
    24902490    :math:`HammingLoss(H,D)=\\frac{1}{|D|} \\sum_{i=1}^{|D|} \\frac{Y_i \\vartriangle Z_i}{|L|}` 
    24912491    """ 
    2492     losses = [0]*res.number_of_learners 
     2492    losses = [0] * res.number_of_learners 
    24932493    label_num = len(res.labels) 
    24942494    example_num = gettotsize(res) 
     
    25032503                if labels[j] != aclass[j]: 
    25042504                    losses[i] += 1 
    2505              
    2506     return [float(x)/(label_num*example_num) for x in losses] 
    2507  
    2508 def mlc_accuracy(res, forgiveness_rate = 1.0): 
     2505 
     2506    return [float(x) / (label_num * example_num) for x in losses] 
     2507 
     2508def mlc_accuracy(res, forgiveness_rate=1.0): 
    25092509    """ 
    25102510    Godbole & Sarawagi, 2004 uses the metrics accuracy, precision, recall as follows: 
     
    25172517    :math:`Accuracy(H,D)=\\frac{1}{|D|} \\sum_{i=1}^{|D|} (\\frac{|Y_i \\cap Z_i|}{|Y_i \\cup Z_i|})^{\\alpha}` 
    25182518    """ 
    2519     accuracies = [0.0]*res.number_of_learners 
     2519    accuracies = [0.0] * res.number_of_learners 
    25202520    example_num = gettotsize(res) 
    2521      
     2521 
    25222522    for e in res.results: 
    25232523        aclass = e.actual_class 
     
    25262526            if len(labels) <> len(aclass): 
    25272527                raise ValueError, "The dimensions of the classified output and the actual class array do not match." 
    2528              
     2528 
    25292529            intersection = 0.0 
    25302530            union = 0.0 
     
    25372537            if union: 
    25382538                accuracies[i] += intersection / union 
    2539              
    2540     return [math.pow(x/example_num,forgiveness_rate) for x in accuracies] 
     2539 
     2540    return [math.pow(x / example_num, forgiveness_rate) for x in accuracies] 
    25412541 
    25422542def mlc_precision(res): 
     
    25442544    :math:`Precision(H,D)=\\frac{1}{|D|} \\sum_{i=1}^{|D|} \\frac{|Y_i \\cap Z_i|}{|Z_i|}` 
    25452545    """ 
    2546     precisions = [0.0]*res.number_of_learners 
     2546    precisions = [0.0] * res.number_of_learners 
    25472547    example_num = gettotsize(res) 
    2548      
     2548 
    25492549    for e in res.results: 
    25502550        aclass = e.actual_class 
     
    25532553            if len(labels) <> len(aclass): 
    25542554                raise ValueError, "The dimensions of the classified output and the actual class array do not match." 
    2555              
     2555 
    25562556            intersection = 0.0 
    25572557            predicted = 0.0 
     
    25632563            if predicted: 
    25642564                precisions[i] += intersection / predicted 
    2565              
    2566     return [x/example_num for x in precisions] 
     2565 
     2566    return [x / example_num for x in precisions] 
    25672567 
    25682568def mlc_recall(res): 
     
    25702570    :math:`Recall(H,D)=\\frac{1}{|D|} \\sum_{i=1}^{|D|} \\frac{|Y_i \\cap Z_i|}{|Y_i|}` 
    25712571    """ 
    2572     recalls = [0.0]*res.number_of_learners 
     2572    recalls = [0.0] * res.number_of_learners 
    25732573    example_num = gettotsize(res) 
    2574      
     2574 
    25752575    for e in res.results: 
    25762576        aclass = e.actual_class 
     
    25792579            if len(labels) <> len(aclass): 
    25802580                raise ValueError, "The dimensions of the classified output and the actual class array do not match." 
    2581              
     2581 
    25822582            intersection = 0.0 
    25832583            actual = 0.0 
     
    25892589            if actual: 
    25902590                recalls[i] += intersection / actual 
    2591              
    2592     return [x/example_num for x in recalls] 
     2591 
     2592    return [x / example_num for x in recalls] 
    25932593 
    25942594#def mlc_ranking_loss(res): 
     
    26712671################################################################################ 
    26722672if __name__ == "__main__": 
    2673     avranks =  [3.143, 2.000, 2.893, 1.964] 
     2673    avranks = [3.143, 2.000, 2.893, 1.964] 
    26742674    names = ["prva", "druga", "tretja", "cetrta" ] 
    26752675    cd = compute_CD(avranks, 14) 
  • Orange/optimization/__init__.py

    r10582 r10633  
    194194        import string 
    195195        names = string.split(name, ".") 
    196         lastobj = self.object 
     196        lastobj = self.learner 
    197197        for i in names[:-1]: 
    198198            lastobj = getattr(lastobj, i) 
     
    269269        compare = getattr(self, "compare", cmp) 
    270270        return_what = getattr(self, "return_what", 
    271                              Tune1Parameter.returnClassifier) 
     271                             Tune1Parameter.RETURN_CLASSIFIER) 
    272272 
    273273        if (type(self.parameter) == list) or (type(self.parameter) == tuple): 
     
    278278        cvind = Orange.core.MakeRandomIndicesCV(data, folds) 
    279279        findBest = Orange.misc.selection.BestOnTheFly(seed=data.checksum(), 
    280                                          callCompareOn1st=True) 
     280                                         call_compare_on_1st=True) 
    281281        tableAndWeight = weight and (data, weight) or data 
    282282        for par in self.values: 
     
    284284                setattr(i[0], i[1], par) 
    285285            res = evaluate(Orange.evaluation.testing.test_with_indices( 
    286                                         [self.object], tableAndWeight, cvind)) 
     286                                        [self.learner], tableAndWeight, cvind)) 
    287287            findBest.candidate((res, par)) 
    288288            if verbose == 2: 
     
    296296            print "*** Optimal parameter: %s = %s" % (self.parameter, bestpar) 
    297297 
    298         if return_what == Tune1Parameter.returnNone: 
     298        if return_what == Tune1Parameter.RETURN_NONE: 
    299299            return None 
    300         elif return_what == Tune1Parameter.returnParameters: 
     300        elif return_what == Tune1Parameter.RETURN_PARAMETERS: 
    301301            return bestpar 
    302         elif return_what == Tune1Parameter.returnLearner: 
    303             return self.object 
    304         else: 
    305             classifier = self.object(data) 
     302        elif return_what == Tune1Parameter.RETURN_LEARNER: 
     303            return self.learner 
     304        else: 
     305            classifier = self.learner(data) 
    306306            if not Orange.utils.environ.orange_no_deprecated_members: 
    307307                classifier.setattr("fittedParameter", bestpar) 
     
    334334        compare = getattr(self, "compare", cmp) 
    335335        verbose = verbose or getattr(self, "verbose", 0) 
    336         return_what = getattr(self, "return_what", Tune1Parameter.returnClassifier) 
     336        return_what = getattr(self, "return_what", Tune1Parameter.RETURN_CLASSIFIER) 
    337337        progress_callback = getattr(self, "progress_callback", lambda i: None) 
    338338 
     
    350350        cvind = Orange.core.MakeRandomIndicesCV(data, folds) 
    351351        findBest = Orange.misc.selection.BestOnTheFly(seed=data.checksum(), 
    352                                          callCompareOn1st=True) 
     352                                         call_compare_on_1st=True) 
    353353        tableAndWeight = weight and (data, weight) or data 
    354354        numOfTests = sum([len(x[1]) for x in self.parameters]) 
     
    365365 
    366366            res = evaluate(Orange.evaluation.testing.test_with_indices( 
    367                                         [self.object], tableAndWeight, cvind)) 
     367                                        [self.learner], tableAndWeight, cvind)) 
    368368            if itercount in milestones: 
    369369                progress_callback(100.0 * itercount / numOfTests) 
     
    384384            print 
    385385 
    386         if return_what == Tune1Parameter.returnNone: 
     386        if return_what == Tune1Parameter.RETURN_NONE: 
    387387            return None 
    388         elif return_what == Tune1Parameter.returnParameters: 
     388        elif return_what == Tune1Parameter.RETURN_PARAMETERS: 
    389389            return bestpar 
    390         elif return_what == Tune1Parameter.returnLearner: 
    391             return self.object 
    392         else: 
    393             classifier = self.object(data) 
     390        elif return_what == Tune1Parameter.RETURN_LEARNER: 
     391            return self.learner 
     392        else: 
     393            classifier = self.learner(data) 
    394394            if Orange.utils.environ.orange_no_deprecated_members: 
    395395                classifier.fittedParameters = bestpar 
  • Orange/orng/orngMisc.py

    r9671 r10633  
    11from __future__ import with_statement 
    22import random, types 
    3  
     3import os.path 
     4 
     5from Orange.utils.environ import install_dir 
    46## -> Orange.misc 
    57 
    68def getobjectname(x, default=""): 
    7     if type(x)==types.StringType: 
     9    if type(x) == types.StringType: 
    810        return x 
    9        
     11 
    1012    for i in ["name", "shortDescription", "description", "func_doc", "func_name"]: 
    1113        if getattr(x, i, ""): 
     
    1416    if hasattr(x, "__class__"): 
    1517        r = repr(x.__class__) 
    16         if r[1:5]=="type": 
     18        if r[1:5] == "type": 
    1719            return str(x.__class__)[7:-2] 
    18         elif r[1:6]=="class": 
     20        elif r[1:6] == "class": 
    1921            return str(x.__class__)[8:-2] 
    2022 
     
    2325 
    2426def demangleExamples(x): 
    25     if type(x)==types.TupleType: 
     27    if type(x) == types.TupleType: 
    2628        return x 
    2729    else: 
    2830        return x, 0 
    29      
     31 
    3032 
    3133## -> Orange.misc.counters 
     
    4143    else: 
    4244        return BooleanCounter(self.bits) 
    43      
     45 
    4446  def next(self): 
    4547    if self.state: 
    46       for bit in range(self.bits-1, -1, -1): 
    47         self.state[bit] = (self.state[bit]+1) % 2 
     48      for bit in range(self.bits - 1, -1, -1): 
     49        self.state[bit] = (self.state[bit] + 1) % 2 
    4850        if self.state[bit]: 
    4951          break 
     
    5153        self.state = None 
    5254    else: 
    53       self.state = [0]*self.bits 
     55      self.state = [0] * self.bits 
    5456 
    5557    if not self.state: 
     
    6365    self.limits = limits 
    6466    self.state = None 
    65      
     67 
    6668  def __iter__(self): 
    6769    if self.state: 
     
    7274  def next(self): 
    7375    if self.state: 
    74       i = len(self.limits)-1 
    75       while (i>=0) and (self.state[i]==self.limits[i]-1): 
     76      i = len(self.limits) - 1 
     77      while (i >= 0) and (self.state[i] == self.limits[i] - 1): 
    7678        self.state[i] = 0 
    7779        i -= 1 
    78       if i==-1: 
     80      if i == -1: 
    7981        self.state = None 
    8082      else: 
    8183        self.state[i] += 1 
    8284    else: 
    83       self.state = [0]*len(self.limits) 
    84    
     85      self.state = [0] * len(self.limits) 
     86 
    8587    if not self.state: 
    8688      raise StopIteration, "LimitedCounter: counting finished" 
     
    9395        if m > n: 
    9496            raise TypeError, "Number of selected items exceeds the number of items" 
    95          
     97 
    9698        self.state = None 
    9799        self.m = m 
    98100        self.n = n 
    99          
     101 
    100102    def __iter__(self): 
    101103        if self.state: 
     
    103105        else: 
    104106            return MofNCounter(self.m, self.n) 
    105          
     107 
    106108    def next(self): 
    107109        if self.state: 
    108110            m, n, state = self.m, self.n, self.state 
    109             for place in range(m-1, -1, -1): 
    110                 if state[place] + m-1-place < n-1: 
     111            for place in range(m - 1, -1, -1): 
     112                if state[place] + m - 1 - place < n - 1: 
    111113                    state[place] += 1 
    112                     for place in range(place+1, m): 
    113                         state[place] = state[place-1] + 1 
     114                    for place in range(place + 1, m): 
     115                        state[place] = state[place - 1] + 1 
    114116                    break 
    115117            else: 
     
    118120        else: 
    119121            self.state = range(self.m) 
    120              
     122 
    121123        return self.state[:] 
    122               
     124 
    123125class NondecreasingCounter: 
    124126  def __init__(self, places): 
    125     self.state=None 
    126     self.subcounter=None 
    127     self.places=places 
     127    self.state = None 
     128    self.subcounter = None 
     129    self.places = places 
    128130 
    129131  def __iter__(self): 
     
    135137  def next(self): 
    136138    if not self.subcounter: 
    137       self.subcounter=BooleanCounter(self.places-1) 
     139      self.subcounter = BooleanCounter(self.places - 1) 
    138140    if self.subcounter.next(): 
    139       self.state=[0] 
     141      self.state = [0] 
    140142      for add_one in self.subcounter.state: 
    141         self.state.append(self.state[-1]+add_one) 
     143        self.state.append(self.state[-1] + add_one) 
    142144    else: 
    143       self.state=None 
    144    
     145      self.state = None 
     146 
    145147    if not self.state: 
    146148      raise StopIteration, "NondecreasingCounter: counting finished" 
     
    162164  def next(self): 
    163165    if self.state: 
    164       i = self.places-1 
    165       while (i>0) and (self.state[i]==max(self.state[:i])+1): 
     166      i = self.places - 1 
     167      while (i > 0) and (self.state[i] == max(self.state[:i]) + 1): 
    166168        self.state[i] = 0 
    167169        i -= 1 
     
    169171        self.state[i] += 1 
    170172      else: 
    171         self.state=None 
     173        self.state = None 
    172174    else: 
    173       self.state = [0]*self.places 
     175      self.state = [0] * self.places 
    174176 
    175177    if not self.state: 
    176178      raise StopIteration, "CanonicFuncCounter: counting finished" 
    177      
     179 
    178180    return self.state 
    179181 
     
    184186 
    185187class BestOnTheFly: 
    186     def __init__(self, compare=cmp, seed = 0, callCompareOn1st = False): 
     188    def __init__(self, compare=cmp, seed=0, callCompareOn1st=False): 
    187189        self.randomGenerator = random.Random(seed) 
    188         self.compare=compare 
    189         self.wins=0 
     190        self.compare = compare 
     191        self.wins = 0 
    190192        self.bestIndex, self.index = -1, -1 
    191193        self.best = None 
     
    195197        self.index += 1 
    196198        if not self.wins: 
    197             self.best=x 
    198             self.wins=1 
    199             self.bestIndex=self.index 
     199            self.best = x 
     200            self.wins = 1 
     201            self.bestIndex = self.index 
    200202            return 1 
    201203        else: 
    202204            if self.callCompareOn1st: 
    203                 cmpr=self.compare(x[0], self.best[0]) 
     205                cmpr = self.compare(x[0], self.best[0]) 
    204206            else: 
    205                 cmpr=self.compare(x, self.best) 
    206             if cmpr>0: 
    207                 self.best=x 
    208                 self.wins=1 
    209                 self.bestIndex=self.index 
     207                cmpr = self.compare(x, self.best) 
     208            if cmpr > 0: 
     209                self.best = x 
     210                self.wins = 1 
     211                self.bestIndex = self.index 
    210212                return 1 
    211             elif cmpr==0: 
    212                 self.wins=self.wins+1 
    213                 if not self.randomGenerator.randint(0, self.wins-1): 
    214                     self.best=x 
    215                     self.bestIndex=self.index 
     213            elif cmpr == 0: 
     214                self.wins = self.wins + 1 
     215                if not self.randomGenerator.randint(0, self.wins - 1): 
     216                    self.best = x 
     217                    self.bestIndex = self.index 
    216218                    return 1 
    217219        return 0 
     
    226228            return None 
    227229 
    228 def selectBest(x, compare=cmp, seed = 0, callCompareOn1st = False): 
    229     bs=BestOnTheFly(compare, seed, callCompareOn1st) 
     230def selectBest(x, compare=cmp, seed=0, callCompareOn1st=False): 
     231    bs = BestOnTheFly(compare, seed, callCompareOn1st) 
    230232    for i in x: 
    231233        bs.candidate(i) 
    232234    return bs.winner() 
    233235 
    234 def selectBestIndex(x, compare=cmp, seed = 0, callCompareOn1st = False): 
    235     bs=BestOnTheFly(compare, seed, callCompareOn1st) 
     236def selectBestIndex(x, compare=cmp, seed=0, callCompareOn1st=False): 
     237    bs = BestOnTheFly(compare, seed, callCompareOn1st) 
    236238    for i in x: 
    237239        bs.candidate(i) 
     
    261263def frange(*argw): 
    262264    start, stop, step = 0.0, 1.0, 0.1 
    263     if len(argw)==1: 
    264         start=step=argw[0] 
    265     elif len(argw)==2: 
     265    if len(argw) == 1: 
     266        start = step = argw[0] 
     267    elif len(argw) == 2: 
    266268        stop, step = argw 
    267     elif len(argw)==3: 
     269    elif len(argw) == 3: 
    268270        start, stop, step = argw 
    269     elif len(argw)>3: 
     271    elif len(argw) > 3: 
    270272        raise AttributeError, "1-3 arguments expected" 
    271273 
    272     stop+=1e-10 
    273     i=0 
    274     res=[] 
     274    stop += 1e-10 
     275    i = 0 
     276    res = [] 
    275277    while 1: 
    276         f=start+i*step 
    277         if f>stop: 
     278        f = start + i * step 
     279        if f > stop: 
    278280            break 
    279281        res.append(f) 
    280         i+=1 
     282        i += 1 
    281283    return res 
    282284 
     
    301303        self.output = output 
    302304 
    303     def clear(self, i=-1): 
     305    def clear(self, i= -1): 
    304306        try: 
    305307            if hasattr(self.output, "isatty") and self.output.isatty(): 
     
    335337        self.__call__(100) 
    336338        self.output.write("\n") 
    337          
     339 
    338340def progressBarMilestones(count, iterations=100): 
    339     return set([int(i*count/float(iterations)) for i in range(iterations)]) 
     341    return set([int(i * count / float(iterations)) for i in range(iterations)]) 
    340342 
    341343 
    342344## Odkrij, kdo to uporablja 
    343        
     345 
    344346class ColorPalette(object): 
    345347    def __init__(self, colors, gamma=None, overflow=(255, 255, 255), underflow=(255, 255, 255), unknown=(0, 0, 0)): 
    346348        self.colors = colors 
    347         self.gammaFunc = lambda x, gamma:((math.exp(gamma*math.log(2*x-1)) if x > 0.5 else -math.exp(gamma*math.log(-2*x+1)) if x!=0.5 else 0.0)+1)/2.0 
     349        self.gammaFunc = lambda x, gamma:((math.exp(gamma * math.log(2 * x - 1)) if x > 0.5 else -math.exp(gamma * math.log(-2 * x + 1)) if x != 0.5 else 0.0) + 1) / 2.0 
    348350        self.gamma = gamma 
    349351        self.overflow = overflow 
     
    369371                x = self.gammaFunc(x, gamma) 
    370372            return [(c2 - c1) * x + c1 for c1, c2 in [(red1, red2), (green1, green2), (blue1, blue2)]] 
    371          
     373 
    372374    def __call__(self, val, gamma=None): 
    373375        return self.get_rgb(val, gamma) 
    374      
     376 
    375377import math 
    376378 
    377379#from ColorPalette import ColorPalette 
    378      
     380 
    379381class GeneratorContextManager(object): 
    380382   def __init__(self, gen): 
     
    437439        with contextmanager(disabler)(): 
    438440            return func(*args, **kwargs) 
    439     return wrapper   
     441    return wrapper 
    440442 
    441443 
     
    446448class Renderer(object): 
    447449    render_state_attributes = ["font", "stroke_color", "fill_color", "render_hints", "transform", "gradient", "text_alignment"] 
    448      
     450 
    449451    ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER = range(3) 
    450        
     452 
    451453    def __init__(self, width, height): 
    452454        self.width = width 
     
    463465        self.render_state["render_hints"] = {} 
    464466        self.render_state_stack = [] 
    465          
     467 
    466468    def font(self): 
    467469        return self.render_state["font"] 
    468      
     470 
    469471    def set_font(self, family, size): 
    470472        self.render_state["font"] = family, size 
     
    472474    def fill_color(self): 
    473475        return self.render_state["fill_color"] 
    474      
     476 
    475477    def set_fill_color(self, color): 
    476478        self.render_state["fill_color"] = color 
    477          
     479 
    478480    def set_gradient(self, gradient): 
    479481        self.render_state["gradient"] = gradient 
    480          
     482 
    481483    def gradient(self): 
    482484        return self.render_state["gradient"] 
    483          
     485 
    484486    def stroke_color(self): 
    485487        return self.render_state["stroke_color"] 
    486      
     488 
    487489    def set_stroke_color(self, color): 
    488490        self.render_state["stroke_color"] = color 
    489      
     491 
    490492    def stroke_width(self): 
    491493        return self.render_state["stroke_width"] 
    492      
     494 
    493495    def set_stroke_width(self, width): 
    494496        self.render_state["stroke_width"] = width 
    495          
     497 
    496498    def set_text_alignment(self, align): 
    497499        self.render_state["text_alignment"] = align 
    498          
     500 
    499501    def text_alignment(self): 
    500502        return self.render_state["text_alignment"] 
    501          
     503 
    502504    def transform(self): 
    503505        return self.render_state["transform"] 
    504      
     506 
    505507    def set_transform(self, transform): 
    506508        self.render_state["transform"] = transform 
    507          
     509 
    508510    def render_hints(self): 
    509511        return self.render_state["render_hints"] 
    510      
     512 
    511513    def set_render_hints(self, hints): 
    512514        self.render_state["render_hints"].update(hints) 
    513      
     515 
    514516    def save_render_state(self): 
    515517        import copy 
    516518        self.render_state_stack.append(copy.deepcopy(self.render_state)) 
    517      
     519 
    518520    def restore_render_state(self): 
    519521        self.render_state = self.render_state_stack.pop(-1) 
    520          
     522 
    521523    def apply_transform(self, transform): 
    522524        self.render_state["transform"] = self.render_state["transform"] * transform 
    523           
     525 
    524526    def translate(self, x, y): 
    525527        transform = numpy.eye(3) 
    526528        transform[:, 2] = x, y, 1 
    527529        self.apply_transform(transform) 
    528      
     530 
    529531    def rotate(self, angle): 
    530532        angle *= 2 * math.pi / 360.0 
     
    532534        transform[:2, :2] = [[math.cos(angle), -math.sin(angle)], [math.sin(angle), math.cos(angle)]] 
    533535        self.apply_transform(transform) 
    534      
     536 
    535537    def scale(self, sx, sy): 
    536538        transform = numpy.eye(3) 
    537         transform[(0, 1), (0, 1)] = sx, sy  
     539        transform[(0, 1), (0, 1)] = sx, sy 
    538540        self.apply_transform(transform) 
    539          
     541 
    540542    def skew(self, sx, sy): 
    541543        transform = numpy.eye(3) 
    542544        transform[(1, 0), (0, 1)] = numpy.array([sx, sy]) * 2 * math.pi / 360.0 
    543545        self.apply_transform(transform) 
    544      
     546 
    545547    def draw_line(self, sx, sy, ex, ey, **kwargs): 
    546548        raise NotImplemented 
    547      
     549 
    548550    def draw_lines(self, points, **kwargs): 
    549551        raise NotImplemented 
    550      
     552 
    551553    def draw_rect(self, x, y, w, h, **kwargs): 
    552554        raise NotImplemented 
    553      
     555 
    554556    def draw_polygon(self, vertices, **kwargs): 
    555557        raise NotImplemented 
     
    557559    def draw_arch(self, something, **kwargs): 
    558560        raise NotImplemented 
    559      
     561 
    560562    def draw_text(self, x, y, text, **kwargs): 
    561563        raise NotImplemented 
    562      
     564 
    563565    def string_size_hint(self, text, **kwargs): 
    564566        raise NotImpemented 
    565      
     567 
    566568    @contextmanager 
    567569    def state(self, **kwargs): 
     
    576578        finally: 
    577579            self.restore_render_state() 
    578              
     580 
    579581    def save(self): 
    580582        raise NotImplemented 
    581      
     583 
    582584    def close(self, file): 
    583585        pass 
    584      
     586 
    585587class EPSRenderer(Renderer): 
    586588    EPS_DRAW_RECT = """/draw_rect  
     
    594596 closepath 
    595597} def""" 
    596      
     598 
    597599    EPS_SET_GRADIENT = """<< /PatternType 2 
    598600 /Shading 
     
    642644                                 fill_color=lambda color:"%f %f %f setrgbcolor" % tuple(255.0 / c for c in color), 
    643645                                 stroke_width=lambda w: "%f setlinewidth" % w) 
    644          
     646 
    645647    def set_font(self, family, size): 
    646648        Renderer.set_font(self, family, size) 
    647649        self._eps.write("/%s findfont %f scalefont setfont\n" % self.font()) 
    648          
     650 
    649651    def set_fill_color(self, color): 
    650652        Renderer.set_fill_color(self, color) 
    651         self._eps.write("%f %f %f setrgbcolor\n" % tuple(c/255.0 for c in color)) 
    652          
     653        self._eps.write("%f %f %f setrgbcolor\n" % tuple(c / 255.0 for c in color)) 
     654 
    653655    def set_gradient(self, gradient): 
    654656        Renderer.set_gradient(self, gradient) 
     
    656658        binary = "".join([chr(int(c)) for p, s in samples for c in s]) 
    657659        import binascii 
    658         self._eps.write(self.EPS_SET_GRADIENT % (x1, y1, x2, y2, len(samples), binascii.hexlify(binary)))  
    659          
     660        self._eps.write(self.EPS_SET_GRADIENT % (x1, y1, x2, y2, len(samples), binascii.hexlify(binary))) 
     661 
    660662    def set_stroke_color(self, color): 
    661663        Renderer.set_stroke_color(self, color) 
    662         self._eps.write("%f %f %f setrgbcolor\n" % tuple(c/255.0 for c in color)) 
    663          
     664        self._eps.write("%f %f %f setrgbcolor\n" % tuple(c / 255.0 for c in color)) 
     665 
    664666    def set_stroke_width(self, width): 
    665667        Renderer.set_stroke_width(self, width) 
    666668        self._eps.write("%f setlinewidth\n" % width) 
    667          
     669 
    668670    def set_render_hints(self, hints): 
    669671        Renderer.set_render_hints(self, hints) 
     
    671673            map = {"butt":0, "round":1, "rect":2} 
    672674            self._eps.write("%i setlinecap\n" % (map.get(hints.get("linecap"), 0))) 
    673         
    674     @with_state  
     675 
     676    @with_state 
    675677    def draw_line(self, sx, sy, ex, ey, **kwargs): 
    676678        self._eps.write("newpath\n%f %f moveto %f %f lineto\nstroke\n" % (sx, -sy, ex, -ey)) 
    677          
     679 
    678680    @with_state 
    679681    def draw_rect(self, x, y, w, h, **kwargs): 
    680         self._eps.write("newpath\n%(x)f %(y)f moveto %(w)f 0 rlineto\n0 %(h)f rlineto %(w)f neg 0 rlineto\nclosepath\n" % dict(x=x,y=-y, w=w, h=-h)) 
     682        self._eps.write("newpath\n%(x)f %(y)f moveto %(w)f 0 rlineto\n0 %(h)f rlineto %(w)f neg 0 rlineto\nclosepath\n" % dict(x=x, y= -y, w=w, h= -h)) 
    681683        self._eps.write("gsave\n") 
    682684        if self.gradient(): 
     
    687689        self.set_stroke_color(self.stroke_color()) 
    688690        self._eps.write("stroke\n") 
    689          
     691 
    690692    @with_state 
    691693    def draw_polygon(self, vertices, **kwargs): 
     
    699701        self.set_stroke_color(self.stroke_color()) 
    700702        self._eps.write("stroke\n") 
    701          
     703 
    702704    @with_state 
    703705    def draw_text(self, x, y, text, **kwargs): 
    704706        show = ["show", "right_align_show", "center_align_show"][self.text_alignment()] 
    705707        self._eps.write("%f %f moveto (%s) %s\n" % (x, -y, text, show)) 
    706          
     708 
    707709    def save_render_state(self): 
    708710        Renderer.save_render_state(self) 
    709711        self._eps.write("gsave\n") 
    710          
     712 
    711713    def restore_render_state(self): 
    712714        Renderer.restore_render_state(self) 
    713715        self._eps.write("grestore\n") 
    714          
     716 
    715717    def translate(self, dx, dy): 
    716718        Renderer.translate(self, dx, dy) 
    717719        self._eps.write("%f %f translate\n" % (dx, -dy)) 
    718          
     720 
    719721    def rotate(self, angle): 
    720722        Renderer.rotate(self, angle) 
    721723        self._eps.write("%f rotate\n" % -angle) 
    722          
     724 
    723725    def scale(self, sx, sy): 
    724726        Renderer.scale(self, sx, sy) 
    725727        self._eps.write("%f %f scale\n" % (sx, sy)) 
    726      
     728 
    727729    def skew(self, sx, sy): 
    728730        Renderer.skew(self, sx, sy) 
    729731        self._eps.write("%f %f skew\n" % (sx, sy)) 
    730          
     732 
    731733    def save(self, filename): 
    732734#        self._eps.close() 
    733735        open(filename, "wb").write(self._eps.getvalue()) 
    734          
     736 
    735737    def string_size_hint(self, text, **kwargs): 
    736738        import warnings 
    737739        warnings.warn("EpsRenderer class does not suport exact string width estimation", stacklevel=2) 
    738740        return len(text) * self.font()[1] 
    739          
    740          
     741 
     742 
    741743class PILRenderer(Renderer): 
    742744    def __init__(self, width, height): 
     
    744746        import Image, ImageDraw, ImageFont 
    745747        self._pil_image = Image.new("RGB", (width, height), (255, 255, 255)) 
    746         self._draw =  ImageDraw.Draw(self._pil_image, "RGB") 
     748        self._draw = ImageDraw.Draw(self._pil_image, "RGB") 
    747749        self._pil_font = ImageFont.load_default() 
    748750 
     
    750752        p = self.transform() * [[x], [y], [1]] 
    751753        return p[0, 0], p[1, 0] 
    752      
     754 
    753755    def set_font(self, family, size): 
    754756        Renderer.set_font(self, family, size) 
    755757        import ImageFont 
    756758        try: 
    757             self._pil_font = ImageFont.load(family + ".ttf", size) 
     759            font_file = os.path.join(install_dir, "utils", family + ".ttf") 
     760            if os.path.exists(font_file): 
     761                self._pil_font = ImageFont.truetype(font_file, int(size)) 
     762            else: 
     763                self._pil_font = ImageFont.truetype(family + ".ttf", int(size)) 
    758764        except Exception: 
    759765            import warnings 
    760766            warnings.warn("Could not load %s.ttf font!", stacklevel=2) 
    761767            try: 
    762                 self._pil_font = ImageFont.load("cour.ttf", size) 
     768                self._pil_font = ImageFont.truetype("cour.ttf", int(size)) 
    763769            except Exception: 
    764770                warnings.warn("Could not load the cour.ttf font!! Loading the default", stacklevel=2) 
    765771                self._pil_font = ImageFont.load_default() 
    766          
     772 
    767773    @with_state 
    768774    def draw_line(self, sx, sy, ex, ey, **kwargs): 
     
    775781        x1, y1 = self._transform(x, y) 
    776782        x2, y2 = self._transform(x + w, y + h) 
    777         self._draw.rectangle((x1, y1, x2 ,y2), fill=self.fill_color(), outline=self.stroke_color()) 
    778          
     783        self._draw.rectangle((x1, y1, x2 , y2), fill=self.fill_color(), outline=self.stroke_color()) 
     784 
    779785    @with_state 
    780786    def draw_text(self, x, y, text, **kwargs): 
    781787        x, y = self._transform(x, y - self.font()[1]) 
    782788        self._draw.text((x, y), text, font=self._pil_font, fill=self.stroke_color()) 
    783          
     789 
    784790    def save(self, file): 
    785791        self._pil_image.save(file) 
    786          
     792 
    787793    def string_size_hint(self, text, **kwargs): 
    788794        return self._pil_font.getsize(text)[1] 
     
    804810        self._defs = StringIO.StringIO() 
    805811        self._gradients = {} 
    806          
     812 
    807813    def set_gradient(self, gradient): 
    808814        Renderer.set_gradient(self, gradient) 
     
    812818            (x1, y1, x2, y2), stops = gradient 
    813819            (x1, y1, x2, y2) = (0, 0, 100, 0) 
    814              
     820 
    815821            self._defs.write('<linearGradient id="%s" x1="%f%%" y1="%f%%" x2="%f%%" y2="%f%%">\n' % (id, x1, y1, x2, y2)) 
    816822            for offset, color in stops: 
    817823                self._defs.write('<stop offset="%f" style="stop-color:rgb(%i, %i, %i); stop-opacity:1"/>\n' % ((offset,) + color)) 
    818824            self._defs.write('</linearGradient>\n') 
    819          
     825 
    820826    def get_fill(self): 
    821827        if self.render_state["gradient"]: 
     
    823829        else: 
    824830            return 'fill="rgb(%i %i %i)"' % self.fill_color() 
    825          
     831 
    826832    def get_stroke(self): 
    827833#        if self.render_state["gradient"]: 
     
    829835#        else: 
    830836            return 'stroke="rgb(%i, %i, %i)"' % self.stroke_color() + ' stroke-width="%f"' % self.stroke_width() 
    831          
     837 
    832838    def get_text_alignment(self): 
    833839        return 'text-anchor="%s"' % (["start", "end", "middle"][self.text_alignment()]) 
    834      
     840 
    835841    def get_linecap(self): 
    836842        return 'stroke-linecap="%s"' % self.render_hints().get("linecap", "butt") 
    837          
     843 
    838844    @with_state 
    839845    def draw_line(self, sx, sy, ex, ey): 
    840846        self._svg.write('<line x1="%f" y1="%f" x2="%f" y2="%f" %s %s/>\n' % ((sx, sy, ex, ey) + (self.get_stroke(), self.get_linecap()))) 
    841          
     847 
    842848#    @with_state 
    843849#    def draw_lines(self): 
    844          
     850 
    845851    @with_state 
    846852    def draw_rect(self, x, y, w, h): 
    847853        self._svg.write('<rect x="%f" y="%f" width="%f" height="%f" %s %s/>\n' % ((x, y, w, h) + (self.get_fill(),) + (self.get_stroke(),))) 
    848              
     854 
    849855    @with_state 
    850856    def draw_polygon(self, vertices, **kwargs): 
     
    853859        path += " z" 
    854860        self._svg.write('<path d="%s" %s/>' % ((path,) + (self.get_stroke(),))) 
    855          
     861 
    856862    @with_state 
    857863    def draw_text(self, x, y, text): 
    858         self._svg.write('<text x="%f" y="%f" font-family="%s" font-size="%f" %s>%s</text>\n' % ((x, y) + self.font() +(self.get_text_alignment(), text))) 
    859          
     864        self._svg.write('<text x="%f" y="%f" font-family="%s" font-size="%f" %s>%s</text>\n' % ((x, y) + self.font() + (self.get_text_alignment(), text))) 
     865 
    860866    def translate(self, x, y): 
    861867        self._svg.write('<g transform="translate(%f,%f)">\n' % (x, y)) 
    862868        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    863          
     869 
    864870    def rotate(self, angle): 
    865871        self._svg.write('<g transform="rotate(%f)">\n' % angle) 
    866872        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    867          
     873 
    868874    def scale(self, sx, sy): 
    869875        self._svg.write('<g transform="scale(%f,%f)">\n' % (sx, sy)) 
    870876        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    871          
     877 
    872878    def skew(self, sx, sy): 
    873879        self._svg.write('<g transform="skewX(%f)">' % sx) 
     
    878884        Renderer.save_render_state(self) 
    879885        self.transform_count_stack.append(0) 
    880          
     886 
    881887    def restore_render_state(self): 
    882888        Renderer.restore_render_state(self) 
    883889        count = self.transform_count_stack.pop(-1) 
    884890        self._svg.write('</g>\n' * count) 
    885          
     891 
    886892    def save(self, filename): 
    887893        open(filename, "wb").write(self.SVG_HEADER % (self.height, self.width, self._defs.getvalue(), self._svg.getvalue())) 
    888          
     894 
    889895class CairoRenderer(Renderer): 
    890896    def __init__(self, width, height): 
    891897        Renderer.__init__(self, width, height) 
    892          
     898 
  • Orange/regression/linear.py

    r10605 r10643  
    134134    from Orange import statc as stats 
    135135 
    136 from numpy import dot, sqrt 
     136from numpy import dot, sqrt, std 
    137137from numpy.linalg import inv, pinv 
    138138 
     
    148148    before fitting the regression parameters. 
    149149 
    150     """     
     150    """ 
    151151 
    152152    def __init__(self, name='linear regression', intercept=True, 
     
    197197        self.use_vars = use_vars 
    198198        self.__dict__.update(kwds) 
    199          
     199 
    200200    def __call__(self, table, weight=None, verbose=0): 
    201201        """ 
     
    203203        :type table: :class:`Orange.data.Table` 
    204204        :param weight: the weights for instances. Default: None, i.e. 
    205             all data instances are eqaully important in fitting 
     205            all data instances are equally important in fitting 
    206206            the regression parameters 
    207207        :type weight: None or list of Orange.feature.Continuous 
    208208            which stores weights for instances 
    209         """        
    210         if not self.use_vars is None: 
     209        """ 
     210        if self.use_vars is not None: 
    211211            new_domain = Orange.data.Domain(self.use_vars, 
    212212                                            table.domain.class_var) 
     
    214214            table = Orange.data.Table(new_domain, table) 
    215215 
    216         # dicrete values are continuized         
     216        # discrete values are continuized 
    217217        table = self.continuize_table(table) 
    218            
     218 
    219219        # missing values are imputed 
    220220        table = self.impute_table(table) 
     
    227227            table = Orange.data.Table(new_domain, table) 
    228228 
    229         # convertion to numpy 
    230         A, y, w = table.to_numpy() 
    231         n, m = numpy.shape(A) 
    232       
     229        domain = table.domain 
     230 
     231        # convert to numpy 
     232        X, y, w = table.to_numpy() 
     233        n, m = numpy.shape(X) 
     234 
    233235        if self.intercept: 
    234             X = numpy.insert(A, 0, 1, axis=1) # adds a column of ones 
    235         else: 
    236             X = A 
    237               
    238         domain = table.domain 
    239          
     236            X = numpy.insert(X, 0, 1, axis=1) # adds a column of ones 
     237 
    240238        if weight: 
    241239            weights = numpy.sqrt([float(ins[weight]) for ins in table]) 
    242240            X = weights.reshape(n, 1) * X 
    243241            y = weights * y 
    244          
     242 
    245243        cov = dot(X.T, X) 
    246          
     244 
    247245        if self.ridge_lambda: 
    248246            stride = cov.shape[0] + 1 
     
    257255        mu_y, sigma_y = numpy.mean(y), numpy.std(y) 
    258256        if m > 0: 
    259             cov_x = numpy.cov(X, rowvar=0) 
    260257            # standardized coefficients 
    261             std_coefficients = sqrt(cov_x.diagonal()) / sigma_y * coefficients 
     258            std_coefficients = std(X, axis=0, ddof=1) / sigma_y * coefficients 
    262259        else: 
    263260            std_coefficients = None 
     
    268265                coefficients=coefficients, std_coefficients=std_coefficients, 
    269266                intercept=self.intercept) 
    270              
    271267 
    272268        fitted = dot(X, coefficients) 
     
    274270                     for i, ins in enumerate(table)] 
    275271 
    276         # model summary         
     272        # model summary 
     273        df_reg = n - m - self.intercept 
    277274        # total sum of squares (total variance) 
    278275        sst = numpy.sum((y - mu_y) ** 2) 
    279         # sum of squares due to regression (explained variance) 
     276        # regression sum of squares (explained variance) 
    280277        ssr = numpy.sum((fitted - mu_y) ** 2) 
    281         # error sum of squares (unexplaied variance) 
    282         sse = sst - ssr 
     278        # residual sum of squares 
     279        sse = numpy.sum((y - fitted) ** 2) 
    283280        # coefficient of determination 
    284281        r2 = ssr / sst 
    285         r2adj = 1 - (1 - r2) * (n - 1) / (n - m - 1) 
    286         F = (ssr / m) / (sst - ssr / (n - m - 1)) if m else None 
    287         df = n - 2 
    288         sigma_square = sse / (n - m - 1) 
     282        r2 = 1 - sse / sst 
     283        r2adj = 1 - (1 - r2) * (n - 1) / df_reg 
     284        F = (ssr / m) / ((sst - ssr) / df_reg) if m else 0 
     285        sigma_square = sse / df_reg 
    289286        # standard error of the regression estimator, t-scores and p-values 
    290287        std_error = sqrt(sigma_square * invcov.diagonal()) 
    291288        t_scores = coefficients / std_error 
    292         p_vals = [stats.betai(df * 0.5, 0.5, df / (df + t * t)) 
     289        df_res = n - 2 
     290        p_vals = [stats.betai(df_res * 0.5, 0.5, df_res / (df_res + t * t)) 
    293291                  for t in t_scores] 
    294292 
     
    299297            dict_model["Intercept"] = (coefficients[0], std_error[0], 
    300298                                       t_scores[0], p_vals[0]) 
    301         for i, var in enumerate(domain.attributes): 
     299        for i, var in enumerate(domain.features): 
    302300            j = i + 1 if self.intercept else i 
    303301            dict_model[var.name] = (coefficients[j], std_error[j], 
    304302                                    t_scores[j], p_vals[j]) 
    305          
     303 
    306304        return LinearRegression(domain.class_var, domain, coefficients, F, 
    307305                 std_error=std_error, t_scores=t_scores, p_vals=p_vals, 
     
    326324 
    327325    .. attribute:: F 
    328      
     326 
    329327        F-statistics of the model. 
    330328 
     
    336334    .. attribute:: std_error 
    337335 
    338         Standard errors of the coefficient estimator, stored in list.     
     336        Standard errors of the coefficient estimator, stored in list. 
    339337 
    340338    .. attribute:: t_scores 
    341339 
    342         List of t-scores for the estimated regression coefficients.     
     340        List of t-scores for the estimated regression coefficients. 
    343341 
    344342    .. attribute:: p_vals 
     
    346344        List of p-values for the null hypothesis that the regression 
    347345        coefficients equal 0 based on t-scores and two sided 
    348         alternative hypothesis.     
     346        alternative hypothesis. 
    349347 
    350348    .. attribute:: dict_model 
     
    367365    .. attribute:: m 
    368366 
    369         Number of independent (predictor) variables.     
     367        Number of independent (predictor) variables. 
    370368 
    371369    .. attribute:: n 
    372370 
    373         Number of instances.     
     371        Number of instances. 
    374372 
    375373    .. attribute:: mu_y 
    376374 
    377         Sample mean of the dependent variable.     
     375        Sample mean of the dependent variable. 
    378376 
    379377    .. attribute:: r2 
     
    396394        Standardized regression coefficients. 
    397395 
    398     """    
    399  
    400  
    401      
     396    """ 
     397 
    402398    def __init__(self, class_var=None, domain=None, coefficients=None, F=None, 
    403399                 std_error=None, t_scores=None, p_vals=None, dict_model=None, 
     
    436432                         variable will be predicted 
    437433        :type instance: :obj:`~Orange.data.Instance` 
    438         """         
     434        """ 
    439435        ins = Orange.data.Instance(self.domain, instance) 
    440436        ins = numpy.array(ins.native()) 
     
    465461        return (y_hat, dist) 
    466462 
    467  
    468463    def to_string(self): 
    469464        """Pretty-prints linear regression model, 
     
    472467 
    473468        """ 
    474         from string import join  
     469        from string import join 
    475470        labels = ('Variable', 'Coeff Est', 'Std Error', 't-value', 'p') 
    476471        lines = [join(['%10s' % l for l in labels], ' ')] 
     
    485480            elif p < 0.1: return  "." 
    486481            else: return " " 
    487          
     482 
    488483        if self.intercept == True: 
    489484            stars =  get_star(self.p_vals[0]) 
     
    515510 
    516511    :param c1, c2: linear regression model objects. 
    517     :type lr: :class:`LinearRegression`      
     512    :type lr: :class:`LinearRegression` 
    518513 
    519514    """ 
     
    551546    """ 
    552547 
    553      
    554548    inc_vars = [] 
    555549    not_inc_vars = table.domain.attributes 
     
    568562            except Exception: 
    569563                reduced_model.append(None) 
    570          
     564 
    571565        sigs = [compare_models(r, c0) for r in reduced_model] 
    572566        if sigs and max(sigs) > remove_sig: 
     
    587581            except Exception: 
    588582                extended_model.append(None) 
    589               
     583 
    590584        sigs = [compare_models(c0, r) for r in extended_model] 
    591585        if sigs and min(sigs) < add_sig: 
  • Orange/testing/regression/results_reference/ensemble-forest.py.txt

    r9954 r10635  
    11Classification: bupa.tab 
    22Learner  CA     Brier  AUC 
    3 tree     0.588  0.823  0.578 
     3tree     0.591  0.817  0.570 
    44forest   0.704  0.406  0.751 
    55Regression: housing.tab 
    66Learner  MSE    RSE    R2 
    7 tree     23.113  0.274  0.726 
     7tree     21.685  0.257  0.743 
    88forest   15.225  0.180  0.820 
  • Orange/testing/regression/tests/test_auc.py

    r10175 r10633  
    1010        prob = [random.random() for _ in data.domain.class_var.values] 
    1111        sprob = sum(prob) 
    12         prob = [i/sprob for i in prob] 
     12        prob = [i / sprob for i in prob] 
    1313        distribution.Discrete(prob) 
    1414        return data.domain.class_var[0], prob 
     
    3838measures = ( 
    3939    (lambda x:auc(x), "AUC"), 
    40     (lambda x:auc(x, method=0), "AUC+M0"), 
    41     (lambda x:auc(x, method=1), "AUC+M1"), 
    42     (lambda x:auc(x, method=2), "AUC+M2"), 
    43     (lambda x:auc(x, method=3), "AUC+M3"), 
     40    (lambda x:auc(x, multiclass=0), "AUC+M0"), 
     41    (lambda x:auc(x, multiclass=1), "AUC+M1"), 
     42    (lambda x:auc(x, multiclass=2), "AUC+M2"), 
     43    (lambda x:auc(x, multiclass=3), "AUC+M3"), 
    4444) 
    4545 
    4646tests = ( 
    47     (lambda l, ds: testing.cross_validation([l],ds), "CV"), 
     47    (lambda l, ds: testing.cross_validation([l], ds), "CV"), 
    4848    (lambda l, ds: testing.proportion_test([l], ds, .7, 1), "Proportion test"), 
    4949) 
  • Orange/testing/regression/xtest_one.py

    r10291 r10634  
    44import os as t__os 
    55 
     6from Orange.core import AttributeWarning 
     7 
    68#ignore warnings 
    79import warnings as t__warnings 
    8 t__warnings.simplefilter("ignore") 
     10t__warnings.filterwarnings("ignore", "", AttributeWarning) 
     11 
     12#from numpy import seterr 
     13#seterr(all='raise') 
    914 
    1015NO_RANDOMNESS = 1 # prevent random parts of scripts to run 
     
    7984t__iterations = int(t__sys.argv[2]) 
    8085t__outputsdir = t__sys.argv[3] 
     86 
     87# when testing backward compatibility support suppress deprecation warnings 
     88if "tests_20" in t__outputsdir or "tutorial" in t__outputsdir: 
     89    t__warnings.filterwarnings("ignore", category=DeprecationWarning) 
    8190 
    8291t__timedoutname, t__crashname, t__errorname, t__newname, t__changedname, t__random1name, t__random2name = ["%s/%s.%s.%s.%s.txt" % (t__outputsdir, t__name, t__sys.platform, t__sys.version[:3], t) for t in ["timedout", "crash", "error", "new", "changed", "random1", "random2"]] 
  • Orange/testing/unit/tests/test_svm.py

    r10584 r10641  
     1try: 
     2    import unittest2 as unittest 
     3except: 
     4    import unittest 
     5     
    16import Orange 
    2 from Orange.classification.svm import SVMLearner, MeasureAttribute_SVMWeights,\ 
    3                             LinearLearner, RFE, get_linear_svm_weights, \ 
     7from Orange.classification.svm import SVMLearner, SVMLearnerSparse, \ 
     8                            ScoreSVMWeights, LinearLearner, RFE, \ 
     9                            get_linear_svm_weights, \ 
    410                            example_weighted_sum 
    5                              
     11from Orange.classification import svm                             
    612from Orange.classification.svm.kernels import BagOfWords, RBFKernelWrapper 
    713from Orange.misc import testing 
     
    1420import numpy as np 
    1521 
    16 def multiclass_from1sv1(dec_values, class_var): 
     22def multiclass_from1vs1(dec_values, class_var): 
    1723    n_class = len(class_var.values) 
    1824    votes = [0] * n_class 
     
    5965            prediction_1 = classifier_no_prob(inst) 
    6066            d_val = classifier_no_prob.get_decision_values(inst) 
    61             prediciton_2 = multiclass_from1sv1(d_val, classifier_no_prob.class_var) 
     67            prediciton_2 = multiclass_from1vs1(d_val, classifier_no_prob.class_var) 
    6268            self.assertEqual(prediction_1, prediciton_2) 
    6369             
     
    7480         
    7581     
    76     @test_on_datasets(datasets=testing.CLASSIFICATION_DATASETS + ["zoo"]) 
    77     def test_linear_weights_on(self, dataset): 
     82    # Don't test on "monks" the coefs are really large and 
     83    @test_on_datasets(datasets=["iris", "brown-selected", "lenses", "zoo"]) 
     84    def test_linear_classifier_weights_on(self, dataset): 
    7885        # Test get_linear_svm_weights 
    7986        classifier = self.LEARNER(dataset) 
     
    9097                     
    9198        l_map = classifier._get_libsvm_labels_map() 
    92         # Would need to map the rho values 
    93         if l_map == sorted(l_map): 
    94             for inst in dataset[:20]: 
    95                 dec_values = classifier.get_decision_values(inst) 
    96                  
    97                 for dec_v, weight, rho, pair in zip(dec_values, weights, 
    98                                         classifier.rho, class_pairs(n_class)): 
    99                     t_inst = Orange.data.Instance(classifier.domain, inst)                     
    100                     dec_v1 = example_weighted_sum(t_inst, weight) - rho 
    101                     self.assertAlmostEqual(dec_v, dec_v1, 4) 
    102          
    103          
     99     
     100        for inst in dataset[:20]: 
     101            dec_values = classifier.get_decision_values(inst) 
     102             
     103            for dec_v, weight, rho, pair in zip(dec_values, weights, 
     104                                    classifier.rho, class_pairs(n_class)): 
     105                t_inst = Orange.data.Instance(classifier.domain, inst)                     
     106                dec_v1 = example_weighted_sum(t_inst, weight) - rho 
     107                self.assertAlmostEqual(dec_v, dec_v1, 4) 
     108                     
     109    @test_on_datasets(datasets=testing.REGRESSION_DATASETS) 
     110    def test_linear_regression_weights_on(self, dataset): 
     111        predictor = self.LEARNER(dataset) 
     112        weights = get_linear_svm_weights(predictor) 
     113         
     114        for inst in dataset[:20]: 
     115            t_inst = Orange.data.Instance(predictor.domain, inst) 
     116            prediction = predictor(inst) 
     117            w_sum = example_weighted_sum(t_inst, weights) 
     118            self.assertAlmostEqual(float(prediction),  
     119                                   w_sum - predictor.rho[0], 
     120                                   places=4) 
     121         
     122 
    104123@datasets_driven(datasets=datasets) 
    105124class PolySVMTestCase(testing.LearnerTestCase): 
     
    133152 
    134153 
    135 #def to_sparse(data): 
    136 #    domain = Orange.data.Domain([], data.domain.class_var) 
    137 #    domain.add_metas(dict([(Orange.core.newmetaid(), v) for v in data.domain.attributes])) 
    138 #    return Orange.data.Table(domain, data) 
    139 # 
    140 #def sparse_data_iter(): 
    141 #    for name, (data, ) in testing.datasets_iter(datasets): 
    142 #        yield name, (to_sparse(data), ) 
    143 #     
    144 ## This needs sparse datasets.  
    145 #@testing.data_driven(data_iter=sparse_data_iter()) 
    146 #class BagOfWordsSVMTestCase(testing.LearnerTestCase): 
    147 #    LEARNER = SVMLearner(name="svm-bow", kernel_type=SVMLearner.Custom, kernelFunc=BagOfWords()) 
    148  
    149  
     154def to_sparse(data): 
     155    domain = Orange.data.Domain([], data.domain.class_var) 
     156    domain.add_metas(dict([(Orange.core.newmetaid(), v) for v in data.domain.attributes])) 
     157    return Orange.data.Table(domain, data) 
     158 
     159def sparse_data_iter(): 
     160    for name, (data, ) in testing.datasets_iter(datasets): 
     161        yield name, (to_sparse(data), ) 
     162 
     163@testing.data_driven(data_iter=sparse_data_iter()) 
     164class SparseSVMTestCase(testing.LearnerTestCase): 
     165    LEARNER = SVMLearnerSparse(name="svm-sparse") 
     166     
     167    @test_on_data 
     168    def test_learner_on(self, dataset): 
     169        testing.LearnerTestCase.test_learner_on(self, dataset) 
     170        svm_test_binary_classifier(self, dataset) 
     171 
     172  
    150173@datasets_driven(datasets=datasets) 
    151174class CustomWrapperSVMTestCase(testing.LearnerTestCase): 
     
    173196 
    174197@datasets_driven(datasets=datasets) 
    175 class TestMeasureAttr_LinWeights(testing.MeasureAttributeTestCase): 
    176     MEASURE = MeasureAttribute_SVMWeights() 
    177  
     198class TestScoreSVMWeights(testing.MeasureAttributeTestCase): 
     199    MEASURE = ScoreSVMWeights() 
     200     
    178201 
    179202@datasets_driven(datasets=["iris"]) 
     
    194217        copy = cPickle.loads(cPickle.dumps(rfe)) 
    195218 
     219 
    196220if __name__ == "__main__": 
    197     try: 
    198         import unittest2 as unittest 
    199     except: 
    200         import unittest 
    201221    unittest.main() 
  • Orange/utils/render.py

    r10582 r10633  
    1414import numpy 
    1515import math 
    16  
     16import os.path 
     17 
     18from Orange.utils.environ import install_dir 
    1719 
    1820class GeneratorContextManager(object): 
     
    8284    def __init__(self, colors, gamma=None, overflow=(255, 255, 255), underflow=(255, 255, 255), unknown=(0, 0, 0)): 
    8385        self.colors = colors 
    84         self.gamma_func = lambda x, gamma:((math.exp(gamma*math.log(2*x-1)) if x > 0.5 else -math.exp(gamma*math.log(-2*x+1)) if x!=0.5 else 0.0)+1)/2.0 
     86        self.gamma_func = lambda x, gamma:((math.exp(gamma * math.log(2 * x - 1)) if x > 0.5 else -math.exp(gamma * math.log(-2 * x + 1)) if x != 0.5 else 0.0) + 1) / 2.0 
    8587        self.gamma = gamma 
    8688        self.overflow = overflow 
     
    106108                x = self.gamma_func(x, gamma) 
    107109            return [(c2 - c1) * x + c1 for c1, c2 in [(red1, red2), (green1, green2), (blue1, blue2)]] 
    108          
     110 
    109111    def __call__(self, val, gamma=None): 
    110112        return self.get_rgb(val, gamma) 
    111      
     113 
    112114def as_open_file(file, mode="rb"): 
    113115    if isinstance(file, basestring): 
     
    119121class Renderer(object): 
    120122    render_state_attributes = ["font", "stroke_color", "fill_color", "render_hints", "transform", "gradient", "text_alignment"] 
    121      
     123 
    122124    ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER = range(3) 
    123        
     125 
    124126    def __init__(self, width, height): 
    125127        self.width = width 
     
    136138        self.render_state["render_hints"] = {} 
    137139        self.render_state_stack = [] 
    138          
     140 
    139141    def font(self): 
    140142        return self.render_state["font"] 
    141      
     143 
    142144    def set_font(self, family, size): 
    143145        self.render_state["font"] = family, size 
     
    145147    def fill_color(self): 
    146148        return self.render_state["fill_color"] 
    147      
     149 
    148150    def set_fill_color(self, color): 
    149151        self.render_state["fill_color"] = color 
    150          
     152 
    151153    def set_gradient(self, gradient): 
    152154        self.render_state["gradient"] = gradient 
    153          
     155 
    154156    def gradient(self): 
    155157        return self.render_state["gradient"] 
    156          
     158 
    157159    def stroke_color(self): 
    158160        return self.render_state["stroke_color"] 
    159      
     161 
    160162    def set_stroke_color(self, color): 
    161163        self.render_state["stroke_color"] = color 
    162      
     164 
    163165    def stroke_width(self): 
    164166        return self.render_state["stroke_width"] 
    165      
     167 
    166168    def set_stroke_width(self, width): 
    167169        self.render_state["stroke_width"] = width 
    168          
     170 
    169171    def set_text_alignment(self, align): 
    170172        self.render_state["text_alignment"] = align 
    171          
     173 
    172174    def text_alignment(self): 
    173175        return self.render_state["text_alignment"] 
    174          
     176 
    175177    def transform(self): 
    176178        return self.render_state["transform"] 
    177      
     179 
    178180    def set_transform(self, transform): 
    179181        self.render_state["transform"] = transform 
    180          
     182 
    181183    def render_hints(self): 
    182184        return self.render_state["render_hints"] 
    183      
     185 
    184186    def set_render_hints(self, hints): 
    185187        self.render_state["render_hints"].update(hints) 
    186      
     188 
    187189    def save_render_state(self): 
    188190        import copy 
    189191        self.render_state_stack.append(copy.deepcopy(self.render_state)) 
    190      
     192 
    191193    def restore_render_state(self): 
    192194        self.render_state = self.render_state_stack.pop(-1) 
    193          
     195 
    194196    def apply_transform(self, transform): 
    195197        self.render_state["transform"] = self.render_state["transform"] * transform 
    196           
     198 
    197199    def translate(self, x, y): 
    198200        transform = numpy.eye(3) 
    199201        transform[:, 2] = x, y, 1 
    200202        self.apply_transform(transform) 
    201      
     203 
    202204    def rotate(self, angle): 
    203205        angle *= 2 * math.pi / 360.0 
     
    205207        transform[:2, :2] = [[math.cos(angle), -math.sin(angle)], [math.sin(angle), math.cos(angle)]] 
    206208        self.apply_transform(transform) 
    207      
     209 
    208210    def scale(self, sx, sy): 
    209211        transform = numpy.eye(3) 
    210         transform[(0, 1), (0, 1)] = sx, sy  
     212        transform[(0, 1), (0, 1)] = sx, sy 
    211213        self.apply_transform(transform) 
    212          
     214 
    213215    def skew(self, sx, sy): 
    214216        transform = numpy.eye(3) 
    215217        transform[(1, 0), (0, 1)] = numpy.array([sx, sy]) * 2 * math.pi / 360.0 
    216218        self.apply_transform(transform) 
    217      
     219 
    218220    def draw_line(self, sx, sy, ex, ey, **kwargs): 
    219221        raise NotImplementedError 
    220      
     222 
    221223    def draw_lines(self, points, **kwargs): 
    222224        raise NotImplementedError 
    223      
     225 
    224226    def draw_rect(self, x, y, w, h, **kwargs): 
    225227        raise NotImplementedError 
    226      
     228 
    227229    def draw_polygon(self, vertices, **kwargs): 
    228230        raise NotImplementedError 
     
    230232    def draw_arch(self, something, **kwargs): 
    231233        raise NotImplementedError 
    232      
     234 
    233235    def draw_text(self, x, y, text, **kwargs): 
    234236        raise NotImplementedError 
    235      
     237 
    236238    def string_size_hint(self, text, **kwargs): 
    237239        raise NotImpemented 
    238      
     240 
    239241    @contextmanager 
    240242    def state(self, **kwargs): 
     
    249251        finally: 
    250252            self.restore_render_state() 
    251              
     253 
    252254    def save(self, file): 
    253255        raise NotImplementedError 
    254      
     256 
    255257    def close(self, file): 
    256258        pass 
    257      
     259 
    258260class EPSRenderer(Renderer): 
    259261    EPS_DRAW_RECT = """/draw_rect  
     
    267269 closepath 
    268270} def""" 
    269      
     271 
    270272    EPS_SET_GRADIENT = """<< /PatternType 2 
    271273 /Shading 
     
    315317                                 fill_color=lambda color:"%f %f %f setrgbcolor" % tuple(255.0 / c for c in color), 
    316318                                 stroke_width=lambda w: "%f setlinewidth" % w) 
    317          
     319 
    318320    def set_font(self, family, size): 
    319321        Renderer.set_font(self, family, size) 
    320322        self._eps.write("/%s findfont %f scalefont setfont\n" % self.font()) 
    321          
     323 
    322324    def set_fill_color(self, color): 
    323325        Renderer.set_fill_color(self, color) 
    324         self._eps.write("%f %f %f setrgbcolor\n" % tuple(c/255.0 for c in color)) 
    325          
     326        self._eps.write("%f %f %f setrgbcolor\n" % tuple(c / 255.0 for c in color)) 
     327 
    326328    def set_gradient(self, gradient): 
    327329        Renderer.set_gradient(self, gradient) 
     
    329331        binary = "".join([chr(int(c)) for p, s in samples for c in s]) 
    330332        import binascii 
    331         self._eps.write(self.EPS_SET_GRADIENT % (x1, y1, x2, y2, len(samples), binascii.hexlify(binary)))  
    332          
     333        self._eps.write(self.EPS_SET_GRADIENT % (x1, y1, x2, y2, len(samples), binascii.hexlify(binary))) 
     334 
    333335    def set_stroke_color(self, color): 
    334336        Renderer.set_stroke_color(self, color) 
    335         self._eps.write("%f %f %f setrgbcolor\n" % tuple(c/255.0 for c in color)) 
    336          
     337        self._eps.write("%f %f %f setrgbcolor\n" % tuple(c / 255.0 for c in color)) 
     338 
    337339    def set_stroke_width(self, width): 
    338340        Renderer.set_stroke_width(self, width) 
    339341        self._eps.write("%f setlinewidth\n" % width) 
    340          
     342 
    341343    def set_render_hints(self, hints): 
    342344        Renderer.set_render_hints(self, hints) 
     
    344346            map = {"butt":0, "round":1, "rect":2} 
    345347            self._eps.write("%i setlinecap\n" % (map.get(hints.get("linecap"), 0))) 
    346         
    347     @with_state  
     348 
     349    @with_state 
    348350    def draw_line(self, sx, sy, ex, ey, **kwargs): 
    349351        self._eps.write("newpath\n%f %f moveto %f %f lineto\nstroke\n" % (sx, -sy, ex, -ey)) 
    350          
     352 
    351353    @with_state 
    352354    def draw_rect(self, x, y, w, h, **kwargs): 
    353         self._eps.write("newpath\n%(x)f %(y)f moveto %(w)f 0 rlineto\n0 %(h)f rlineto %(w)f neg 0 rlineto\nclosepath\n" % dict(x=x,y=-y, w=w, h=-h)) 
     355        self._eps.write("newpath\n%(x)f %(y)f moveto %(w)f 0 rlineto\n0 %(h)f rlineto %(w)f neg 0 rlineto\nclosepath\n" % dict(x=x, y= -y, w=w, h= -h)) 
    354356        self._eps.write("gsave\n") 
    355357        if self.gradient(): 
     
    360362        self.set_stroke_color(self.stroke_color()) 
    361363        self._eps.write("stroke\n") 
    362          
     364 
    363365    @with_state 
    364366    def draw_polygon(self, vertices, **kwargs): 
     
    372374        self.set_stroke_color(self.stroke_color()) 
    373375        self._eps.write("stroke\n") 
    374          
     376 
    375377    @with_state 
    376378    def draw_text(self, x, y, text, **kwargs): 
    377379        show = ["show", "right_align_show", "center_align_show"][self.text_alignment()] 
    378380        self._eps.write("%f %f moveto (%s) %s\n" % (x, -y, text, show)) 
    379          
     381 
    380382    def save_render_state(self): 
    381383        Renderer.save_render_state(self) 
    382384        self._eps.write("gsave\n") 
    383          
     385 
    384386    def restore_render_state(self): 
    385387        Renderer.restore_render_state(self) 
    386388        self._eps.write("grestore\n") 
    387          
     389 
    388390    def translate(self, dx, dy): 
    389391        Renderer.translate(self, dx, dy) 
    390392        self._eps.write("%f %f translate\n" % (dx, -dy)) 
    391          
     393 
    392394    def rotate(self, angle): 
    393395        Renderer.rotate(self, angle) 
    394396        self._eps.write("%f rotate\n" % -angle) 
    395          
     397 
    396398    def scale(self, sx, sy): 
    397399        Renderer.scale(self, sx, sy) 
    398400        self._eps.write("%f %f scale\n" % (sx, sy)) 
    399      
     401 
    400402    def skew(self, sx, sy): 
    401403        Renderer.skew(self, sx, sy) 
    402404        self._eps.write("%f %f skew\n" % (sx, sy)) 
    403          
     405 
    404406    def save(self, file): 
    405407        file = as_open_file(file, "wb") 
    406408        file.write(self._eps.getvalue()) 
    407          
     409 
    408410    def string_size_hint(self, text, **kwargs): 
    409411        import warnings 
    410412        warnings.warn("EpsRenderer class does not suport exact string width estimation", stacklevel=2) 
    411413        return len(text) * self.font()[1] 
    412          
     414 
    413415def _int_color(color): 
    414416    """ Transform the color tuple (with floats) to tuple with ints 
     
    422424        import Image, ImageDraw, ImageFont 
    423425        self._pil_image = Image.new("RGB", (int(width), int(height)), (255, 255, 255)) 
    424         self._draw =  ImageDraw.Draw(self._pil_image, "RGB") 
     426        self._draw = ImageDraw.Draw(self._pil_image, "RGB") 
    425427        self._pil_font = ImageFont.load_default() 
    426428 
     
    428430        p = self.transform() * [[x], [y], [1]] 
    429431        return p[0, 0], p[1, 0] 
    430      
     432 
    431433    def set_font(self, family, size): 
    432434        Renderer.set_font(self, family, size) 
    433435        import ImageFont 
    434436        try: 
    435             self._pil_font = ImageFont.load(family + ".ttf", size) 
     437            font_file = os.path.join(install_dir, "utils", family + ".ttf") 
     438            if os.path.exists(font_file): 
     439                self._pil_font = ImageFont.truetype(font_file, int(size)) 
     440            else: 
     441                self._pil_font = ImageFont.truetype(family + ".ttf", int(size)) 
    436442        except Exception: 
    437443            import warnings 
    438             warnings.warn("Could not load %s.ttf font!", stacklevel=2) 
     444            warnings.warn("Could not load %s.ttf font!" % family, stacklevel=2) 
    439445            try: 
    440                 self._pil_font = ImageFont.load("cour.ttf", size) 
     446                self._pil_font = ImageFont.truetype("cour.ttf", int(size)) 
    441447            except Exception: 
    442448                warnings.warn("Could not load the cour.ttf font!! Loading the default", stacklevel=2) 
    443449                self._pil_font = ImageFont.load_default() 
    444          
     450 
    445451    @with_state 
    446452    def draw_line(self, sx, sy, ex, ey, **kwargs): 
     
    454460        x1, y1 = self._transform(x, y) 
    455461        x2, y2 = self._transform(x + w, y + h) 
    456         self._draw.rectangle((x1, y1, x2 ,y2), fill=_int_color(self.fill_color()), 
     462        self._draw.rectangle((x1, y1, x2 , y2), fill=_int_color(self.fill_color()), 
    457463                             outline=_int_color(self.stroke_color())) 
    458          
     464 
    459465    @with_state 
    460466    def draw_text(self, x, y, text, **kwargs): 
     
    462468        self._draw.text((x, y), text, font=self._pil_font, 
    463469                        fill=_int_color(self.stroke_color())) 
    464          
     470 
    465471    def save(self, file, format=None): 
    466472        if isinstance(file, basestring): 
     
    469475            file = as_open_file(file, "wb") 
    470476            self._pil_image.save(file, format) 
    471          
     477 
    472478    def string_size_hint(self, text, **kwargs): 
    473479        return self._pil_font.getsize(text)[1] 
    474      
     480 
    475481 
    476482class SVGRenderer(Renderer): 
     
    490496        self._defs = StringIO.StringIO() 
    491497        self._gradients = {} 
    492          
     498 
    493499    def set_gradient(self, gradient): 
    494500        Renderer.set_gradient(self, gradient) 
     
    498504            (x1, y1, x2, y2), stops = gradient 
    499505            (x1, y1, x2, y2) = (0, 0, 100, 0) 
    500              
     506 
    501507            self._defs.write('<linearGradient id="%s" x1="%f%%" y1="%f%%" x2="%f%%" y2="%f%%">\n' % (id, x1, y1, x2, y2)) 
    502508            for offset, color in stops: 
    503509                self._defs.write('<stop offset="%f" style="stop-color:rgb(%i, %i, %i); stop-opacity:1"/>\n' % ((offset,) + color)) 
    504510            self._defs.write('</linearGradient>\n') 
    505          
     511 
    506512    def get_fill(self): 
    507513        if self.render_state["gradient"]: 
     
    509515        else: 
    510516            return 'fill="rgb(%i %i %i)"' % self.fill_color() 
    511          
     517 
    512518    def get_stroke(self): 
    513519#        if self.render_state["gradient"]: 
     
    515521#        else: 
    516522            return 'stroke="rgb(%i, %i, %i)"' % self.stroke_color() + ' stroke-width="%f"' % self.stroke_width() 
    517          
     523 
    518524    def get_text_alignment(self): 
    519525        return 'text-anchor="%s"' % (["start", "end", "middle"][self.text_alignment()]) 
    520      
     526 
    521527    def get_linecap(self): 
    522528        return 'stroke-linecap="%s"' % self.render_hints().get("linecap", "butt") 
    523          
     529 
    524530    @with_state 
    525531    def draw_line(self, sx, sy, ex, ey): 
    526532        self._svg.write('<line x1="%f" y1="%f" x2="%f" y2="%f" %s %s/>\n' % ((sx, sy, ex, ey) + (self.get_stroke(), self.get_linecap()))) 
    527          
     533 
    528534#    @with_state 
    529535#    def draw_lines(self): 
    530          
     536 
    531537    @with_state 
    532538    def draw_rect(self, x, y, w, h): 
    533539        self._svg.write('<rect x="%f" y="%f" width="%f" height="%f" %s %s/>\n' % ((x, y, w, h) + (self.get_fill(),) + (self.get_stroke(),))) 
    534              
     540 
    535541    @with_state 
    536542    def draw_polygon(self, vertices, **kwargs): 
     
    539545        path += " z" 
    540546        self._svg.write('<path d="%s" %s/>' % ((path,) + (self.get_stroke(),))) 
    541          
     547 
    542548    @with_state 
    543549    def draw_text(self, x, y, text): 
    544         self._svg.write('<text x="%f" y="%f" font-family="%s" font-size="%f" %s>%s</text>\n' % ((x, y) + self.font() +(self.get_text_alignment(), text))) 
    545          
     550        self._svg.write('<text x="%f" y="%f" font-family="%s" font-size="%f" %s>%s</text>\n' % ((x, y) + self.font() + (self.get_text_alignment(), text))) 
     551 
    546552    def translate(self, x, y): 
    547553        self._svg.write('<g transform="translate(%f,%f)">\n' % (x, y)) 
    548554        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    549          
     555 
    550556    def rotate(self, angle): 
    551557        self._svg.write('<g transform="rotate(%f)">\n' % angle) 
    552558        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    553          
     559 
    554560    def scale(self, sx, sy): 
    555561        self._svg.write('<g transform="scale(%f,%f)">\n' % (sx, sy)) 
    556562        self.transform_count_stack[-1] = self.transform_count_stack[-1] + 1 
    557          
     563 
    558564    def skew(self, sx, sy): 
    559565        self._svg.write('<g transform="skewX(%f)">' % sx) 
     
    564570        Renderer.save_render_state(self) 
    565571        self.transform_count_stack.append(0) 
    566          
     572 
    567573    def restore_render_state(self): 
    568574        Renderer.restore_render_state(self) 
    569575        count = self.transform_count_stack.pop(-1) 
    570576        self._svg.write('</g>\n' * count) 
    571          
     577 
    572578    def save(self, file): 
    573579        file = as_open_file(file, "wb") 
    574580        file.write(self.SVG_HEADER % (self.height, self.width, self._defs.getvalue(), self._svg.getvalue())) 
    575          
     581 
    576582class CairoRenderer(Renderer): 
    577583    def __init__(self, width, height): 
    578584        Renderer.__init__(self, width, height) 
    579          
     585 
  • docs/reference/rst/code/ensemble-forest.py

    r9823 r10633  
    88 
    99forest = Orange.ensemble.forest.RandomForestLearner(trees=50, name="forest") 
    10 tree = Orange.classification.tree.TreeLearner(minExamples=2, mForPrunning=2, \ 
    11                             sameMajorityPruning=True, name='tree') 
     10tree = Orange.classification.tree.TreeLearner(min_instances=2, m_pruning=2, \ 
     11                            same_majority_pruning=True, name='tree') 
    1212learners = [tree, forest] 
    1313 
     
    1818for i in range(len(learners)): 
    1919    print "%-8s %5.3f  %5.3f  %5.3f" % (learners[i].name, \ 
    20         Orange.evaluation.scoring.CA(results)[i],  
     20        Orange.evaluation.scoring.CA(results)[i], 
    2121        Orange.evaluation.scoring.Brier_score(results)[i], 
    2222        Orange.evaluation.scoring.AUC(results)[i]) 
  • docs/reference/rst/code/ensemble-forest2.py

    r9638 r10633  
    1010 
    1111tree = Orange.classification.tree.TreeLearner() 
    12 tree.minExamples = 5 
    13 tree.maxDepth = 5 
     12tree.min_instances = 5 
     13tree.max_depth = 5 
    1414 
    1515forest_learner = Orange.ensemble.forest.RandomForestLearner(base_learner=tree, trees=50, attributes=3)