Source code for kalelinear.transformer._jda

# =============================================================================
# @author: Shuo Zhou, The University of Sheffield, szhou20@sheffield.ac.uk
# =============================================================================
"""Joint and Balanced Distribution Adaptation."""

from numbers import Real

import numpy as np
from sklearn.utils._param_validation import Interval

from kalelinear.transformer._base import _num_features, BaseMMDDomainTransformer
from kalelinear.utils import centering_matrix, mmd_coef


[docs] class JDA(BaseMMDDomainTransformer): """Joint Distribution Adaptation. ``covariates`` represent binary domain labels of length ``n_samples``. They must contain both source and target domains during :meth:`fit`. ``target_covariate`` selects which label is treated as the target domain. ``covariate_encoder`` is unsupported because JDA expects domain labels rather than general categorical side information. """ def __init__( self, n_components=None, kernel="linear", lambda_=1.0, covariate_encoder=None, eigen_solver="auto", tol=0, max_iter=None, iterated_power="auto", remove_zero_eig=False, scale_components=False, random_state=None, copy=True, n_jobs=None, **kwargs, ): if "mu" in kwargs: raise TypeError("JDA.__init__() got an unexpected keyword argument 'mu'") super().__init__( n_components=n_components, lambda_=lambda_, kernel=kernel, kernel_params=kwargs or None, covariate_encoder=covariate_encoder, eigen_solver=eigen_solver, tol=tol, max_iter=max_iter, iterated_power=iterated_power, remove_zero_eig=remove_zero_eig, scale_components=scale_components, random_state=random_state, copy=copy, n_jobs=n_jobs, ) def _joint_mmd_mu(self): return 0.5 def _make_eigenproblem(self, x_kernel_matrix, context): mmd_matrix = self._make_marginal_mmd_matrix(context) if context.ys is not None and context.yt is not None: mmd_matrix = mmd_coef( context.ns, context.nt, context.ys, context.yt, kind="joint", mu=self._joint_mmd_mu(), ) mmd_matrix[np.isnan(mmd_matrix)] = 0 h = centering_matrix(_num_features(x_kernel_matrix), x_kernel_matrix.dtype) identity = np.eye(_num_features(x_kernel_matrix), dtype=x_kernel_matrix.dtype) obj = x_kernel_matrix @ mmd_matrix @ x_kernel_matrix + self.lambda_ * identity st = x_kernel_matrix @ h @ x_kernel_matrix return obj, st
[docs] class BDA(JDA): """Balanced Distribution Adaptation. ``covariates`` represent binary domain labels of length ``n_samples``. They must contain both source and target domains during :meth:`fit`. ``target_covariate`` selects which label is treated as the target domain. ``covariate_encoder`` is unsupported because BDA expects domain labels rather than general categorical side information. """ _parameter_constraints: dict = { **BaseMMDDomainTransformer._parameter_constraints, "mu": [Interval(Real, 0, 1, closed="both")], } def __init__( self, n_components=None, kernel="linear", lambda_=1.0, mu=0.5, covariate_encoder=None, eigen_solver="auto", tol=0, max_iter=None, iterated_power="auto", remove_zero_eig=False, scale_components=False, random_state=None, copy=True, n_jobs=None, **kwargs, ): if mu < 0 or mu > 1: raise ValueError("mu should be in the range [0, 1]") self.mu = mu super().__init__( n_components=n_components, kernel=kernel, lambda_=lambda_, covariate_encoder=covariate_encoder, eigen_solver=eigen_solver, tol=tol, max_iter=max_iter, iterated_power=iterated_power, remove_zero_eig=remove_zero_eig, scale_components=scale_components, random_state=random_state, copy=copy, n_jobs=n_jobs, **kwargs, ) def _joint_mmd_mu(self): return self.mu