class_docstr: Base class for the sRP ensemble family
class_docstr_tok: ["Base","class","for","the","sRP","ensemble","family"]
code: def _generate_subspaces(self, features: list):
      n_features = len(features)
  
      self._subspaces = [None] * self.n_models
  
      if self.training_method != self._TRAIN_RESAMPLING:
          # Set subspaces - This only applies to subspaces and random patches options
  
          # 1. Calculate the number of features k
          if (
              isinstance(self.subspace_size, float)
              and 0.0 < self.subspace_size <= 1
          ):
              k = self.subspace_size
              percent = (1.0 + k) / 1.0 if k < 0 else k
              k = round(n_features * percent)
              if k < 2:
                  k = round(n_features * percent) + 1
          elif (
              isinstance(self.subspace_size, int)
              and self.subspace_size > 2
          ):
              # k is a fixed number of features
              k = self.subspace_size
          elif self.subspace_size == self._FEATURES_SQRT:
              # k is sqrt(M)+1
              k = round(math.sqrt(n_features)) + 1
          elif self.subspace_size == self._FEATURES_SQRT_INV:
              # k is M-(sqrt(M)+1)
              k = n_features - round(math.sqrt(n_features)) + 1
          else:
              raise ValueError(
                  f"Invalid subspace_size: {self.subspace_size}.\n"
                  f"Valid options are: int [2, M], float (0., 1.],"
                  f" {self._FEATURES_SQRT}, {self._FEATURES_SQRT_INV}"
              )
          if k < 0:
              # k is negative, calculate M - k
              k = n_features + k
  
          # 2. Generate subspaces. The subspaces is a 2D array of shape
          # (n_estimators, k) where each row contains the k-feature indices
          # to be used by each estimator.
          if k != 0 and k < n_features:
              # For low dimensionality it is better to avoid more than
              # 1 classifier with the same subspace, thus we generate all
              # possible combinations of subsets of features and select
              # without replacement.
              # n_features is the total number of features and k is the
              # actual size of a subspace.
              if n_features <= 20 or k < 2:
                  if k == 1 and n_features > 2:
                      k = 2
                  # Generate n_models subspaces from all possible
                  # feature combinations of size k
                  self._subspaces = []
                  for i, combination in enumerate(
                      itertools.cycle(
                          itertools.combinations(features, k)
                      )
                  ):
                      if i == self.n_models:
                          break
                      self._subspaces.append(list(combination))
              # For high dimensionality we can't generate all combinations
              # as it is too expensive (memory). On top of that, the chance
              # of repeating a subspace is lower, so we randomly generate
              # subspaces without worrying about repetitions.
              else:
                  self._subspaces = [
                      random_subspace(
                          all_features=features, k=k, rng=self._rng
                      )
                      for _ in range(self.n_models)
                  ]
          else:
              # k == 0 or k > n_features (subspace size is larger than the
              # number of features), then default to re-sampling
              self.training_method = self._TRAIN_RESAMPLING
  
imports: from __future__ import annotations
  import collections
  import itertools
  import math
  import random
  import numpy
  from river import base
  from river.drift import ADWIN
  from river.metrics import MAE, Accuracy
  from river.metrics.base import ClassificationMetric, Metric, RegressionMetric
  from river.tree import HoeffdingTreeClassifier, HoeffdingTreeRegressor
  from river.utils.random import poisson
label_desc: Use image node_id 7 for calling the BaseSRPEnsemble obj's underlying member method code with example usage: obj._generate_subspaces(features) without return types