Skip to content

[MRG+2] Update the repo for release #295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ metric-learn contains efficient Python implementations of several popular superv
- Information Theoretic Metric Learning (ITML)
- Sparse Determinant Metric Learning (SDML)
- Least Squares Metric Learning (LSML)
- Sparse Compositional Metric Learning (SCML)
- Neighborhood Components Analysis (NCA)
- Local Fisher Discriminant Analysis (LFDA)
- Relative Components Analysis (RCA)
Expand Down
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
u'Bellet and Nathalie Vauquier')
author = (u'CJ Carey, Yuan Tang, William de Vazelhes, Aurélien Bellet and '
u'Nathalie Vauquier')
version = '0.5.0'
release = '0.5.0'
version = '0.6.0'
release = '0.6.0'
language = 'en'

exclude_patterns = ['_build']
Expand Down
7 changes: 7 additions & 0 deletions doc/modules.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
metric_learn
============

.. toctree::
:maxdepth: 4

metric_learn
2 changes: 1 addition & 1 deletion doc/supervised.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ classes will be large. To do so, we fit the metric learner (example:
>>> from metric_learn import NCA
>>> nca = NCA(random_state=42)
>>> nca.fit(X, y)
NCA(init=None, max_iter=100, n_components=None, num_dims='deprecated',
NCA(init='auto', max_iter=100, n_components=None,
preprocessor=None, random_state=42, tol=None, verbose=False)


Expand Down
6 changes: 3 additions & 3 deletions doc/weakly_supervised.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ are respected.
>>> mmc = MMC(random_state=42)
>>> mmc.fit(tuples, y)
MMC(A0='deprecated', convergence_threshold=0.001, diagonal=False,
diagonal_c=1.0, init=None, max_iter=100, max_proj=10000,
diagonal_c=1.0, init='auto', max_iter=100, max_proj=10000,
preprocessor=None, random_state=42, verbose=False)

Or alternatively (using a preprocessor):
Expand Down Expand Up @@ -250,8 +250,8 @@ tuples).
>>> y_pairs = np.array([1, -1])
>>> mmc = MMC(random_state=42)
>>> mmc.fit(pairs, y_pairs)
MMC(A0='deprecated', convergence_threshold=0.001, diagonal=False,
diagonal_c=1.0, init=None, max_iter=100, max_proj=10000, preprocessor=None,
MMC(convergence_threshold=0.001, diagonal=False,
diagonal_c=1.0, init='auto', max_iter=100, max_proj=10000, preprocessor=None,
random_state=42, verbose=False)

Here, we learned a metric that puts the two first points closer
Expand Down
2 changes: 1 addition & 1 deletion examples/plot_metric_learning_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def plot_tsne(X, y, colormap=plt.cm.Paired):
# - See more in the documentation of the class :py:class:`LFDA
# <metric_learn.LFDA>`

lfda = metric_learn.LFDA(k=2, num_dims=2)
lfda = metric_learn.LFDA(k=2, n_components=2)
X_lfda = lfda.fit_transform(X, y)

plot_tsne(X_lfda, y)
Expand Down
2 changes: 1 addition & 1 deletion metric_learn/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.5.0'
__version__ = '0.6.0'
10 changes: 0 additions & 10 deletions metric_learn/base_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import numpy as np
from abc import ABCMeta, abstractmethod
from ._util import ArrayIndexer, check_input, validate_vector
import warnings


class BaseMetricLearner(BaseEstimator, metaclass=ABCMeta):
Expand Down Expand Up @@ -285,15 +284,6 @@ def metric_fun(u, v, squared=False):

get_metric.__doc__ = BaseMetricLearner.get_metric.__doc__

def metric(self):
"""Deprecated. Will be removed in v0.6.0. Use `get_mahalanobis_matrix`
instead"""
# TODO: remove this method in version 0.6.0
warnings.warn(("`metric` is deprecated since version 0.5.0 and will be "
"removed in 0.6.0. Use `get_mahalanobis_matrix` instead."),
DeprecationWarning)
return self.get_mahalanobis_matrix()

def get_mahalanobis_matrix(self):
"""Returns a copy of the Mahalanobis matrix learned by the metric learner.

Expand Down
68 changes: 4 additions & 64 deletions metric_learn/itml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
Information Theoretic Metric Learning (ITML)
"""

import warnings
import numpy as np
from sklearn.exceptions import ChangedBehaviorWarning
from sklearn.metrics import pairwise_distances
from sklearn.utils.validation import check_array
from sklearn.base import TransformerMixin
Expand All @@ -19,23 +17,17 @@ class _BaseITML(MahalanobisMixin):
_tuple_size = 2 # constraints are pairs

def __init__(self, gamma=1., max_iter=1000, convergence_threshold=1e-3,
prior='identity', A0='deprecated', verbose=False,
prior='identity', verbose=False,
preprocessor=None, random_state=None):
self.gamma = gamma
self.max_iter = max_iter
self.convergence_threshold = convergence_threshold
self.prior = prior
self.A0 = A0
self.verbose = verbose
self.random_state = random_state
super(_BaseITML, self).__init__(preprocessor)

def _fit(self, pairs, y, bounds=None):
if self.A0 != 'deprecated':
warnings.warn('"A0" parameter is not used.'
' It has been deprecated in version 0.5.0 and will be'
'removed in 0.6.0. Use "prior" instead.',
DeprecationWarning)
pairs, y = self._prepare_inputs(pairs, y,
type_of_inputs='tuples')
# init bounds
Expand Down Expand Up @@ -155,11 +147,6 @@ class ITML(_BaseITML, _PairsClassifierMixin):
(n_features, n_features), that will be used as such to set the
prior.

A0 : Not used
.. deprecated:: 0.5.0
`A0` was deprecated in version 0.5.0 and will
be removed in 0.6.0. Use 'prior' instead.

verbose : bool, optional (default=False)
If True, prints information while learning

Expand Down Expand Up @@ -276,21 +263,10 @@ class ITML_Supervised(_BaseITML, TransformerMixin):
convergence_threshold : float, optional (default=1e-3)
Tolerance of the optimization procedure.

num_labeled : Not used
.. deprecated:: 0.5.0
`num_labeled` was deprecated in version 0.5.0 and will
be removed in 0.6.0.

num_constraints : int, optional (default=None)
Number of constraints to generate. If None, default to `20 *
num_classes**2`.

bounds : Not used
.. deprecated:: 0.5.0
`bounds` was deprecated in version 0.5.0 and will
be removed in 0.6.0. Set `bounds` at fit time instead :
`itml_supervised.fit(X, y, bounds=...)`

prior : string or numpy array, optional (default='identity')
Initialization of the Mahalanobis matrix. Possible options are
'identity', 'covariance', 'random', and a numpy array of shape
Expand All @@ -313,11 +289,6 @@ class ITML_Supervised(_BaseITML, TransformerMixin):
(n_features, n_features), that will be used as such to set the
prior.

A0 : Not used
.. deprecated:: 0.5.0
`A0` was deprecated in version 0.5.0 and will
be removed in 0.6.0. Use 'prior' instead.

verbose : bool, optional (default=False)
If True, prints information while learning

Expand Down Expand Up @@ -368,18 +339,15 @@ class ITML_Supervised(_BaseITML, TransformerMixin):
"""

def __init__(self, gamma=1.0, max_iter=1000, convergence_threshold=1e-3,
num_labeled='deprecated', num_constraints=None,
bounds='deprecated', prior='identity', A0='deprecated',
num_constraints=None, prior='identity',
verbose=False, preprocessor=None, random_state=None):
_BaseITML.__init__(self, gamma=gamma, max_iter=max_iter,
convergence_threshold=convergence_threshold,
A0=A0, prior=prior, verbose=verbose,
prior=prior, verbose=verbose,
preprocessor=preprocessor, random_state=random_state)
self.num_labeled = num_labeled
self.num_constraints = num_constraints
self.bounds = bounds

def fit(self, X, y, random_state='deprecated', bounds=None):
def fit(self, X, y, bounds=None):
"""Create constraints from labels and learn the ITML model.


Expand All @@ -391,12 +359,6 @@ def fit(self, X, y, random_state='deprecated', bounds=None):
y : (n) array-like
Data labels.

random_state : Not used
.. deprecated:: 0.5.0
`random_state` in the `fit` function was deprecated in version 0.5.0
and will be removed in 0.6.0. Set `random_state` at initialization
instead (when instantiating a new `ITML_Supervised` object).

bounds : array-like of two numbers
Bounds on similarity, aside slack variables, s.t.
``d(a, b) < bounds_[0]`` for all given pairs of similar points ``a``
Expand All @@ -406,28 +368,6 @@ def fit(self, X, y, random_state='deprecated', bounds=None):
set to the 5th and 95th percentile of the pairwise distances among all
points in the training data `X`.
"""
# TODO: remove these in v0.6.0
if self.num_labeled != 'deprecated':
warnings.warn('"num_labeled" parameter is not used.'
' It has been deprecated in version 0.5.0 and will be'
' removed in 0.6.0', DeprecationWarning)
if self.bounds != 'deprecated':
warnings.warn('"bounds" parameter from initialization is not used.'
' It has been deprecated in version 0.5.0 and will be'
' removed in 0.6.0. Use the "bounds" parameter of this '
'fit method instead.', DeprecationWarning)
if random_state != 'deprecated':
warnings.warn('"random_state" parameter in the `fit` function is '
'deprecated. Set `random_state` at initialization '
'instead (when instantiating a new `ITML_Supervised` '
'object).', DeprecationWarning)
else:
warnings.warn('As of v0.5.0, `ITML_Supervised` now uses the '
'`random_state` given at initialization to sample '
'constraints, not the default `np.random` from the `fit` '
'method, since this argument is now deprecated. '
'This warning will disappear in v0.6.0.',
ChangedBehaviorWarning)
X, y = self._prepare_inputs(X, y, ensure_min_samples=2)
num_constraints = self.num_constraints
if num_constraints is None:
Expand Down
13 changes: 1 addition & 12 deletions metric_learn/lfda.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ class LFDA(MahalanobisMixin, TransformerMixin):
n_components : int or None, optional (default=None)
Dimensionality of reduced space (if None, defaults to dimension of X).

num_dims : Not used
.. deprecated:: 0.5.0
`num_dims` was deprecated in version 0.5.0 and will
be removed in 0.6.0. Use `n_components` instead.

k : int, optional (default=None)
Number of nearest neighbors used in local scaling method. If None,
defaults to min(7, n_features - 1).
Expand Down Expand Up @@ -81,12 +76,11 @@ class LFDA(MahalanobisMixin, TransformerMixin):
-discriminant-analysis-on-beer-style-clustering.html#>`_.
'''

def __init__(self, n_components=None, num_dims='deprecated',
def __init__(self, n_components=None,
k=None, embedding_type='weighted', preprocessor=None):
if embedding_type not in ('weighted', 'orthonormalized', 'plain'):
raise ValueError('Invalid embedding_type: %r' % embedding_type)
self.n_components = n_components
self.num_dims = num_dims
self.embedding_type = embedding_type
self.k = k
super(LFDA, self).__init__(preprocessor)
Expand All @@ -102,11 +96,6 @@ def fit(self, X, y):
y : (n,) array-like
Class labels, one per point of data.
'''
if self.num_dims != 'deprecated':
warnings.warn('"num_dims" parameter is not used.'
' It has been deprecated in version 0.5.0 and will be'
' removed in 0.6.0. Use "n_components" instead',
DeprecationWarning)
X, y = self._prepare_inputs(X, y, ensure_min_samples=2)
unique_classes, y = np.unique(y, return_inverse=True)
n, d = X.shape
Expand Down
51 changes: 6 additions & 45 deletions metric_learn/lmnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
Large Margin Nearest Neighbor Metric learning (LMNN)
"""
import numpy as np
import warnings
from collections import Counter
from sklearn.exceptions import ChangedBehaviorWarning
from sklearn.metrics import euclidean_distances
from sklearn.base import TransformerMixin

Expand All @@ -25,12 +23,10 @@ class LMNN(MahalanobisMixin, TransformerMixin):

Parameters
----------
init : None, string or numpy array, optional (default=None)
init : string or numpy array, optional (default='auto')
Initialization of the linear transformation. Possible options are
'auto', 'pca', 'identity', 'random', and a numpy array of shape
(n_features_a, n_features_b). If None, will be set automatically to
'auto' (this option is to raise a warning if 'init' is not set, and
stays to its default value None, in v0.5.0).
(n_features_a, n_features_b).

'auto'
Depending on ``n_components``, the most reasonable initialization
Expand Down Expand Up @@ -83,11 +79,6 @@ class LMNN(MahalanobisMixin, TransformerMixin):
Tolerance of the optimization procedure. If the objective value varies
less than `tol`, we consider the algorithm has converged and stop it.

use_pca : Not used
.. deprecated:: 0.5.0
`use_pca` was deprecated in version 0.5.0 and will
be removed in 0.6.0.

verbose : bool, optional (default=False)
Whether to print the progress of the optimization procedure.

Expand All @@ -102,11 +93,6 @@ class LMNN(MahalanobisMixin, TransformerMixin):
n_components : int or None, optional (default=None)
Dimensionality of reduced space (if None, defaults to dimension of X).

num_dims : Not used
.. deprecated:: 0.5.0
`num_dims` was deprecated in version 0.5.0 and will
be removed in 0.6.0. Use `n_components` instead.

random_state : int or numpy.RandomState or None, optional (default=None)
A pseudo random number generator object or a seed for it if int. If
``init='random'``, ``random_state`` is used to initialize the random
Expand Down Expand Up @@ -142,35 +128,23 @@ class LMNN(MahalanobisMixin, TransformerMixin):
2005.
"""

def __init__(self, init=None, k=3, min_iter=50, max_iter=1000,
def __init__(self, init='auto', k=3, min_iter=50, max_iter=1000,
learn_rate=1e-7, regularization=0.5, convergence_tol=0.001,
use_pca='deprecated', verbose=False, preprocessor=None,
n_components=None, num_dims='deprecated', random_state=None):
verbose=False, preprocessor=None,
n_components=None, random_state=None):
self.init = init
self.k = k
self.min_iter = min_iter
self.max_iter = max_iter
self.learn_rate = learn_rate
self.regularization = regularization
self.convergence_tol = convergence_tol
self.use_pca = use_pca
self.verbose = verbose
self.n_components = n_components
self.num_dims = num_dims
self.random_state = random_state
super(LMNN, self).__init__(preprocessor)

def fit(self, X, y):
if self.num_dims != 'deprecated':
warnings.warn('"num_dims" parameter is not used.'
' It has been deprecated in version 0.5.0 and will be'
' removed in 0.6.0. Use "n_components" instead',
DeprecationWarning)
if self.use_pca != 'deprecated':
warnings.warn('"use_pca" parameter is not used.'
' It has been deprecated in version 0.5.0 and will be'
' removed in 0.6.0.',
DeprecationWarning)
k = self.k
reg = self.regularization
learn_rate = self.learn_rate
Expand All @@ -184,20 +158,7 @@ def fit(self, X, y):
raise ValueError('Must have one label per point.')
self.labels_ = np.arange(len(unique_labels))

# if the init is the default (None), we raise a warning
if self.init is None:
# TODO: replace init=None by init='auto' in v0.6.0 and remove the warning
msg = ("Warning, no init was set (`init=None`). As of version 0.5.0, "
"the default init will now be set to 'auto', instead of the "
"previous identity matrix. If you still want to use the identity "
"matrix as before, set init='identity'. This warning "
"will disappear in v0.6.0, and `init` parameter's default value "
"will be set to 'auto'.")
warnings.warn(msg, ChangedBehaviorWarning)
init = 'auto'
else:
init = self.init
self.components_ = _initialize_components(output_dim, X, y, init,
self.components_ = _initialize_components(output_dim, X, y, self.init,
self.verbose,
random_state=self.random_state)
required_k = np.bincount(label_inds).min()
Expand Down
Loading