"""
Base module.
"""
-from sklearn.base import BaseEstimator
+from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.utils.extmath import stable_cumsum
from sklearn.utils.validation import _is_arraylike, check_is_fitted
from sklearn.metrics import roc_auc_score, roc_curve, precision_recall_curve
import numpy as np
from abc import ABCMeta, abstractmethod
from ._util import ArrayIndexer, check_input, validate_vector
+import warnings
-[docs]class BaseMetricLearner(BaseEstimator, metaclass=ABCMeta):
-
"""
+
+
[docs]
+
class BaseMetricLearner(BaseEstimator, metaclass=ABCMeta):
+
"""
Base class for all metric-learners.
Parameters
@@ -189,18 +113,68 @@
Source code for metric_learn.base_metric
tuples will be gotten like this: X[indices].
"""
-[docs] def __init__(self, preprocessor=None):
+
+
[docs]
+
def __init__(self, preprocessor=None):
self.preprocessor = preprocessor
-
[docs] @abstractmethod
+
+
+
[docs]
+
@abstractmethod
def score_pairs(self, pairs):
-
"""Returns the score between pairs
+
"""
+
Returns the score between pairs
(can be a similarity, or a distance/metric depending on the algorithm)
+
.. deprecated:: 0.7.0
+
Refer to `pair_distance` and `pair_score`.
+
+
.. warning::
+
This method will be removed in 0.8.0. Please refer to `pair_distance`
+
or `pair_score`. This change will occur in order to add learners
+
that don't necessarily learn a Mahalanobis distance.
+
+
Parameters
+
----------
+
pairs : array-like, shape=(n_pairs, 2, n_features) or (n_pairs, 2)
+
3D Array of pairs to score, with each row corresponding to two points,
+
for 2D array of indices of pairs if the metric learner uses a
+
preprocessor.
+
+
Returns
+
-------
+
scores : `numpy.ndarray` of shape=(n_pairs,)
+
The score of every pair.
+
+
See Also
+
--------
+
get_metric : a method that returns a function to compute the metric between
+
two points. The difference between `score_pairs` is that it works on two
+
1D arrays and cannot use a preprocessor. Besides, the returned function
+
is independent of the metric learner and hence is not modified if the
+
metric learner is.
+
"""
+
+
+
+
[docs]
+
@abstractmethod
+
def pair_score(self, pairs):
+
"""
+
.. versionadded:: 0.7.0 Compute the similarity score between pairs
+
+
Returns the similarity score between pairs of points (the larger the score,
+
the more similar the pair). For metric learners that learn a distance,
+
the score is simply the opposite of the distance between pairs. All
+
learners have access to this method.
+
Parameters
----------
-
pairs : `numpy.ndarray`, shape=(n_samples, 2, n_features)
-
3D array of pairs.
+
pairs : array-like, shape=(n_pairs, 2, n_features) or (n_pairs, 2)
+
3D Array of pairs to score, with each row corresponding to two points,
+
for 2D array of indices of pairs if the metric learner uses a
+
preprocessor.
Returns
-------
@@ -210,17 +184,51 @@
Source code for metric_learn.base_metric
See Also
--------
get_metric : a method that returns a function to compute the metric between
- two points. The difference with `score_pairs` is that it works on two 1D
- arrays and cannot use a preprocessor. Besides, the returned function is
- independent of the metric learner and hence is not modified if the metric
- learner is.
+ two points. The difference with `pair_score` is that it works on two
+ 1D arrays and cannot use a preprocessor. Besides, the returned function
+ is independent of the metric learner and hence is not modified if the
+ metric learner is.
"""
+
+
+
[docs]
+
@abstractmethod
+
def pair_distance(self, pairs):
+
"""
+
.. versionadded:: 0.7.0 Compute the distance between pairs
+
+
Returns the (pseudo) distance between pairs, when available. For metric
+
learners that do not learn a (pseudo) distance, an error is thrown
+
instead.
+
+
Parameters
+
----------
+
pairs : array-like, shape=(n_pairs, 2, n_features) or (n_pairs, 2)
+
3D Array of pairs for which to compute the distance, with each
+
row corresponding to two points, for 2D array of indices of pairs
+
if the metric learner uses a preprocessor.
+
+
Returns
+
-------
+
scores : `numpy.ndarray` of shape=(n_pairs,)
+
The distance between every pair.
+
+
See Also
+
--------
+
get_metric : a method that returns a function to compute the metric between
+
two points. The difference with `pair_distance` is that it works on two
+
1D arrays and cannot use a preprocessor. Besides, the returned function
+
is independent of the metric learner and hence is not modified if the
+
metric learner is.
+
"""
+
+
def _check_preprocessor(self):
-
"""Initializes the preprocessor"""
+
"""Initializes the preprocessor"""
if _is_arraylike(self.preprocessor):
self.preprocessor_ = ArrayIndexer(self.preprocessor)
-
elif callable(self.preprocessor) or self.preprocessor is None:
+
elif callable(self.preprocessor) or self.preprocessor is None:
self.preprocessor_ = self.preprocessor
else:
raise ValueError("Invalid type for the preprocessor: {}. You should "
@@ -229,7 +237,7 @@
Source code for metric_learn.base_metric
def _prepare_inputs(self, X, y=None, type_of_inputs='classic',
**kwargs):
- """Initializes the preprocessor and processes inputs. See `check_input`
+ """Initializes the preprocessor and processes inputs. See `check_input`
for more details.
Parameters
@@ -260,17 +268,25 @@ Source code for metric_learn.base_metric
self._check_preprocessor()
check_is_fitted(self, ['preprocessor_'])
- return check_input(X, y,
+ outs = check_input(X, y,
type_of_inputs=type_of_inputs,
preprocessor=self.preprocessor_,
estimator=self,
tuple_size=getattr(self, '_tuple_size', None),
**kwargs)
+ # Conform to SLEP010
+ if not hasattr(self, 'n_features_in_'):
+ self.n_features_in_ = (outs if y is None else outs[0]).shape[1]
+ return outs
-[docs] @abstractmethod
+
+
[docs]
+
@abstractmethod
def get_metric(self):
-
"""Returns a function that takes as input two 1D arrays and outputs the
-
learned metric score on these two points.
+
"""Returns a function that takes as input two 1D arrays and outputs
+
the value of the learned metric on these two points. Depending on the
+
algorithm, it can return a distance or a similarity function between
+
pairs.
This function will be independent from the metric learner that learned it
(it will not be modified if the initial metric learner is modified),
@@ -303,18 +319,34 @@
Source code for metric_learn.base_metric
See Also
--------
- score_pairs : a method that returns the metric score between several pairs
- of points. Unlike `get_metric`, this is a method of the metric learner
- and therefore can change if the metric learner changes. Besides, it can
- use the metric learner's preprocessor, and works on concatenated arrays.
- """
+
pair_distance : a method that returns the distance between several
+
pairs of points. Unlike `get_metric`, this is a method of the metric
+
learner and therefore can change if the metric learner changes. Besides,
+
it can use the metric learner's preprocessor, and works on concatenated
+
arrays.
+
+
pair_score : a method that returns the similarity score between
+
several pairs of points. Unlike `get_metric`, this is a method of the
+
metric learner and therefore can change if the metric learner changes.
+
Besides, it can use the metric learner's preprocessor, and works on
+
concatenated arrays.
+
"""
+
-class MetricTransformer(metaclass=ABCMeta):
+