Changeset 9503:e70b002076e2 in orange


Ignore:
Timestamp:
12/29/11 12:15:58 (2 years ago)
Author:
matija <matija.polajnar@…>
Branch:
default
Convert:
29b9fdcdeb48a621f38352499b1492537ca51534
Message:

Adapt testing.py to MLC.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/Orange/evaluation/testing.py

    r9502 r9503  
    22 
    33import Orange 
    4 from Orange.misc import demangle_examples, getobjectname, printVerbose, deprecated_keywords 
     4from Orange.misc import demangle_examples, getobjectname, printVerbose, deprecated_keywords, deprecated_members 
    55 
    66#### Data structures 
     7 
     8TEST_TYPE_SINGLE = 0 
     9TEST_TYPE_MLC = 1 
    710 
    811class TestedExample: 
     
    1720    """ 
    1821 
    19     def __init__(self, iterationNumber=None, actualClass=None, n=0, weight=1.0): 
    20         """ 
    21         :param iterationNumber: 
    22         :param actualClass: 
     22    @deprecated_keywords({"iterationNumber": "iteration_number", 
     23                          "actualClass": "actual_class"}) 
     24    def __init__(self, iteration_number=None, actual_class=None, n=0, weight=1.0): 
     25        """ 
     26        :param iteration_number: 
     27        :param actual_class: 
    2328        :param n: 
    2429        :param weight: 
     
    2631        self.classes = [None]*n 
    2732        self.probabilities = [None]*n 
    28         self.iterationNumber = iterationNumber 
    29         self.actualClass= actualClass 
     33        self.iterationNumber = iteration_number 
     34        self.actualClass= actual_class 
    3035        self.weight = weight 
    3136 
     
    3338        """Appends a new result (class and probability prediction by a single classifier) to the classes and probabilities field.""" 
    3439     
    35         if type(aclass.value)==float: 
     40        if type(aclass)==list: 
     41            self.classes.append(aclass) 
     42            self.probabilities.append(aprob) 
     43        elif type(aclass.value)==float: 
    3644            self.classes.append(float(aclass)) 
    3745            self.probabilities.append(aprob) 
     
    4250    def set_result(self, i, aclass, aprob): 
    4351        """Sets the result of the i-th classifier to the given values.""" 
    44         if type(aclass.value)==float: 
     52        if type(aclass)==list: 
     53            self.classes[i] = aclass 
     54            self.probabilities[i] = aprob 
     55        elif type(aclass.value)==float: 
    4556            self.classes[i] = float(aclass) 
    4657            self.probabilities[i] = aprob 
     
    6172    :var classifiers: A list of classifiers, one element for each repetition (eg. fold). Each element is a list 
    6273      of classifiers, one for each learner. This field is used only if storing is enabled by ``storeClassifiers=1``. 
    63     :var numberOfIterations: Number of iterations. This can be the number of folds (in cross validation) 
     74    :var number_of_iterations: Number of iterations. This can be the number of folds (in cross validation) 
    6475      or the number of repetitions of some test. ``TestedExample``'s attribute ``iterationNumber`` should 
    65       be in range ``[0, numberOfIterations-1]``. 
    66     :var numberOfLearners: Number of learners. Lengths of lists classes and probabilities in each :obj:`TestedExample` 
    67       should equal ``numberOfLearners``. 
     76      be in range ``[0, number_of_iterations-1]``. 
     77    :var number_of_learners: Number of learners. Lengths of lists classes and probabilities in each :obj:`TestedExample` 
     78      should equal ``number_of_learners``. 
    6879    :var loaded: If the experimental method supports caching and there are no obstacles for caching (such as unknown 
    6980      random seeds), this is a list of boolean values. Each element corresponds to a classifier and tells whether the 
     
    7384      testing examples but you would like to ignore the weights in statistics. 
    7485    """ 
    75     def __init__(self, iterations, classifierNames, classValues=None, weights=None, baseClass=-1, domain=None, **argkw): 
    76         self.classValues = classValues 
    77         self.classifierNames = classifierNames 
    78         self.numberOfIterations = iterations 
    79         self.numberOfLearners = len(classifierNames) 
     86    @deprecated_keywords({"classifierNames": "classifier_names", 
     87                          "classValues": "class_values", 
     88                          "baseClass": "base_class", 
     89                          "numberOfIterations": "number_of_iterations", 
     90                          "numberOfLearners": "number_of_learners"}) 
     91    def __init__(self, iterations, classifier_names, class_values=None, weights=None, base_class=-1, domain=None, test_type=TEST_TYPE_SINGLE, **argkw): 
     92        self.class_values = class_values 
     93        self.classifier_names = classifier_names 
     94        self.number_of_iterations = iterations 
     95        self.number_of_learners = len(classifier_names) 
    8096        self.results = [] 
    8197        self.classifiers = [] 
    8298        self.loaded = None 
    83         self.baseClass = baseClass 
     99        self.base_class = base_class 
    84100        self.weights = weights 
     101        self.test_type = test_type 
    85102 
    86103        if domain is not None: 
    87             if domain.classVar.varType == Orange.data.Type.Discrete: 
    88                 self.classValues = list(domain.classVar.values) 
    89                 self.baseClass = domain.classVar.base_value 
    90                 self.converter = int 
    91             else: 
    92                 self.baseClass = self.classValues = None 
    93                 self.converter = float 
     104            self.base_class = self.class_values = None 
     105            if test_type==TEST_TYPE_SINGLE: 
     106                if domain.class_var.var_type == Orange.data.Type.Discrete: 
     107                    self.class_values = list(domain.class_var.values) 
     108                    self.base_class = domain.class_var.base_value 
     109                    self.converter = int 
     110                else: 
     111                    self.converter = float 
     112            elif test_type==TEST_TYPE_MLC: 
     113                self.converter = lambda vals: [int(val) if val.variable.var_type == Orange.data.Type.Discrete 
     114                                               else float(val) for val in vals] 
    94115 
    95116        self.__dict__.update(argkw) 
     
    102123 
    103124    def create_tested_example(self, fold, example): 
     125        actual = [example.getclass, example.get_classes][self.test_type]() 
    104126        return TestedExample(fold, 
    105                              self.converter(example.getclass()), 
    106                              self.numberOfLearners, 
     127                             self.converter(actual), 
     128                             self.number_of_learners, 
    107129                             example.getweight(self.weights)) 
    108130 
     
    112134            del r.classes[index] 
    113135            del r.probabilities[index] 
    114         del self.classifierNames[index] 
    115         self.numberOfLearners -= 1 
     136        del self.classifier_names[index] 
     137        self.number_of_learners -= 1 
    116138 
    117139    def add(self, results, index, replace=-1): 
     
    119141        if len(self.results)!=len(results.results): 
    120142            raise SystemError("mismatch in number of test cases") 
    121         if self.numberOfIterations!=results.numberOfIterations: 
     143        if self.number_of_iterations!=results.number_of_iterations: 
    122144            raise SystemError("mismatch in number of iterations (%d<>%d)" % \ 
    123                   (self.numberOfIterations, results.numberOfIterations)) 
     145                  (self.number_of_iterations, results.number_of_iterations)) 
    124146        if len(self.classifiers) and len(results.classifiers)==0: 
    125147            raise SystemError("no classifiers in results") 
    126148 
    127         if replace < 0 or replace >= self.numberOfLearners: # results for new learner 
    128             self.classifierNames.append(results.classifierNames[index]) 
    129             self.numberOfLearners += 1 
     149        if replace < 0 or replace >= self.number_of_learners: # results for new learner 
     150            self.classifier_names.append(results.classifier_names[index]) 
     151            self.number_of_learners += 1 
    130152            for i,r in enumerate(self.results): 
    131153                r.classes.append(results.results[i].classes[index]) 
    132154                r.probabilities.append(results.results[i].probabilities[index]) 
    133155            if len(self.classifiers): 
    134                 for i in range(self.numberOfIterations): 
     156                for i in range(self.number_of_iterations): 
    135157                    self.classifiers[i].append(results.classifiers[i][index]) 
    136158        else: # replace results of existing learner 
    137             self.classifierNames[replace] = results.classifierNames[index] 
     159            self.classifier_names[replace] = results.classifier_names[index] 
    138160            for i,r in enumerate(self.results): 
    139161                r.classes[replace] = results.results[i].classes[index] 
    140162                r.probabilities[replace] = results.results[i].probabilities[index] 
    141163            if len(self.classifiers): 
    142                 for i in range(self.numberOfIterations): 
     164                for i in range(self.number_of_iterations): 
    143165                    self.classifiers[replace] = results.classifiers[i][index] 
    144166 
    145167    def __repr__(self): 
    146168        return str(self.__dict__) 
     169 
     170 
     171ExperimentResults = deprecated_members({"classValues": "class_values", 
     172                                        "classifierNames": "classifier_names", 
     173                                        "baseClass": "base_class", 
     174                                        "numberOfIterations": "number_of_iterations", 
     175                                        "numberOfLearners": "number_of_learners" 
     176                                        })(ExperimentResults) 
     177 
    147178#### Experimental procedures 
    148179class Evaluation(object): 
     
    192223        return self.test_with_indices(learners, examples, indices=range(len(examples)), preprocessors=preprocessors, 
    193224                                 callback=callback, store_classifiers=store_classifiers, store_examples=store_examples) 
     225     
     226    def check_test_type(self, instances, learners): 
     227        learner_is_mlc = [isinstance(l, Orange.multilabel.MultiLabelLearner) 
     228                          for l in learners] 
     229        multi_label = any(learner_is_mlc) 
     230        if multi_label and not all(learner_is_mlc): 
     231            raise ValueError("Test on mixed types of learners (MLC and non-MLC) not possible") 
     232         
     233        if multi_label and not instances.domain.class_vars: 
     234            raise ValueError("Test data with multiple labels (class vars) expected") 
     235        if not multi_label and not instances.domain.class_var: 
     236            raise ValueError("Test data set without class attributes") 
     237         
     238        return [TEST_TYPE_SINGLE, TEST_TYPE_MLC][multi_label] 
    194239 
    195240     
     
    216261        if not examples: 
    217262            raise ValueError("Test data set with no examples") 
    218         if not examples.domain.classVar: 
    219             raise ValueError("Test data set without class attribute") 
     263        test_type = self.check_test_type(examples, learners) 
    220264        if "cache" in kwargs: 
    221265            raise ValueError("This feature is no longer supported.") 
    222  
    223266 
    224267        niterations = max(indices)+1 
     
    226269                                        classifierNames = [getobjectname(l) for l in learners], 
    227270                                        domain=examples.domain, 
    228                                         weights=weight) 
     271                                        weights=weight, 
     272                                        test_type=test_type) 
    229273 
    230274        test_result.results = [test_result.create_tested_example(indices[i], example) 
     
    602646                # Hide actual class to prevent cheating 
    603647                ex2 = Orange.data.Instance(example) 
    604                 ex2.setclass("?") 
     648                if ex2.domain.class_var: ex2.setclass("?") 
     649                if ex2.domain.class_vars: ex2.set_classes(["?" for cv in ex2.domain.class_vars]) 
    605650                result = classifier(ex2, Orange.core.GetBoth) 
    606651                results.append((e, c, result)) 
Note: See TracChangeset for help on using the changeset viewer.