RandomForestClassifier class_weight/max_samples interaction can lead to ungraceful and nondescriptive failure

### Describe the bug

The acceptable values for `max_samples` are `(0, 1]`. One possible option for `class_weight` is `balanced_subsample`. However, for values of `max_samples` near zero and `class_weight='balanced_subsample'`, the model fails with an unhelpful error related to having an empty array as an indexer.

This is only likely to come up in a grid search, as it seems unlikely that someone would deliberately force a subsample of zero items. However, it might be useful to have a minimum of one sample, or it might be useful to fail gracefully with a more descriptive error.


### Steps/Code to Reproduce

```python
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier

X, y = load_wine(return_X_y=True)

clf = RandomForestClassifier(max_samples=1e-4, class_weight='balanced_subsample')
clf.fit(X,y)
```
### Expected Results

EITHER:
No error is thrown

OR
```
ValueError: insufficient samples for max_samples value
```

### Actual Results

```
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-4-afd4cda53619> in <module>()
----> 1 clf.fit(X,y)

11 frames
[/usr/local/lib/python3.7/dist-packages/sklearn/ensemble/_forest.py](https://localhost:8080/#) in fit(self, X, y, sample_weight)
    465                     n_samples_bootstrap=n_samples_bootstrap,
    466                 )
--> 467                 for i, t in enumerate(trees)
    468             )
    469 

[/usr/local/lib/python3.7/dist-packages/joblib/parallel.py](https://localhost:8080/#) in __call__(self, iterable)
   1041             # remaining jobs.
   1042             self._iterating = False
-> 1043             if self.dispatch_one_batch(iterator):
   1044                 self._iterating = self._original_iterator is not None
   1045 

[/usr/local/lib/python3.7/dist-packages/joblib/parallel.py](https://localhost:8080/#) in dispatch_one_batch(self, iterator)
    859                 return False
    860             else:
--> 861                 self._dispatch(tasks)
    862                 return True
    863 

[/usr/local/lib/python3.7/dist-packages/joblib/parallel.py](https://localhost:8080/#) in _dispatch(self, batch)
    777         with self._lock:
    778             job_idx = len(self._jobs)
--> 779             job = self._backend.apply_async(batch, callback=cb)
    780             # A job can complete so quickly than its callback is
    781             # called before we get here, causing self._jobs to

[/usr/local/lib/python3.7/dist-packages/joblib/_parallel_backends.py](https://localhost:8080/#) in apply_async(self, func, callback)
    206     def apply_async(self, func, callback=None):
    207         """Schedule a func to be run"""
--> 208         result = ImmediateResult(func)
    209         if callback:
    210             callback(result)

[/usr/local/lib/python3.7/dist-packages/joblib/_parallel_backends.py](https://localhost:8080/#) in __init__(self, batch)
    570         # Don't delay the application, to avoid keeping the input
    571         # arguments in memory
--> 572         self.results = batch()
    573 
    574     def get(self):

[/usr/local/lib/python3.7/dist-packages/joblib/parallel.py](https://localhost:8080/#) in __call__(self)
    261         with parallel_backend(self._backend, n_jobs=self._n_jobs):
    262             return [func(*args, **kwargs)
--> 263                     for func, args, kwargs in self.items]
    264 
    265     def __reduce__(self):

[/usr/local/lib/python3.7/dist-packages/joblib/parallel.py](https://localhost:8080/#) in <listcomp>(.0)
    261         with parallel_backend(self._backend, n_jobs=self._n_jobs):
    262             return [func(*args, **kwargs)
--> 263                     for func, args, kwargs in self.items]
    264 
    265     def __reduce__(self):

[/usr/local/lib/python3.7/dist-packages/sklearn/utils/fixes.py](https://localhost:8080/#) in __call__(self, *args, **kwargs)
    214     def __call__(self, *args, **kwargs):
    215         with config_context(**self.config):
--> 216             return self.function(*args, **kwargs)
    217 
    218 

[/usr/local/lib/python3.7/dist-packages/sklearn/ensemble/_forest.py](https://localhost:8080/#) in _parallel_build_trees(tree, forest, X, y, sample_weight, tree_idx, n_trees, verbose, class_weight, n_samples_bootstrap)
    181                 curr_sample_weight *= compute_sample_weight("auto", y, indices=indices)
    182         elif class_weight == "balanced_subsample":
--> 183             curr_sample_weight *= compute_sample_weight("balanced", y, indices=indices)
    184 
    185         tree.fit(X, y, sample_weight=curr_sample_weight, check_input=False)

[/usr/local/lib/python3.7/dist-packages/sklearn/utils/class_weight.py](https://localhost:8080/#) in compute_sample_weight(class_weight, y, indices)
    157             weight_k = np.take(
    158                 compute_class_weight(
--> 159                     class_weight_k, classes=classes_subsample, y=y_subsample
    160                 ),
    161                 np.searchsorted(classes_subsample, classes_full),

[/usr/local/lib/python3.7/dist-packages/sklearn/utils/class_weight.py](https://localhost:8080/#) in compute_class_weight(class_weight, classes, y)
     51 
     52         recip_freq = len(y) / (len(le.classes_) * np.bincount(y_ind).astype(np.float64))
---> 53         weight = recip_freq[le.transform(classes)]
     54     else:
     55         # user-defined dictionary

IndexError: arrays used as indices must be of integer (or boolean) type
```

### Versions

```shell
System:
    python: 3.7.13 (default, Apr 24 2022, 01:04:09)  [GCC 7.5.0]
executable: /usr/bin/python3
   machine: Linux-5.4.188+-x86_64-with-Ubuntu-18.04-bionic

Python dependencies:
          pip: 21.1.3
   setuptools: 57.4.0
      sklearn: 1.0.2
        numpy: 1.21.6
        scipy: 1.7.3
       Cython: 0.29.30
       pandas: 1.3.5
   matplotlib: 3.2.2
       joblib: 1.1.0
threadpoolctl: 3.1.0
```

COMMENT:
We should probably add a check before launching the actual `fit` to be sure that the condition is met to do so. A nice error message is indeed what we need here.

Labels: Bug, module:ensemble, module:tree