docstr: The conditional mean embedding is estimated as the solution of a regularised regression problem.
  
  This private method function uses cross validation to select the regularisation parameter that
  minimises squared error on the out-of-fold instances. The error is a distance in the RKHS and is
  therefore an MMD-like quantity itself.
docstr_tok: ["The","conditional","mean","embedding","is","estimated","as","the","solution","of","a","regularised","regression","problem",".","This","private","method","function","uses","cross","validation","to","select","the","regularisation","parameter","that","minimises","squared","error","on","the","out-of-fold","instances",".","The","error","is","a","distance","in","the","RKHS","and","is","therefore","an","MMD-like","quantity","itself","."]
code: def _pick_lam(
      self,
      lams: torch.Tensor,
      K: torch.Tensor,
      L: torch.Tensor,
      n_folds: int = 5,
  ) -> torch.Tensor:
      """
      The conditional mean embedding is estimated as the solution of a regularised regression problem.
  
      This private method function uses cross validation to select the regularisation parameter that
      minimises squared error on the out-of-fold instances. The error is a distance in the RKHS and is
      therefore an MMD-like quantity itself.
      """
      n = len(L)
      fold_size = n // n_folds
      K, L = K.type(torch.float64), L.type(torch.float64)
      perm = torch.randperm(n)
      K, L = K[perm][:, perm], L[perm][:, perm]
      losses = torch.zeros_like(lams, dtype=torch.float).to(K.device)
      for fold in range(n_folds):
          inds_oof = list(
              np.arange(n)[
                  (fold * fold_size) : ((fold + 1) * fold_size)
              ]
          )
          inds_if = list(np.setdiff1d(np.arange(n), inds_oof))
          K_if, L_if = K[inds_if][:, inds_if], L[inds_if][:, inds_if]
          n_if = len(K_if)
          L_inv_lams = torch.stack(
              [
                  torch.linalg.inv(
                      L_if + n_if * lam * torch.eye(n_if).to(L.device)
                  )
                  for lam in lams
              ]
          )  # n_lam x n_if x n_if
          KW = torch.einsum("ij,ljk->lik", K_if, L_inv_lams)
          lW = torch.einsum(
              "ij,ljk->lik", L[inds_oof][:, inds_if], L_inv_lams
          )
          lWKW = torch.einsum("lij,ljk->lik", lW, KW)
          lWKWl = torch.einsum(
              "lkj,jk->lk", lWKW, L[inds_if][:, inds_oof]
          )  # n_lam x n_oof
          lWk = torch.einsum(
              "lij,ji->li", lW, K[inds_if][:, inds_oof]
          )  # n_lam x n_oof
          kxx = torch.ones_like(lWk).to(lWk.device) * torch.max(K)
          losses += (lWKWl + kxx - 2 * lWk).sum(-1)
      return lams[torch.argmin(losses)]
  
file_path: alibi-detect/alibi_detect/cd/pytorch/context_aware.py
imports: import logging
  import numpy
  import torch
  from typing import Callable, Dict, Optional, Tuple, Union
  from alibi_detect.cd.base import BaseContextMMDDrift
  from alibi_detect.utils.pytorch import get_device
  from alibi_detect.utils.pytorch.kernels import GaussianRBF
  from alibi_detect.utils.warnings import deprecated_alias
  from alibi_detect.utils.frameworks import Framework
  from alibi_detect.cd._domain_clf import _SVCDomainClf
  from alibi_detect.utils._types import TorchDeviceType
  from tqdm import tqdm
label_desc: Use image node_id 4 for calling the ContextMMDDriftTorch obj's underlying member method code with example usage: obj._pick_lam(lams, K, L, n_folds) and returns: lams