ClassifierChain does not accept NaN values even when base estimator supports them

### Describe the bug

I am working on a multilabel classification problem using ClassifierChain with RandomForestClassifier as the base estimator.
I have encountered an issue where ClassifierChain raises a ValueError when the input data X contains np.nan values, even though RandomForestClassifier can handle np.nan values natively.
When I use RandomForestClassifier alone, it processes np.nan values without any problems, thanks to its internal tree splitting mechanism that supports missing values. Similarly, when I use MultiOutputClassifier with RandomForestClassifier, I do not encounter any errors with np.nan values.
However, when I use ClassifierChain, I receive an error during hyperparameter tuning.
Since the base estimator can handle np.nan values, I expected ClassifierChain to pass the data through without additional checks. It seems inconsistent that ClassifierChain does not support missing values when the base estimator does. 
I'm wondering if this is the intended behavior of ClassifierChain. If not, could it be updated to support missing values when the base estimator does? Alternatively, is there a recommended workaround that doesn't involve imputing or dropping missing values?

### Steps/Code to Reproduce

```py
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.multioutput import ClassifierChain, MultiOutputClassifier


X = np.array([np.nan, -1, np.nan, 1]).reshape(-1, 1) # Input data with NaN values
y = np.array([[0, 1], [0, 0], [1, 0], [1, 1]])

base_clf = RandomForestClassifier() # Base classifier

clf_br = MultiOutputClassifier(base_clf) # MultiOutputClassifier (Binary Relevance) - works fine with NaN
clf_br.fit(X, y)  # No error

clf_chain = ClassifierChain(base_clf) # ClassifierChain - raises error
clf_chain.fit(X, y)  # Raises ValueError about NaNs
```

### Expected Results

No error is thrown when using ClassifierChain with RandomForestClassifier as the base estimator, since RandomForestClassifier handles np.nan values natively without any issues. The model should fit and train successfully, just as it does with MultiOutputClassifier.

### Actual Results

Instead, when fitting the ClassifierChain, I receive the following error message:
```py-tb
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 5
      2 clf_chain = ClassifierChain(base_clf)
      4 # Fitting the model (this will likely raise an error due to NaN in X)
----> 5 clf_chain.fit(X, y)

File <env_path>/python3.12/site-packages/sklearn/base.py, line=1472, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
   1466     estimator._validate_params()
   1468 with config_context(
   1469     skip_parameter_validation=(
   1470         prefer_skip_nested_validation or global_skip_validation
   1471     )
   1472 ):
-> 1473     return fit_method(estimator, *args, **kwargs)

File <env_path>/python3.12/site-packages/sklearn/multioutput.py, line=1029, in ClassifierChain.fit(self, X, Y, **fit_params)
   1005 """Fit the model to data matrix X and targets Y.
   1006 
   1007 Parameters
   (...)
   1026     Class instance.
   1027 """
   1028 _raise_for_params(fit_params, self, "fit")
-> 1030 super().fit(X, Y, **fit_params)
   1031 self.classes_ = [estimator.classes_ for estimator in self.estimators_]
   1032 return self

File <env_path>/python3.12/site-packages/sklearn/multioutput.py, line=720, in _BaseChain.fit(self, X, Y, **fit_params)
    699 @abstractmethod
    700 def fit(self, X, Y, **fit_params):
    701     """Fit the model to data matrix X and targets Y.
    702 
    703     Parameters
   (...)
    719         Returns a fitted instance.
    720     """
--> 721     X, Y = self._validate_data(X, Y, multi_output=True, accept_sparse=True)
    723     random_state = check_random_state(self.random_state)
    724     self.order_ = self.order

File <env_path>/python3.12/site-packages/sklearn/base.py, line=649, in BaseEstimator._validate_data(self, X, y, reset, validate_separately, cast_to_ndarray, **check_params)
    648         y = check_array(y, input_name="y", **check_y_params)
    649     else:
--> 650         X, y = check_X_y(X, y, **check_params)
    651     out = X, y
    653 if not no_val_X and check_params.get("ensure_2d", True):

File <env_path>/python3.12/site-packages/sklearn/utils/validation.py, line=1300, in check_X_y(X, y, accept_sparse, accept_large_sparse, dtype, order, copy, force_writeable, force_all_finite, ensure_2d, allow_nd, multi_output, ensure_min_samples, ensure_min_features, y_numeric, estimator)
   1296         estimator_name = _check_estimator_name(estimator)
   1297     raise ValueError(
   1298         f"{estimator_name} requires y to be passed, but the target y is None"
   1299     )
-> 1301 X = check_array(
   1302     X,
   1303     accept_sparse=accept_sparse,
   1304     accept_large_sparse=accept_large_sparse,
   1305     dtype=dtype,
   1306     order=order,
   1307     copy=copy,
   1308     force_writeable=force_writeable,
   1309     force_all_finite=force_all_finite,
   1310     ensure_2d=ensure_2d,
   1311     allow_nd=allow_nd,
   1312     ensure_min_samples=ensure_min_samples,
   1313     ensure_min_features=ensure_min_features,
   1314     estimator=estimator,
   1315     input_name="X",
   1316 )
   1318 y = _check_y(y, multi_output=multi_output, y_numeric=y_numeric, estimator=estimator)
   1320 check_consistent_length(X, y)

File <env_path>/python3.12/site-packages/sklearn/utils/validation.py, line=1063, in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_writeable, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)
   1058     raise ValueError(
   1059         "Found array with dim %d. %s expected <= 2."
   1060         % (array.ndim, estimator_name)
   1061     )
   1063 if force_all_finite:
-> 1064     _assert_all_finite(
   1065         array,
   1066         input_name=input_name,
   1067         estimator_name=estimator_name,
   1068         allow_nan=force_all_finite == "allow-nan",
   1069     )
   1071 if copy:
   1072     if _is_numpy_namespace(xp):
   1073         # only make a copy if `array` and `array_orig` may share memory`

File <env_path>/python3.12/site-packages/sklearn/utils/validation.py, line=122, in _assert_all_finite(X, allow_nan, msg_dtype, estimator_name, input_name)
    120 if first_pass_isfinite:
    121     return
--> 123 _assert_all_finite_element_wise(
    124     X,
    125     xp=xp,
    126     allow_nan=allow_nan,
    127     msg_dtype=msg_dtype,
    128     estimator_name=estimator_name,
    129     input_name=input_name,
    130 )

File <env_path>/python3.12/site-packages/sklearn/utils/validation.py, line=171, in _assert_all_finite_element_wise(X, xp, allow_nan, msg_dtype, estimator_name, input_name)
    155 if estimator_name and input_name == "X" and has_nan_error:
    156     # Improve the error message on how to handle missing values in
    157     # scikit-learn.
    158     msg_err += (
    159         f"\n{estimator_name} does not accept missing values"
    160         " encoded as NaN natively. For supervised learning, you might want"
   (...)
    170         "#estimators-that-handle-nan-values"
    171     )
--> 172 raise ValueError(msg_err)

ValueError: Input X contains NaN.
ClassifierChain does not accept missing values encoded as NaN natively. For supervised learning, you might want to consider sklearn.ensemble.HistGradientBoostingClassifier and Regressor which accept missing values encoded as NaNs natively. Alternatively, it is possible to preprocess the data, for instance by using an imputer transformer in a pipeline or drop samples with missing values. See https://scikit-learn.org/stable/modules/impute.html You can find a list of all estimators that handle NaN values at the following page: https://scikit-learn.org/stable/modules/impute.html#estimators-that-handle-nan-values
```

### Versions

```shell
System and Versions:

Python version: 3.12.5 (packaged by conda-forge)
scikit-learn version: 1.5.1
```

COMMENT:
I attempted to use ensure_all_finite="allow-nan" in two different ways, but I encountered issues with both.

I tried passing the ensure_all_finite argument in the fit() method:

```
from sklearn import set_config
from sklearn.multioutput import ClassifierChain
from sklearn.ensemble import RandomForestClassifier
import numpy as np

set_config(enable_metadata_routing=True)

X = np.array([np.nan, -1, np.nan, 1]).reshape(-1, 1)
y = np.array([[0, 1], [0, 0], [1, 0], [1, 1]])

base_clf = RandomForestClassifier()
clf_chain = ClassifierChain(base_clf)
clf_chain.fit(X, y, ensure_all_finite="allow-nan")
```

This gave the same error I reported in my previous comment, as if the code did not take into account my assignment of that parameter:

> ValueError: Input X contains NaN.
> ClassifierChain does not accept missing values encoded as NaN natively. For supervised learning, you might want to consider sklearn.ensemble.HistGradientBoostingClassifier and Regressor which accept missing values encoded as NaNs natively. Alternatively, it is possible to preprocess the data, for instance by using an imputer transformer in a pipeline or drop samples with missing values. See https://scikit-learn.org/stable/modules/impute.html You can find a list of all estimators that handle NaN values at the following page: https://scikit-learn.org/stable/modules/impute.html#estimators-that-handle-nan-values

It seems that ClassifierChain is still performing a validation on X, even though the base estimator (RandomForestClassifier) supports NaN values. 

For completeness, I also tried passing ensure_all_finite="allow-nan" directly in the ClassifierChain constructor:

```
from sklearn import set_config
from sklearn.multioutput import ClassifierChain
from sklearn.ensemble import RandomForestClassifier
import numpy as np

set_config(enable_metadata_routing=True)

X = np.array([np.nan, -1, np.nan, 1]).reshape(-1, 1)
y = np.array([[0, 1], [0, 0], [1, 0], [1, 1]])

clf_chain = ClassifierChain(RandomForestClassifier(), ensure_all_finite="allow-nan")
clf_chain.fit(X, y)
```
This resulted in the following error:

> TypeError: ClassifierChain.__init__() got an unexpected keyword argument 'ensure_all_finite'

Given that both approaches have failed, I was wondering if it might be necessary to modify the source code of ClassifierChain to skip the validation of X during .fit() (as is done in MultiOutputClassifier), or if there’s any workaround I can use to make ClassifierChain work with missing values when the base estimator handles them.

Labels: Bug