From da23123e9ddddb799b310e5c53f6b53ad24806ea Mon Sep 17 00:00:00 2001 From: Felipe Date: Sun, 28 Jun 2026 20:00:00 -0400 Subject: [PATCH] fix type in converters --- .../converters/category/feature_selection.py | 64 ++++++++++++++++++- .../scikit_learn/generic_univariate_select.py | 19 ------ .../converters/scikit_learn/select_fdr.py | 19 ------ .../converters/scikit_learn/select_fpr.py | 19 ------ .../converters/scikit_learn/select_fwe.py | 19 ------ .../converters/scikit_learn/select_k_best.py | 19 ------ .../scikit_learn/select_percentile.py | 19 ------ .../scikit_learn/variance_threshold.py | 41 ++++++++++-- 8 files changed, 100 insertions(+), 119 deletions(-) diff --git a/DashAI/back/converters/category/feature_selection.py b/DashAI/back/converters/category/feature_selection.py index 9b7171433..f090ae69a 100644 --- a/DashAI/back/converters/category/feature_selection.py +++ b/DashAI/back/converters/category/feature_selection.py @@ -1,8 +1,12 @@ -from typing import Final +from typing import TYPE_CHECKING, Final, Union from DashAI.back.converters.base_converter import BaseConverter from DashAI.back.core.utils import MultilingualString from DashAI.back.static.icons import Icon +from DashAI.back.types.dashai_data_type import DashAIDataType + +if TYPE_CHECKING: + from DashAI.back.dataloaders.classes.dashai_dataset import DashAIDataset class FeatureSelectionConverter(BaseConverter): @@ -15,6 +19,10 @@ class FeatureSelectionConverter(BaseConverter): Use these converters to reduce overfitting, speed up training, and improve model interpretability by retaining only the most informative features. + + These converters only drop columns; the retained columns keep their + original values untouched, so their data types must be preserved instead of + being coerced to float. """ CATEGORY = MultilingualString( @@ -26,3 +34,57 @@ class FeatureSelectionConverter(BaseConverter): ) ICON: Final[str] = Icon.FilterList.value COLOR: Final[str] = "rgb(255, 206, 86)" + + def fit( + self, x: "DashAIDataset", y: Union["DashAIDataset", None] = None + ) -> "FeatureSelectionConverter": + """Fit the selector while remembering the input column types. + + Feature selection only keeps a subset of the input columns without + modifying their values, so the original types are captured here to be + returned later by ``get_output_type``. Types are recorded during ``fit`` + (rather than ``transform``) because scikit-learn auto-wraps ``transform`` + on subclasses and would coerce its output back to a pandas DataFrame. + + Parameters + ---------- + x : DashAIDataset + The input dataset to fit the selector on. + y : DashAIDataset, optional + Target values for the supervised selectors. Defaults to None. + + Returns + ------- + FeatureSelectionConverter + The fitted selector instance (self). + """ + if hasattr(x, "types") and x.types is not None: + self._input_types = dict(x.types) + return super().fit(x, y) + + def get_output_type(self, column_name: str = None) -> DashAIDataType: + """Return the original DashAI data type of a retained column. + + Since feature selection leaves the retained columns' values unchanged, + the output type matches the input type of that column. + + Parameters + ---------- + column_name : str, optional + The name of the retained column. Defaults to None. + + Returns + ------- + DashAIDataType + The original type of the column. Falls back to ``float64`` when the + input type is unknown (feature selectors only operate on numbers). + """ + input_types = getattr(self, "_input_types", None) + if input_types is not None and column_name in input_types: + return input_types[column_name] + + import pyarrow as pa + + from DashAI.back.types.value_types import Float + + return Float(arrow_type=pa.float64()) diff --git a/DashAI/back/converters/scikit_learn/generic_univariate_select.py b/DashAI/back/converters/scikit_learn/generic_univariate_select.py index 7799d344e..4ce7f2324 100644 --- a/DashAI/back/converters/scikit_learn/generic_univariate_select.py +++ b/DashAI/back/converters/scikit_learn/generic_univariate_select.py @@ -14,7 +14,6 @@ ) from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -83,21 +82,3 @@ class GenericUnivariateSelect( ) IMAGE_PREVIEW = "generic_univariate_select.png" metadata = {"allowed_types": [Float, Integer], "allowed_dtypes": []} - - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) diff --git a/DashAI/back/converters/scikit_learn/select_fdr.py b/DashAI/back/converters/scikit_learn/select_fdr.py index a37762be2..0dc935952 100644 --- a/DashAI/back/converters/scikit_learn/select_fdr.py +++ b/DashAI/back/converters/scikit_learn/select_fdr.py @@ -5,7 +5,6 @@ from DashAI.back.core.schema_fields import float_field, schema_field from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -104,21 +103,3 @@ def __init__(self, **kwargs): schema fields. Forwarded to the underlying scikit-learn class. """ super().__init__(**kwargs) - - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) diff --git a/DashAI/back/converters/scikit_learn/select_fpr.py b/DashAI/back/converters/scikit_learn/select_fpr.py index 84d966955..8097b8d52 100644 --- a/DashAI/back/converters/scikit_learn/select_fpr.py +++ b/DashAI/back/converters/scikit_learn/select_fpr.py @@ -5,7 +5,6 @@ from DashAI.back.core.schema_fields import float_field, schema_field from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -95,21 +94,3 @@ def __init__(self, **kwargs): schema fields. Forwarded to the underlying scikit-learn class. """ super().__init__(**kwargs) - - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) diff --git a/DashAI/back/converters/scikit_learn/select_fwe.py b/DashAI/back/converters/scikit_learn/select_fwe.py index 5f187b516..4efd800eb 100644 --- a/DashAI/back/converters/scikit_learn/select_fwe.py +++ b/DashAI/back/converters/scikit_learn/select_fwe.py @@ -5,7 +5,6 @@ from DashAI.back.core.schema_fields import float_field, schema_field from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -96,24 +95,6 @@ class SelectFwe(FeatureSelectionConverter, SklearnWrapper, SelectFweOperation): IMAGE_PREVIEW = "select_fwe.png" metadata = {"allowed_types": [Float, Integer], "allowed_dtypes": []} - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) - def __init__(self, **kwargs): """Initialize the SelectFwe converter. diff --git a/DashAI/back/converters/scikit_learn/select_k_best.py b/DashAI/back/converters/scikit_learn/select_k_best.py index dc78135a8..1bffc79f7 100644 --- a/DashAI/back/converters/scikit_learn/select_k_best.py +++ b/DashAI/back/converters/scikit_learn/select_k_best.py @@ -10,7 +10,6 @@ ) from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -83,24 +82,6 @@ class SelectKBest(FeatureSelectionConverter, SklearnWrapper, SelectKBestOperatio IMAGE_PREVIEW = "select_k_best.png" metadata = {"allowed_types": [Float, Integer], "allowed_dtypes": []} - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) - def __init__(self, **kwargs): """Initialize the SelectKBest converter. diff --git a/DashAI/back/converters/scikit_learn/select_percentile.py b/DashAI/back/converters/scikit_learn/select_percentile.py index c5346129d..7054e237e 100644 --- a/DashAI/back/converters/scikit_learn/select_percentile.py +++ b/DashAI/back/converters/scikit_learn/select_percentile.py @@ -5,7 +5,6 @@ from DashAI.back.core.schema_fields import int_field, schema_field from DashAI.back.core.schema_fields.base_schema import BaseSchema from DashAI.back.core.utils import MultilingualString -from DashAI.back.types.dashai_data_type import DashAIDataType from DashAI.back.types.value_types import Float, Integer @@ -87,24 +86,6 @@ class SelectPercentile( IMAGE_PREVIEW = "select_percentile.png" metadata = {"allowed_types": [Float, Integer], "allowed_dtypes": []} - def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. - - Parameters - ---------- - column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. - - Returns - ------- - DashAIDataType - A Float type backed by ``pyarrow.float64()``. - """ - import pyarrow as pa - - return Float(arrow_type=pa.float64()) - def __init__(self, **kwargs): """Initialize the SelectPercentile converter. diff --git a/DashAI/back/converters/scikit_learn/variance_threshold.py b/DashAI/back/converters/scikit_learn/variance_threshold.py index ca741f530..6ad002e5c 100644 --- a/DashAI/back/converters/scikit_learn/variance_threshold.py +++ b/DashAI/back/converters/scikit_learn/variance_threshold.py @@ -88,20 +88,53 @@ class VarianceThreshold( zh="方差阈值", ) + def fit(self, x, y=None): + """Fit the selector while remembering the input column types. + + VarianceThreshold only drops low-variance columns without modifying the + retained columns' values, so their original types are captured here to + be returned later by ``get_output_type`` instead of coercing to float. + Types are recorded during ``fit`` (rather than ``transform``) because + scikit-learn auto-wraps ``transform`` on subclasses and would coerce its + output back to a pandas DataFrame. + + Parameters + ---------- + x : DashAIDataset + The input dataset to fit the selector on. + y : DashAIDataset, optional + Not used by this unsupervised selector. Defaults to None. + + Returns + ------- + VarianceThreshold + The fitted selector instance (self). + """ + if hasattr(x, "types") and x.types is not None: + self._input_types = dict(x.types) + return super().fit(x, y) + def get_output_type(self, column_name: str = None) -> DashAIDataType: - """Return the DashAI data type produced by this converter for a column. + """Return the original DashAI data type of a retained column. + + Since the selection leaves the retained columns' values unchanged, the + output type matches the input type of that column. Parameters ---------- column_name : str, optional - Not used; all output columns share the - same type. Defaults to None. + The name of the retained column. Defaults to None. Returns ------- DashAIDataType - A Float type backed by ``pyarrow.float64()``. + The original type of the column. Falls back to ``float64`` when the + input type is unknown (the selector only operates on numbers). """ + input_types = getattr(self, "_input_types", None) + if input_types is not None and column_name in input_types: + return input_types[column_name] + import pyarrow as pa return Float(arrow_type=pa.float64())