From f643a2c28b0f8b0b44cb83680f21b95f3f31d726 Mon Sep 17 00:00:00 2001
From: Amir Mohammadi <183.amir@gmail.com>
Date: Tue, 31 Jan 2017 17:43:46 +0100
Subject: [PATCH] allow for preprocessors to use label for training

---
 bob/fusion/base/algorithm/Algorithm.py | 242 ++++++++++++-------------
 1 file changed, 121 insertions(+), 121 deletions(-)

diff --git a/bob/fusion/base/algorithm/Algorithm.py b/bob/fusion/base/algorithm/Algorithm.py
index ac78197..a56cafb 100644
--- a/bob/fusion/base/algorithm/Algorithm.py
+++ b/bob/fusion/base/algorithm/Algorithm.py
@@ -11,126 +11,126 @@ logger = bob.core.log.setup("bob.fusion.base")
 
 
 class Algorithm(object):
-  """A class to be used in score fusion"""
-
-  def __init__(self,
-               preprocessors=None,
-               classifier=None,
-               *args,
-               **kwargs
-               ):
-    """
-  preprocessors: A list of preprocessors that follow the API of
-    :py:meth:`sklearn.preprocessing.StandardScaler`. Especially `fit_transform`
-    and `transform` must be implemented.
-
-  classifier: An instance of a class that implements `fit(X[, y])` and
-    `decision_function(X)` like:
-    :py:meth:`sklearn.linear_model.LogisticRegression`
-
-  kwargs : ``key=value`` pairs
-    A list of keyword arguments to be written in the
-      :py:meth:`__str__` function.
+    """A class to be used in score fusion"""
+
+    def __init__(self,
+                 preprocessors=None,
+                 classifier=None,
+                 *args,
+                 **kwargs
+                 ):
+        """
+    preprocessors: A list of preprocessors that follow the API of
+        :py:meth:`sklearn.preprocessing.StandardScaler`. Especially `fit_transform`
+        and `transform` must be implemented.
+
+    classifier: An instance of a class that implements `fit(X[, y])` and
+        `decision_function(X)` like:
+        :py:meth:`sklearn.linear_model.LogisticRegression`
+
+    kwargs : ``key=value`` pairs
+        A list of keyword arguments to be written in the
+            :py:meth:`__str__` function.
 
 """
-    super(Algorithm, self).__init__()
-    self.classifier = classifier
-    self.preprocessors = preprocessors
-    self._kwargs = kwargs
-    self._kwargs['preprocessors'] = preprocessors
-    if classifier is not self:
-      self._kwargs['classifier'] = classifier
-
-  def train_preprocessors(self, X):
-    """Train preprocessors in order.
-    X: numpy.ndarray with the shape of (n_samples, n_systems)."""
-    if self.preprocessors is not None:
-      for preprocessor in self.preprocessors:
-        X = preprocessor.fit_transform(X)
-
-  def preprocess(self, scores):
-    """
-    scores: numpy.ndarray with the shape of (n_samples, n_systems).
-    returns the transformed scores."""
-    if self.preprocessors is not None:
-      for preprocessor in self.preprocessors:
-        scores = preprocessor.transform(scores)
-    return scores
-
-  def train(self, train_neg, train_pos, devel_neg=None, devel_pos=None):
-    """If you use development data for training you need to override this
-    method.
-
-    train_neg: numpy.ndarray
-      Negatives training data should be numpy.ndarray with the shape of
-      (n_samples, n_systems).
-    train_pos: numpy.ndarray
-      Positives training data should be numpy.ndarray with the shape of
-      (n_samples, n_systems).
-    devel_neg, devel_pos: numpy.ndarray
-      Same as ``train`` but used for development (validation).
-    """
-    train_scores = np.vstack((train_neg, train_pos))
-    neg_len = train_neg.shape[0]
-    y = np.zeros((train_scores.shape[0],), dtype='bool')
-    y[neg_len:] = True
-    self.classifier.fit(train_scores, y)
-
-  def fuse(self, scores):
-    """
-    scores: numpy.ndarray
-      A numpy.ndarray with the shape of (n_samples, n_systems).
-
-    **Returns:**
-
-    fused_score: numpy.ndarray
-      The fused scores in shape of (n_samples,).
-    """
-    return self.classifier.decision_function(scores)
-
-  def __str__(self):
-    """Return all parameters of this class (and its derived class) in string.
-
-
-    **Returns:**
-
-    info: str
-      A string containing the full information of all parameters of this
-        (and the derived) class.
-    """
-    return "%s(%s)" % (str(self.__class__), ", ".join(
-        ["%s=%s" % (key, value) for key, value in
-         self._kwargs.items() if value is not None]))
-
-  def save(self, model_file):
-    """Save the instance of the algorithm.
-
-    model_file: str
-      A path to save the file. Please note that file objects
-      are not accepted. The filename MUST end with ".pkl".
-      Also, an algorithm may save itself in multiple files with different
-      extensions such as model_file and model_file[:-3]+'hdf5'.
-    """
-    # support for bob machines
-    if hasattr(self, "custom_save"):
-      self.custom_save(model_file)
-    else:
-      with open(model_file, "wb") as f:
-        pickle.dump(type(self), f)
-        pickle.dump(self, f)
-
-  def load(self, model_file):
-    """Load the algorithm the same way it was saved.
-    A new instance will be returned.
-
-    **Returns:**
-
-    loaded_algorithm: Algorithm
-      A new instance of the loaded algorithm.
-    """
-    with open(model_file, "rb") as f:
-      algo_class = pickle.load(f)
-      algo = algo_class()
-      if not hasattr(algo, 'custom_save'):
-        return pickle.load(f)
-    return algo.load(model_file)
+        super(Algorithm, self).__init__()
+        self.classifier = classifier
+        self.preprocessors = preprocessors
+        self._kwargs = kwargs
+        self._kwargs['preprocessors'] = preprocessors
+        if classifier is not self:
+            self._kwargs['classifier'] = classifier
+
+    def train_preprocessors(self, X, y=None):
+        """Train preprocessors in order.
+        X: numpy.ndarray with the shape of (n_samples, n_systems)."""
+        if self.preprocessors is not None:
+            for preprocessor in self.preprocessors:
+                X = preprocessor.fit_transform(X, y)
+
+    def preprocess(self, scores):
+        """
+        scores: numpy.ndarray with the shape of (n_samples, n_systems).
+        returns the transformed scores."""
+        if self.preprocessors is not None:
+            for preprocessor in self.preprocessors:
+                scores = preprocessor.transform(scores)
+        return scores
+
+    def train(self, train_neg, train_pos, devel_neg=None, devel_pos=None):
+        """If you use development data for training you need to override this
+        method.
+
+        train_neg: numpy.ndarray
+            Negatives training data should be numpy.ndarray with the shape of
+            (n_samples, n_systems).
+        train_pos: numpy.ndarray
+            Positives training data should be numpy.ndarray with the shape of
+            (n_samples, n_systems).
+        devel_neg, devel_pos: numpy.ndarray
+            Same as ``train`` but used for development (validation).
+        """
+        train_scores = np.vstack((train_neg, train_pos))
+        neg_len = train_neg.shape[0]
+        y = np.zeros((train_scores.shape[0],), dtype='bool')
+        y[neg_len:] = True
+        self.classifier.fit(train_scores, y)
+
+    def fuse(self, scores):
+        """
+        scores: numpy.ndarray
+            A numpy.ndarray with the shape of (n_samples, n_systems).
+
+        **Returns:**
+
+        fused_score: numpy.ndarray
+            The fused scores in shape of (n_samples,).
+        """
+        return self.classifier.decision_function(scores)
+
+    def __str__(self):
+        """Return all parameters of this class (and its derived class) in string.
+
+
+        **Returns:**
+
+        info: str
+            A string containing the full information of all parameters of this
+                (and the derived) class.
+        """
+        return "%s(%s)" % (str(self.__class__), ", ".join(
+            ["%s=%s" % (key, value) for key, value in
+             self._kwargs.items() if value is not None]))
+
+    def save(self, model_file):
+        """Save the instance of the algorithm.
+
+        model_file: str
+            A path to save the file. Please note that file objects
+            are not accepted. The filename MUST end with ".pkl".
+            Also, an algorithm may save itself in multiple files with different
+            extensions such as model_file and model_file[:-3]+'hdf5'.
+        """
+        # support for bob machines
+        if hasattr(self, "custom_save"):
+            self.custom_save(model_file)
+        else:
+            with open(model_file, "wb") as f:
+                pickle.dump(type(self), f)
+                pickle.dump(self, f)
+
+    def load(self, model_file):
+        """Load the algorithm the same way it was saved.
+        A new instance will be returned.
+
+        **Returns:**
+
+        loaded_algorithm: Algorithm
+            A new instance of the loaded algorithm.
+        """
+        with open(model_file, "rb") as f:
+            algo_class = pickle.load(f)
+            algo = algo_class()
+            if not hasattr(algo, 'custom_save'):
+                return pickle.load(f)
+        return algo.load(model_file)
-- 
GitLab