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实例吧)和它的工作以同样的方式不管有多少基本分类器被聘用。它只是作为一个多类决策树。 然后我做了一个破解。我在每次迭代中选择一个关于它们的权重的随机样本,并且使用没有任何权重的随机子集对象训练分类器。而且,它的工作原理应该如此。
答
默认树标准,即信息增益,没有考虑权重。如果你知道这样做的公式,我会执行它。
与此同时,使用neg_z1_loss会正确地做到这一点。顺便说一下,该实现中存在一个小问题,所以您需要使用最新的github master。
请您介绍一些代码,说明更改权重并运行分类吗? – Thomas
作者牛奶在这里:我第二个托马斯的情绪。这可能是牛奶中的缺陷或缺乏对该功能的支持,但我需要查看代码。 – luispedro
你有没有考虑过把它清理一下并提交给牛奶?我可以做一些清理工作,如果你对牛奶许可证(BSD简化)可以。 – luispedro