hscredit.core.selectors.null_selector 源代码

"""缺失值筛选器.

移除缺失率过高的特征。

**参考样例**

>>> from hscredit.core.selectors import NullSelector
>>> import pandas as pd
>>> import numpy as np
>>> X = pd.DataFrame({
...     'a': [1, 2, np.nan, 4, 5],     # 缺失率20%
...     'b': [1, 2, 3, 4, 5],           # 无缺失
...     'c': [np.nan, np.nan, np.nan, np.nan, np.nan]  # 全部缺失
... })
>>> selector = NullSelector(threshold=0.5)  # 移除缺失率>50%的特征
>>> selector.fit(X)
>>> print(selector.selected_features_)
['a', 'b']
"""

from typing import Union, List, Optional, Dict, Any
import numpy as np
import pandas as pd

from .base import BaseFeatureSelector


def _compute_null_feature(task):
    """计算单列缺失率。"""
    feature, series = task
    return feature, series.isnull().mean()


[文档] class NullSelector(BaseFeatureSelector): """缺失率筛选器. 移除缺失率高于阈值的特征。 用于过滤掉数据质量较差的特征。 **参数** :param threshold: 缺失率阈值,默认为0.95 - 0.95: 移除缺失率超过95%的特征 - 范围: 0-1之间的浮点数 **参考样例** :: >>> from hscredit.core.selectors import NullSelector >>> import pandas as pd >>> import numpy as np >>> X = pd.DataFrame({ ... 'a': [1, 2, np.nan, 4, 5], ... 'b': [1, 2, 3, 4, 5], ... 'c': [np.nan, np.nan, np.nan, np.nan, np.nan] ... }) >>> selector = NullSelector(threshold=0.5) >>> selector.fit(X) >>> print(selector.selected_features_) ['a', 'b'] """ method_name = "缺失率筛选" def __init__( self, threshold: float = 0.95, target: str = "target", include: Optional[List[str]] = None, exclude: Optional[List[str]] = None, force_drop: Optional[List[str]] = None, n_jobs: Optional[Union[int, float]] = -1, binner: Optional[Any] = None, binning_params: Optional[Dict[str, Any]] = None, parallel_backend: Optional[str] = None, parallel_config: Optional[Dict[str, Any]] = None, ): super().__init__( target=target, threshold=threshold, include=include, exclude=exclude, force_drop=force_drop, n_jobs=n_jobs, binner=binner, binning_params=binning_params, parallel_backend=parallel_backend, parallel_config=parallel_config, ) def _fit_impl( self, X: pd.DataFrame, y: Optional[Union[pd.Series, np.ndarray]], ) -> None: """拟合缺失率筛选器。 :param X: 输入特征DataFrame :param y: 目标变量(此筛选器不需要) """ self._get_feature_names(X) self._validate_parallel_configuration() null_rates = X.isnull().mean(axis=0).reindex(X.columns) self.scores_ = null_rates # 选择缺失率低于阈值的特征 selected_mask = null_rates < self.threshold self.selected_features_ = X.columns[selected_mask].tolist() # 构建详细的dropped_记录,包含缺失率数值 dropped_cols = X.columns[~selected_mask].tolist() if len(dropped_cols) > 0: self.dropped_ = pd.DataFrame( { "特征": dropped_cols, "剔除原因": [f"缺失率({null_rates[col]:.2%}) >= 阈值({self.threshold:.2%})" for col in dropped_cols], "缺失率": [null_rates[col] for col in dropped_cols], "阈值": [self.threshold] * len(dropped_cols), } ) else: self.dropped_ = pd.DataFrame(columns=["特征", "剔除原因", "缺失率", "阈值"])