Changeset 10753:1019ea26af2d in orange


Ignore:
Timestamp:
04/05/12 12:41:41 (2 years ago)
Author:
Miran@…
Branch:
default
Message:

Fixed support for multi-target tree learners in random forests,
fixed scoring documentation for the new mt scoring functions.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Orange/ensemble/forest.py

    r10745 r10753  
    161161 
    162162        return RandomForestClassifier(classifiers = classifiers, name=self.name,\ 
    163                     domain=instances.domain, class_var=instances.domain.class_var) 
     163                    domain=instances.domain, class_var=instances.domain.class_var, \ 
     164                    class_vars=instances.domain.class_vars) 
     165 
     166             
    164167RandomForestLearner = Orange.utils.deprecated_members({"examples":"instances"})(RandomForestLearner) 
    165168 
     
    186189    :type class_var: :class:`Orange.feature.Descriptor` 
    187190 
    188     """ 
    189     def __init__(self, classifiers, name, domain, class_var, **kwds): 
     191    :param class_vars: the multi-target class features. 
     192    :type class_vars: list of :class:`Orange.feature.Descriptor` 
     193 
     194    """ 
     195    def __init__(self, classifiers, name, domain, class_var, class_vars, **kwds): 
    190196        self.classifiers = classifiers 
    191197        self.name = name 
    192198        self.domain = domain 
    193199        self.class_var = class_var 
     200        self.class_vars = class_vars 
    194201        self.__dict__.update(kwds) 
     202        self.single_class = True if not class_vars else False 
    195203 
    196204    def __call__(self, instance, result_type = orange.GetValue): 
     
    208216        from operator import add 
    209217         
    210         # handle discreete class 
    211          
    212         if self.class_var.var_type == Orange.feature.Discrete.Discrete: 
    213          
    214             # voting for class probabilities 
    215             if result_type == orange.GetProbabilities or result_type == orange.GetBoth: 
    216                 prob = [0.] * len(self.domain.class_var.values) 
    217                 for c in self.classifiers: 
    218                     a = [x for x in c(instance, orange.GetProbabilities)] 
    219                     prob = map(add, prob, a) 
    220                 norm = sum(prob) 
    221                 cprob = Orange.statistics.distribution.Discrete(self.class_var) 
    222                 for i in range(len(prob)): 
    223                     cprob[i] = prob[i]/norm 
     218        # get results to avoid multiple calls 
     219        res_both = [c(instance, orange.GetBoth) for c in self.classifiers] 
     220 
     221        # transform single class instance to match multi-target instances 
     222        if self.single_class: 
     223            self.class_vars = [self.class_var] 
     224            res_both = [([(r[0])],[(r[1])]) for r in res_both] 
     225 
     226        mt_prob = [] 
     227        mt_value = [] 
     228 
     229        for varn in xrange(len(self.class_vars)): 
     230 
     231            self.class_var = self.class_vars[varn] 
     232             
     233            # handle discreete class 
     234         
     235            if self.class_var.var_type == Orange.feature.Discrete.Discrete: 
     236         
     237                # voting for class probabilities 
     238                if result_type == orange.GetProbabilities or result_type == orange.GetBoth: 
     239                    prob = [0.] * len(self.class_var.values) 
     240                    for r in res_both: 
     241                        a = [x for x in r[1][varn]] 
     242                        prob = map(add, prob, a) 
     243                    norm = sum(prob) 
     244                    cprob = Orange.statistics.distribution.Discrete(self.class_var) 
     245                    for i in range(len(prob)): 
     246                        cprob[i] = prob[i]/norm 
    224247                 
    225             # voting for crisp class membership, notice that 
    226             # this may not be the same class as one obtaining the 
    227             # highest probability through probability voting 
    228             if result_type == orange.GetValue or result_type == orange.GetBoth: 
    229                 cfreq = [0] * len(self.domain.class_var.values) 
    230                 for c in self.classifiers: 
    231                     cfreq[int(c(instance))] += 1 
    232                 index = cfreq.index(max(cfreq)) 
    233                 cvalue = Orange.data.Value(self.domain.class_var, index) 
    234      
    235             if result_type == orange.GetValue: return cvalue 
    236             elif result_type == orange.GetProbabilities: return cprob 
    237             else: return (cvalue, cprob) 
    238          
    239         else: 
    240             # Handle continuous class 
    241          
    242             # voting for class probabilities 
    243             if result_type == orange.GetProbabilities or result_type == orange.GetBoth: 
    244                 probs = [c(instance, orange.GetBoth) for c in self.classifiers] 
    245                 cprob = dict() 
    246                 for val,prob in probs: 
    247                     if prob != None: #no probability output 
    248                         a = dict(prob.items()) 
    249                     else: 
    250                         a = { val.value : 1. } 
    251                     cprob = dict( (n, a.get(n, 0)+cprob.get(n, 0)) for n in set(a)|set(cprob) ) 
    252                 cprob = Orange.statistics.distribution.Continuous(cprob) 
    253                 cprob.normalize() 
     248                # voting for crisp class membership, notice that 
     249                # this may not be the same class as one obtaining the 
     250                # highest probability through probability voting 
     251                if result_type == orange.GetValue or result_type == orange.GetBoth: 
     252                    cfreq = [0] * len(self.class_var.values) 
     253                    for r in res_both: 
     254                        cfreq[int(r[0][varn])] += 1 
     255                    index = cfreq.index(max(cfreq)) 
     256                    cvalue = Orange.data.Value(self.class_var, index) 
     257             
     258 
     259                if result_type == orange.GetValue: mt_value.append(cvalue) 
     260                elif result_type == orange.GetProbabilities: mt_prob.append(cprob) 
     261                else:  
     262                    mt_value.append(cvalue) 
     263                    mt_prob.append(cprob) 
     264         
     265            else: 
     266                # Handle continuous class 
     267         
     268                # voting for class probabilities 
     269                if result_type == orange.GetProbabilities or result_type == orange.GetBoth: 
     270                    probs = [ r for r in res_both] 
     271                    cprob = dict() 
     272 
     273                
     274                    for val,prob in probs: 
     275                        if prob != None: #no probability output 
     276                            a = dict(prob.items()) 
     277                        else: 
     278                            ya = { val.value : 1. } 
     279                        cprob = dict( (n, a.get(n, 0)+cprob.get(n, 0)) for n in set(a)|set(cprob) ) 
     280                    cprob = Orange.statistics.distribution.Continuous(cprob) 
     281                    cprob.normalize() 
    254282                 
    255             # gather average class value 
    256             if result_type == orange.GetValue or result_type == orange.GetBoth: 
    257                 values = [c(instance).value for c in self.classifiers] 
    258                 cvalue = Orange.data.Value(self.domain.class_var, sum(values) / len(self.classifiers)) 
    259              
    260             if result_type == orange.GetValue: return cvalue 
    261             elif result_type == orange.GetProbabilities: return cprob 
    262             else: return (cvalue, cprob) 
    263              
     283                # gather average class value 
     284                if result_type == orange.GetValue or result_type == orange.GetBoth: 
     285                    values = [c(instance).value for c in self.classifiers] 
     286                    cvalue = Orange.data.Value(self.class_var, sum(values) / len(self.classifiers)) 
     287             
     288                if result_type == orange.GetValue: mt_value.append(cvalue) 
     289                elif result_type == orange.GetProbabilities: mt_prob.append(cprob) 
     290                else:  
     291                    mt_value.append(cvalue) 
     292                    mt_prob.append(cprob) 
     293         
     294        # check for singleclass when returning 
     295        if self.single_class: 
     296            if result_type == orange.GetValue: return mt_value[0] 
     297            elif result_type == orange.GetProbabilities: return mt_prob[0] 
     298            else:  
     299                return [mt_value[0],mt_prob[0]]  
     300             
     301        if result_type == orange.GetValue: return tuple(mt_value) 
     302        elif result_type == orange.GetProbabilities: return tuple(mt_prob) 
     303        else:  
     304            return [tuple(mt_value),tuple(mt_prob)] 
     305 
    264306    def __reduce__(self): 
    265         return type(self), (self.classifiers, self.name, self.domain, self.class_var), dict(self.__dict__) 
     307        return type(self), (self.classifiers, self.name, self.domain, self.class_var, self.class_vars), dict(self.__dict__) 
    266308RandomForestClassifier = Orange.utils.deprecated_members({"resultType":"result_type", "classVar":"class_var", "example":"instance"})(RandomForestClassifier) 
    267309### MeasureAttribute_randomForests 
  • Orange/evaluation/scoring.py

    r10740 r10753  
    26702670def mt_global_accuracy(res): 
    26712671    """ 
    2672     \emph{Global accuracy} (accuracy per example) over \emph{d}-dimensional class variable. 
    2673     :math:`Acc = \frac{1}{N}\sum_{i=1}^{N}\delta(\mathbf{c_{i}'},\mathbf{c_{i}})` 
    2674     :math:'\delta (\mathbf{c_{i}'},\mathbf{c_{i}} )=\left\{\begin{matrix}1:\mathbf{c_{i}'}=\mathbf{c_{i}}\\ 0: otherwise\end{matrix}' 
     2672    :math:`Acc = \\frac{1}{N}\\sum_{i=1}^{N}\\delta(\\mathbf{c_{i}'},\\mathbf{c_{i}}) \\newline` 
     2673     
     2674    :math:`\\delta (\\mathbf{c_{i}'},\\mathbf{c_{i}} )=\\left\\{\\begin{matrix}1:\\mathbf{c_{i}'}=\\mathbf{c_{i}}\\\\ 0: otherwise\\end{matrix}\\right.` 
    26752675    """ 
    26762676    results = [] 
     
    26862686    return results 
    26872687 
     2688 
    26882689def mt_mean_accuracy(res): 
    26892690    """ 
    2690     \emph{Mean accuracy} (accuracy per class or per label) over \emph{d} class variables. 
    2691     :math:`\overline{Acc_{d}} = \frac{1}{d}\sum_{j=1}^{d}Acc_{j} = \frac{1}{d}\sum_{j=1}^{d} \frac{1}{N}\sum_{i=1}^{N}\delta(c_{ij}',c_{ij} )` 
    2692     :math:'\delta (c_{ij}',c_{ij} )=\left\{\begin{matrix}1:c_{ij}'=c_{ij}\\ 0: otherwise\end{matrix}' 
     2691    :math:`\\overline{Acc_{d}} = \\frac{1}{d}\sum_{j=1}^{d}Acc_{j} = \\frac{1}{d}\\sum_{j=1}^{d} \\frac{1}{N}\sum_{i=1}^{N}\\delta(c_{ij}',c_{ij} ) \\newline ` 
     2692     
     2693    :math:`\\delta (c_{ij}',c_{ij} )=\\left\\{\\begin{matrix}1:c_{ij}'=c_{ij}\\\\ 0: otherwise\\end{matrix}\\right.` 
    26932694    """ 
    26942695    results = [] 
     
    26992700 
    27002701        for r in res.results: 
    2701             #n_correct+=sum((1 if r.classes[l][i] == r.actual_class[i] else 0 for i in xrange(n_classes))) 
    27022702            for i in xrange(n_classes): 
    27032703                if r.classes[l][i] == r.actual_class[i]: 
     
    27052705        results.append(n_correct/n_classes/n_results) 
    27062706    return results 
     2707 
     2708 
    27072709 
    27082710################################################################################ 
  • docs/reference/rst/Orange.evaluation.scoring.rst

    r10741 r10753  
    164164Two more accuracy measures based on the article by Zaragoza et al.(2011): 
    165165 
    166 Global accuracy (accuracy per example) over d-dimensional class variable. 
     166Global accuracy (accuracy per example) over d-dimensional class variable: 
    167167 
    168168.. autofunction:: mt_global_accuracy 
    169169 
    170 Mean accuracy accuracy per class or per label over d class variables. 
     170Mean accuracy (accuracy per class or per label) over d class variables:  
    171171 
    172172.. autofunction:: mt_mean_accuracy    
Note: See TracChangeset for help on using the changeset viewer.