source: orange/Orange/ensemble/stacking.py @ 10540:788913064426

Revision 10540:788913064426, 3.0 KB checked in by blaz <blaz.zupan@…>, 2 years ago (diff)

Added stacking (ensemble method).

Line 
1import Orange
2
3class StackedClassificationLearner(Orange.classification.Learner):
4    """Stacking by inference of meta classifier from class probability estimates
5    on cross-validation held-out data for level-0 classifiers developed on held-in data sets.
6
7    :param learners: level-0 learners.
8    :type learners: list
9
10    :param meta_learner: meta learner (default: :class:`~Orange.classification.bayes.NaiveLearner`).
11    :type meta_learner: :class:`~Orange.classification.Learner`
12
13    :param folds: number of iterations (folds) of cross-validation to assemble class probability data for meta learner.
14
15    :param name: learner name (default: stacking).
16    :type name: string
17
18    :rtype: :class:`~Orange.ensemble.stacking.StackedClassificationLearner` or
19        :class:`~Orange.ensemble.stacking.StackedClassifier`
20    """
21    def __new__(cls, learners, data=None, weight=0, **kwds):
22        if data is None:
23            self = Orange.classification.Learner.__new__(cls)
24            return self
25        else:
26            self = cls(learners, **kwds)
27            return self(data, weight)
28
29    def __init__(self, learners, meta_learner=Orange.classification.bayes.NaiveLearner(), folds=10, name='stacking'):
30        self.learners = learners
31        self.meta_learner = meta_learner
32        self.name = name
33        self.folds = folds
34
35    def __call__(self, data, weight=0):
36        res = Orange.evaluation.testing.cross_validation(self.learners, data, self.folds)
37        features = [Orange.feature.Continuous("%d" % i) for i in range(len(self.learners) * (len(data.domain.class_var.values) - 1))]
38        domain = Orange.data.Domain(features + [data.domain.class_var])
39        p_data = Orange.data.Table(domain)
40        for r in res.results:
41            p_data.append([p for ps in r.probabilities for p in ps[:-1]] + [r.actual_class])
42        meta_classifier = self.meta_learner(p_data)
43
44        classifiers = [l(data, weight) for l in self.learners]
45        feature_domain = Orange.data.Domain(features)
46        return StackedClassifier(classifiers, meta_classifier, name=self.name)
47
48class StackedClassifier:
49    """
50    A classifier for stacking. Uses a set of level-0 classifiers to induce class probabilities, which
51    are an input to a meta-classifier to predict class probability for a given data instance.
52
53    :param classifiers: a list of level-0 classifiers.
54    :type classifiers: list
55
56    :param meta_classifier: meta-classifier.
57    :type meta_classifier: :class:`~Orange.classification.Classifier`
58    """
59    def __init__(self, classifiers, meta_classifier, **kwds):
60        self.classifiers = classifiers
61        self.meta_classifier = meta_classifier
62        self.domain = Orange.data.Domain(self.meta_classifier.domain.features, False)
63        self.__dict__.update(kwds)
64
65    def __call__(self, instance, resultType=Orange.core.GetValue):
66        ps = Orange.data.Instance(self.domain, [p for cl in self.classifiers for p in list(cl(instance, Orange.core.GetProbabilities))[:-1]])
67        return self.meta_classifier(ps, resultType)
Note: See TracBrowser for help on using the repository browser.