@@ -354,9 +354,10 @@ def fit(self, X, y, sample_weight=None):
354354 skip_check_array = True ,
355355 )
356356 X = self ._preprocess_X (X , reset = True )
357- # X has already been encoded to a numeric array. Do not call
358- # validate_data(reset=True) again here because ndarray input would
359- # remove feature_names_in_ captured from the original container.
357+ # Feature names were already stored from the original dataframe above.
358+ # Encoding turns X into a plain ndarray with no names.
359+ # validate_data(reset=True) would treat that as "no feature names"
360+ # and delete feature_names_in_.
360361 X , y = validate_data (
361362 self ,
362363 X ,
@@ -497,9 +498,9 @@ def fit(self, X, y, sample_weight=None):
497498 self ._make_estimator (append = False , random_state = random_state )
498499 for i in range (n_more_estimators )
499500 ]
500- # Pass the resolved categorical mask, not the user parameter. After the
501- # forest encodes X, trees only see a float ndarray so values like
502- # "from_dtype" or feature-name lists would silently resolve to None .
501+ # Trees must get the bool mask, not categorical_features="from_dtype" (or
502+ # column names). The forest already turned X into a NumPy array, so trees
503+ # can no longer read dtypes/names and would treat all features as numeric .
503504 if self .is_categorical_ is not None :
504505 for tree in trees :
505506 tree .set_params (categorical_features = self .is_categorical_ )
0 commit comments