class_docstr: CP tensor regression
  
      Learns a low rank CP tensor weight
  
  Parameters
  ----------
  weight_rank : int
      rank of the CP decomposition of the regression weights
  tol : float
      convergence value
  reg_W : int, optional, default is 1
      regularisation on the weights
  n_iter_max : int, optional, default is 100
      maximum number of iteration
  random_state : None, int or RandomState, optional, default is None
  verbose : int, default is 1
      level of verbosity
class_docstr_tok: ["CP","tensor","regression","Learns","a","low","rank","CP","tensor","weight","Parameters","--","--","--","--","--","weight_rank",":","int","rank","of","the","CP","decomposition","of","the","regression","weights","tol",":","float","convergence","value","reg_W",":","int",",","optional",",","default","is","1","regularisation","on","the","weights","n_iter_max",":","int",",","optional",",","default","is","100","maximum","number","of","iteration","random_state",":","None",",","int","or","RandomState",",","optional",",","default","is","None","verbose",":","int",",","default","is","1","level","of","verbosity"]
docstr: Fits the model to the data (X, y)
  
  Parameters
  ----------
  X : ndarray
      tensor data of shape (n_samples, N1, ..., NS)
  y : 1D-array of shape (n_samples, )
      labels associated with each sample
  
  Returns
  -------
  self
docstr_tok: ["Fits","the","model","to","the","data","(","X",",","y",")","Parameters","--","--","--","--","--","X",":","ndarray","tensor","data","of","shape","(","n_samples",",","N1",",","...",",","NS",")","y",":","1D-array","of","shape","(","n_samples",",",")","labels","associated","with","each","sample","Returns","--","--","--","-","self"]
code: def fit(self, X, y):
      """Fits the model to the data (X, y)
  
      Parameters
      ----------
      X : ndarray
          tensor data of shape (n_samples, N1, ..., NS)
      y : 1D-array of shape (n_samples, )
          labels associated with each sample
  
      Returns
      -------
      self
      """
      rng = T.check_random_state(self.random_state)
  
      # Initialise randomly the weights
      W = []
      for i in range(
          1, T.ndim(X)
      ):  # The first dimension of X is the number of samples
          W.append(
              T.tensor(
                  rng.randn(X.shape[i], self.weight_rank),
                  **T.context(X),
              )
          )
  
      # Norm of the weight tensor at each iteration
      norm_W = []
      weights = T.ones(self.weight_rank, **T.context(X))
  
      for iteration in range(self.n_iter_max):
          # Optimise each factor of W
          for i in range(len(W)):
              phi = T.reshape(
                  T.dot(
                      partial_unfold(X, i, skip_begin=1),
                      khatri_rao(W, skip_matrix=i),
                  ),
                  (X.shape[0], -1),
              )
              inv_term = T.dot(
                  T.transpose(phi), phi
              ) + self.reg_W * T.tensor(
                  np.eye(phi.shape[1]), **T.context(X)
              )
              W[i] = T.reshape(
                  T.solve(inv_term, T.dot(T.transpose(phi), y)),
                  (X.shape[i + 1], self.weight_rank),
              )
  
          weight_tensor_ = cp_to_tensor((weights, W))
          norm_W.append(T.norm(weight_tensor_, 2))
  
          # Convergence check
          if iteration > 1:
              weight_evolution = (
                  abs(norm_W[-1] - norm_W[-2]) / norm_W[-1]
              )
  
              if weight_evolution <= self.tol:
                  if self.verbose:
                      print(f"\nConverged in {iteration} iterations")
                  break
  
      self.weight_tensor_ = weight_tensor_
      self.cp_weight_ = (weights, W)
  
      self.vec_W_ = cp_to_vec((weights, W))
      self.n_iterations_ = iteration + 1
      self.norm_W_ = norm_W
  
      return self
  
file_path: tensorly/tensorly/regression/cp_regression.py
imports: import numpy
  from ..base import partial_tensor_to_vec, partial_unfold
  from ..tenalg import khatri_rao
  from ..cp_tensor import cp_to_tensor, cp_to_vec
  from ..None import backend
label_desc: Use image node_id 4 for calling the CPRegressor obj's underlying member method code with example usage: obj.fit(X, y) and returns: self