class_docstr: MPCA implementation compatible with scikit-learn
  
  Args:
      var_ratio (float, optional): Percentage of variance explained (between 0 and 1). Defaults to 0.97.
      max_iter (int, optional): Maximum number of iteration. Defaults to 1.
      vectorize (bool): Whether return the transformed/projected tensor in vector. Defaults to False.
      n_components (int): Number of components to keep. Applies only when vectorize=True. Defaults to None.
  
  Attributes:
      proj_mats (list of arrays): A list of transposed projection matrices, shapes (P_1, I_1), ...,
          (P_N, I_N), where P_1, ..., P_N are output tensor shape for each sample.
      idx_order (array-like): The ordering index of projected (and vectorized) features in decreasing variance.
      mean_ (array-like): Per-feature empirical mean, estimated from the training set, shape (I_1, I_2, ..., I_N).
      shape_in (tuple): Input tensor shapes, i.e. (I_1, I_2, ..., I_N).
      shape_out (tuple): Output tensor shapes, i.e. (P_1, P_2, ..., P_N).
  
  Reference:
      Haiping Lu, K.N. Plataniotis, and A.N. Venetsanopoulos, "MPCA: Multilinear Principal Component Analysis of
      Tensor Objects", IEEE Transactions on Neural Networks, Vol. 19, No. 1, Page: 18-39, January 2008. For initial
      Matlab implementation, please go to https://uk.mathworks.com/matlabcentral/fileexchange/26168.
  
  Examples:
      >>> import numpy as np
      >>> from kale.embed.factorization import MPCA
      >>> x = np.random.random((40, 20, 25, 20))
      >>> x.shape
      (40, 20, 25, 20)
      >>> mpca = MPCA()
      >>> x_projected = mpca.fit_transform(x)
      >>> x_projected.shape
      (40, 18, 23, 18)
      >>> x_projected = mpca.transform(x)
      >>> x_projected.shape
      (40, 7452)
      >>> x_projected = mpca.transform(x)
      >>> x_projected.shape
      (40, 50)
      >>> x_rec = mpca.inverse_transform(x_projected)
      >>> x_rec.shape
      (40, 20, 25, 20)
code: def __init__(
      self,
      var_ratio=0.97,
      max_iter=1,
      vectorize=False,
      n_components=None,
  ):
      self.var_ratio = var_ratio
      if max_iter > 0 and isinstance(max_iter, int):
          self.max_iter = max_iter
      else:
          msg = (
              "Number of max iterations must be a positive integer but given %s"
              % max_iter
          )
          logging.error(msg)
          raise ValueError(msg)
      self.proj_mats = []
      self.vectorize = vectorize
      self.n_components = n_components
  
imports: import logging
  import warnings
  import numpy
  from numpy.linalg import multi_dot
  from scipy import linalg
  from sklearn.base import BaseEstimator, TransformerMixin
  from sklearn.metrics.pairwise import pairwise_kernels
  from sklearn.preprocessing import KernelCenterer, LabelBinarizer
  from sklearn.utils.validation import check_is_fitted
  from tensorly.base import fold, unfold
  from tensorly.tenalg import multi_mode_dot
label_desc: Use image node_id 1 to create a new MPCA object from inherited base classes: BaseEstimator, TransformerMixin with example: obj = MPCA(var_ratio, max_iter, vectorize, n_components)