Python牛奶库:对象权重问题

问题描述:

我正尝试使用one_vs_one决策树组合来进行多类别分类。问题是,当我将不同的对象权重传递给分类器时,结果保持不变。Python牛奶库:对象权重问题

我对重量有误解吗?还是只是错误地工作?

感谢您的回复!

这里是我的代码:

class AdaLearner(object): 
    def __init__(self, in_base_type, in_multi_type): 
     self.base_type = in_base_type 
     self.multi_type = in_multi_type 

    def train(self, in_features, in_labels): 
     model = AdaBoost(self.base_type, self.multi_type) 
     model.learn(in_features, in_labels) 

     return model 

class AdaBoost(object): 
    CLASSIFIERS_NUM = 100 
    def __init__(self, in_base_type, in_multi_type): 
     self.base_type = in_base_type 
     self.multi_type = in_multi_type 
     self.classifiers = [] 
     self.weights = [] 

    def learn(self, in_features, in_labels): 
     labels_number = len(set(in_labels)) 
     self.weights = self.get_initial_weights(in_labels) 

     for iteration in xrange(AdaBoost.CLASSIFIERS_NUM): 
      classifier = self.multi_type(self.base_type()) 
      self.classifiers.append(classifier.train(in_features, 
                in_labels, 
                weights=self.weights)) 
      answers = [] 
      for obj in in_features: 
       answers.append(self.classifiers[-1].apply(obj)) 
      err = self.compute_weighted_error(in_labels, answers) 
      print err 
      if abs(err - 0.) < 1e-6: 
      break 

      alpha = 0.5 * log((1 - err)/err) 

      self.update_weights(in_labels, answers, alpha) 
      self.normalize_weights() 

    def apply(self, in_features): 
     answers = {} 
     for classifier in self.classifiers: 
      answer = classifier.apply(in_features) 
      if answer in answers: 
       answers[answer] += 1 
      else: 
       answers[answer] = 1 
     ranked_answers = sorted(answers.iteritems(), 
           key=lambda (k,v): (v,k), 
           reverse=True) 
     return ranked_answers[0][0] 

    def compute_weighted_error(self, in_labels, in_answers): 
     error = 0. 
     w_sum = sum(self.weights) 
     for ind in xrange(len(in_labels)): 
      error += (in_answers[ind] != in_labels[ind]) * self.weights[ind]/w_sum 
     return error 

    def update_weights(self, in_labels, in_answers, in_alpha): 
     for ind in xrange(len(in_labels)): 
      self.weights[ind] *= exp(in_alpha * (in_answers[ind] != in_labels[ind])) 

    def normalize_weights(self): 
     w_sum = sum(self.weights) 
     for ind in xrange(len(self.weights)): 
      self.weights[ind] /= w_sum 

    def get_initial_weights(self, in_labels): 
     weight = 1/float(len(in_labels)) 
     result = [] 
     for i in xrange(len(in_labels)): 
      result.append(weight) 
     return result 

正如你所看到的,它只是一个简单的AdaBoost(我in_base_type = tree_learner,in_multi_type = one_against_one实例吧)和它的工作以同样的方式不管有多少基本分类器被聘用。它只是作为一个多类决策树。 然后我做了一个破解。我在每次迭代中选择一个关于它们的权重的随机样本,并且使用没有任何权重的随机子集对象训练分类器。而且,它的工作原理应该如此。

+1

请您介绍一些代码,说明更改权重并运行分类吗? – Thomas

+2

作者牛奶在这里:我第二个托马斯的情绪。这可能是牛奶中的缺陷或缺乏对该功能的支持,但我需要查看代码。 – luispedro

+0

你有没有考虑过把它清理一下并提交给牛奶?我可以做一些清理工作,如果你对牛奶许可证(BSD简化)可以。 – luispedro

默认树标准,即信息增益,没有考虑权重。如果你知道这样做的公式,我会执行它。

与此同时,使用neg_z1_loss会正确地做到这一点。顺便说一下,该实现中存在一个小问题,所以您需要使用最新的github master