news 2026/9/7 16:43:34

数据建模实战:缺失值与异常值处理的系统化方法与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据建模实战:缺失值与异常值处理的系统化方法与避坑指南

1. 从一次真实的建模翻车说起:缺失值与异常值的“隐形杀手”

去年带队参加一个省级数学建模竞赛,题目是关于城市共享单车使用量的预测。我们团队信心满满,用上了当时刚学的随机森林和XGBoost,特征工程也做了不少,自以为模型稳了。结果,提交的预测结果和真实数据一对比,误差大得离谱,排名直接掉到了后半区。赛后复盘,我们花了整整两天时间,才在数据清洗阶段找到了罪魁祸首:对缺失值和异常值的处理过于草率

我们当时拿到的是某个平台脱敏后的骑行订单数据,看起来挺“干净”的。对于缺失值,我们简单地用整列的均值填充了;对于异常值,我们看了一眼数据分布,觉得那些特别大的骑行时长(比如超过24小时)肯定是“坏数据”,直接一刀切地删除了。就是这个看似“标准”的操作,导致了系统性偏差。事后分析发现,那些“异常”的长时长订单,很多发生在节假日或景区周边,是真实的用户行为模式;而用均值填充缺失的“天气”字段,则完全抹平了雨天和晴天的骑行量差异。模型学到的,是一个被我们“修正”过的、失真的世界,预测不准是必然的。

这次教训让我深刻认识到,在数学建模,尤其是像“攻坚战”这种强调实战和深度的系列中,数据预处理绝不是可有可无的“前戏”,而是决定模型上限的基石。缺失值和异常值处理,更是基石中最容易松动、也最致命的两块砖。处理得好,它们是模型稳健性的保障;处理不当,它们就是埋在模型里的“地雷”,随时可能让所有复杂的算法努力付诸东流。今天,我们就来系统性地拆解这两个“隐形杀手”,把这块基石打牢。

2. 缺失值处理:不仅仅是“填平”那么简单

面对数据中的空白(NaN, Null, 空字符串等),新手最常见的冲动就是赶紧找个值填上,让程序能跑起来。但资深从业者会先停下来问三个问题:为什么缺失?缺失得多吗?缺失的模式是什么?这三个问题的答案,直接决定了后续的处理策略。

2.1 诊断缺失:理解缺失机制(MCAR, MAR, MNAR)

在动手处理之前,必须判断缺失的机制,这是选择方法的理论依据。

  1. 完全随机缺失(MCAR):数据缺失与否,与任何已观测或未观测的变量都无关。就像随机洒在数据集上的“胡椒粉”。例如,因服务器临时故障随机丢失了几条记录。这是最理想的情况,但现实中很少见。
  2. 随机缺失(MAR):数据缺失与否,与已观测到的其他变量有关,但与未观测到的自身真实值无关。例如,一份收入调查中,高收入人群更可能拒绝回答收入项(缺失与否与“职业”这个已观测变量有关),但具体缺失的那个收入值本身不决定它是否缺失。这是最常见且相对可处理的假设。
  3. 非随机缺失(MNAR):数据缺失与否,与未观测到的真实值本身有关。例如,在心理健康调查中,越是抑郁程度高的人,越可能拒绝填写抑郁自评量表。这种情况下,缺失本身就包含了重要信息,处理起来最棘手。

如何初步判断?一个实用的方法是进行简单的统计分析。比如,你可以将数据集按某个可能相关的特征(如性别、用户等级)分组,然后比较各组间的缺失率是否有显著差异。如果有,则很可能不是MCAR。对于MNAR,则需要结合业务知识进行推断。

注意:很多教程和代码一上来就教填充方法,却忽略了缺失机制的诊断。跳过这一步,就像医生不问诊直接开药,风险极高。在数学建模中,对于关键特征,花时间做缺失模式分析是绝对值得的。

2.2 删除法:最简单,但代价可能最大

当缺失数据占比很低,且满足MCAR假设时,直接删除缺失行或列是可行的。

  • 列表删除:直接删除含有缺失值的任何一行。在Python的pandas中就是df.dropna()

    # 直接删除任何包含缺失值的行 df_dropped = df.dropna() # 删除在特定列(如‘income’)上有缺失的行 df_dropped = df.dropna(subset=['income'])

    代价:可能丢失大量非缺失信息,导致样本量锐减,特别是当特征很多时,很容易出现“任何一行都有缺失”的情况,造成数据浪费。

  • 成对删除:在计算相关系数矩阵或协方差矩阵时,只使用每对变量都非缺失的观测值。这能保留更多数据用于不同分析,但会导致不同分析基于的样本子集不同,可能使结果难以比较。

实操心得:我个人的原则是,只有当缺失比例低于5%,且通过分析确信其为MCAR时,才会考虑删除整行。对于特征(列)的删除更为谨慎,只有当该特征缺失率超过30%-40%,且并非核心预测变量时,才会考虑。在时间序列数据中,删除要格外小心,以免破坏时间连续性。

2.3 单变量填充:快速但可能引入偏差

这是最常用的方法,用某个统计量替代同一特征下的所有缺失值。

方法计算方式适用场景优点缺点与风险
均值/中位数/众数填充df['col'].fillna(df['col'].mean())数值型,分布近似对称(用均值)或有偏(用中位数);分类型(用众数)简单快速,不减少样本量扭曲特征分布,低估方差,破坏变量间相关性。对异常值敏感(均值)。
前后向填充df['col'].fillna(method='ffill')时间序列数据,缺失具有连续性保持时间顺序,简单可能传播错误值,在非时间序列或无序数据中无意义。
插值法df['col'].interpolate()数值型,尤其是时间序列,数据变化平滑比前后填充更精细,能捕捉趋势对于非线性、剧烈波动的序列效果差。

为什么说可能引入偏差?想象一下,你用全体用户的平均收入去填充那些“未填写收入”的用户。这隐含的假设是:收入缺失的人和收入不缺失的人,收入分布相同。这显然与MAR或MNAR的常见情况相悖,会系统性低估或高估某些群体的特征。

2.4 高级填充:利用数据内部关系

为了克服单变量填充的缺点,我们需要利用其他已观测特征的信息来预测缺失值。

  1. K-最近邻(KNN)填充: 原理是为每个缺失值,在特征空间中寻找K个最相似的、非缺失的样本,用这些“邻居”的该特征值的(加权)平均来填充。

    from sklearn.impute import KNNImputer imputer = KNNImputer(n_neighbors=5, weights='uniform') df_filled = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

    优点:利用了特征间的相关性,比单变量填充更合理。缺点:计算量大,尤其在大数据集上;需要谨慎选择K值和距离度量;对特征尺度敏感(需要先标准化)。

  2. 迭代/链式方程(MICE)填充: 这是目前学术界和工业界在处理MAR数据时推荐的主流方法。它将包含缺失值的每个特征单独视为一个因变量,而其他特征作为自变量,建立一系列回归模型(如线性回归、随机森林等)来迭代预测缺失值。

    from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer from sklearn.ensemble import RandomForestRegressor # 使用随机森林作为估计器 imputer = IterativeImputer(estimator=RandomForestRegressor(n_estimators=10), max_iter=10, random_state=0) df_filled = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

    优点:能很好地保持变量间的相关结构和不确定性,理论上更严谨。缺点:计算复杂度高;需要假设填充模型本身是正确的;对于MNAR数据同样无能为力。

踩坑实录:在一次电商用户价值预测项目中,我们曾用MICE填充“最近购买金额”。但后来发现,缺失该值的用户大多是“仅浏览未购买”的用户,他们的真实金额应该是0,而不是一个预测出来的正数。这就是典型的MNAR场景,任何基于已观测数据的填充模型都会失效。解决方案:我们最终增加了一个二值特征“是否有购买记录”,并将缺失的金额填充为0。这提醒我们,业务理解永远是数据处理的指南针

2.5 将缺失本身作为特征

这是应对MNAR或复杂缺失模式的一记妙招。当缺失可能并非随机,而是包含某种信息时,我们不强行为其填充一个值,而是把“是否缺失”作为一个新的布尔特征(1表示缺失,0表示非缺失)加入模型。

例如,在金融风控中,“单位电话”字段的缺失,可能暗示用户无固定职业或自由职业者,这本身就是一个风险信号。此时,与其用一个模糊的“未知”填充,不如新增一个特征is_work_phone_missing

操作步骤

  1. 复制原特征列,例如income
  2. 创建新列income_missing,当income为NA时赋值为1,否则为0。
  3. 再用相对安全的方法(如中位数)填充原income列的缺失值,或者甚至保留NA(如果模型如XGBoost、LightGBM能直接处理缺失值)。
df['income_missing'] = df['income'].isna().astype(int) # 然后可以选择用中位数填充income,或者不填充 df['income'].fillna(df['income'].median(), inplace=True)

这种方法将缺失的信息显式化,让模型自己去学习和利用这种模式,在实践中往往能带来意想不到的效果提升。

3. 异常值检测:找到那些“不合群”的点

异常值,或称离群点,是那些与数据集中其他观测值显著不同的点。它们可能是数据录入错误(如身高录入为2.5米)、测量误差,也可能是真实的极端事件(如双十一的销售额、金融市场的“黑天鹅”)。我们的目标不是消灭所有异常值,而是识别它们,然后基于业务逻辑决定是修正、保留还是剔除。

3.1 基于统计分布的检测方法

这类方法假设数据服从某种分布,将落在分布尾部的点视为异常。

  1. 3σ原则 / Z-Score法: 适用于近似正态分布的数据。计算每个数据点与均值的差有多少个标准差(Z-Score)。通常认为 |Z-Score| > 3 的点为异常值。

    from scipy import stats z_scores = np.abs(stats.zscore(df['numeric_col'])) outliers = df[z_scores > 3]

    局限:严重依赖正态分布假设,对异常值本身敏感(均值和标准差易受异常值影响)。

  2. 箱线图(IQR)法: 这是一种更稳健的非参数方法。它基于数据的四分位数(Q1, Q3)和四分位距(IQR = Q3 - Q1)。

    • 上界 = Q3 + 1.5 * IQR
    • 下界 = Q1 - 1.5 * IQR 落在上下界之外的点被视为温和异常值。将系数1.5改为3,则可识别极端异常值。
    Q1 = df['col'].quantile(0.25) Q3 = df['col'].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR outliers = df[(df['col'] < lower_bound) | (df['col'] > upper_bound)]

    优点:不依赖于严格的正态分布假设,对极端值不敏感,可视化直观。缺点:对于非单峰、不对称分布的数据,可能效果不佳。

3.2 基于距离的检测方法:LOF

局部离群因子算法是一种非常有效的密度聚类思想下的异常检测方法。它不像全局方法那样一刀切,而是衡量每个点与其邻居点的局部密度偏差。

  • 核心思想:一个点是异常,不是因为它在全局上离得远,而是因为它的局部密度显著低于其邻居的局部密度。
  • 工作流程
    1. 对于每个点,找到其k个最近邻。
    2. 计算该点与其邻居的可达距离。
    3. 计算该点的局部可达密度(LRD)。
    4. 计算LOF分数:邻居的平均LRD / 该点的LRD。
  • LOF ≈ 1:该点与其邻居密度相似,很可能是正常点。
  • LOF >> 1:该点密度远低于邻居,可能是异常点。
from sklearn.neighbors import LocalOutlierFactor lof = LocalOutlierFactor(n_neighbors=20, contamination=0.1) # contamination是异常值比例的估计 outlier_labels = lof.fit_predict(X) # 返回1和-1,-1代表异常 lof_scores = -lof.negative_outlier_factor_ # 分数越大,越异常

适用场景:数据存在不同密度簇时效果非常好。例如,在客户分群中,大部分客户是普通消费者(高密度簇),但存在少数高净值客户(另一个密度较低的簇)和欺诈客户(真正的低密度异常点),LOF能很好地将欺诈客户与高净值客户区分开。

3.3 基于模型的检测方法:孤立森林

孤立森林利用了一个非常巧妙的思路:异常点由于“少而不同”,更容易被随机划分的决策树“孤立”出来

  • 核心思想:随机选择特征和分割值来构建二叉树(iTree)。路径越短,说明点越容易被孤立,是异常点的可能性就越高。集成多棵iTree形成森林,计算每个点的平均路径长度,并归一化得到异常分数。
  • 优点
    • 无需对数据分布做任何假设。
    • 线性时间复杂度,适合高维大数据集。
    • 对内存要求低。
  • 缺点:在具有大量重复值或子空间异常的数据上可能表现不佳。
from sklearn.ensemble import IsolationForest iso_forest = IsolationForest(n_estimators=100, contamination=0.1, random_state=42) outlier_labels = iso_forest.fit_predict(X) # 返回1和-1 outlier_scores = iso_forest.decision_function(X) # 分数越负,越异常

实操选择建议

  • 初步探索、单变量分析:用箱线图,快速直观。
  • 多变量、考虑局部密度:用LOF,尤其当你知道异常点是“局部”的而非全局的。
  • 高维数据、追求效率:用孤立森林,作为基线方法非常可靠。
  • 永远不要只依赖一种方法!将多种方法的结果交叉对比,并结合业务背景做最终判断。

4. 异常值处理:剔除、修正、转换还是包容?

检测出异常值后,如何处理是另一个关键决策。这里没有银弹,必须结合检测方法和业务场景。

4.1 直接剔除

将识别出的异常点从数据集中移除。

  • 何时用:确认异常值是由数据错误(如录入错误、传感器故障)导致,且比例很小(通常<5%)。或者,在构建一个追求高精度、泛化性的通用模型时,剔除极端异常点有助于模型学习主流模式。
  • 风险:可能丢失重要信息。如果是真实的稀有事件(如欺诈交易、疾病爆发),剔除它们会使模型无法识别这类关键模式。在时间序列中剔除点会导致断点。

4.2 修正或替换

用合理的值替换异常值。可以视为异常值的“填充”。

  • 盖帽法/缩尾:将超出指定分位数(如1%和99%)的值,替换为该分位数的值。这是处理数值型异常值最稳健的方法之一,能保留数据点但削弱其极端影响。
    lower_limit = df['col'].quantile(0.01) upper_limit = df['col'].quantile(0.99) df['col_capped'] = df['col'].clip(lower=lower_limit, upper=upper_limit)
  • 替换为缺失值:先将异常值设为缺失(NaN),然后再应用我们第二节提到的缺失值处理方法(如MICE)进行填充。这相当于将异常值处理问题转化为了缺失值处理问题,可以利用更丰富的信息。

4.3 数据转换

通过对整个特征进行数学变换,压缩极端值的范围,使其更符合模型假设。

  • 对数变换np.log1p(x)。特别适用于右偏(正偏)分布,如收入、房价、浏览量。能将大值的尺度急剧缩小,同时对小值影响温和。
  • Box-Cox变换:一种更通用的幂变换,能找到最优的变换参数使数据接近正态分布。要求数据必须为正。
    from scipy.stats import boxcox transformed_data, fitted_lambda = boxcox(original_data + 1) # +1 防止有0值
  • 分箱离散化:将连续值分段到有限的几个桶中。例如,将年龄分为“少年”、“青年”、“中年”、“老年”。这能彻底消除极端值的影响,但会损失一些信息量。

4.4 使用鲁棒模型

与其费尽心思处理异常值,不如直接使用对异常值不敏感的模型。

  • 树模型:如随机森林、梯度提升树(XGBoost, LightGBM, CatBoost),基于分割点的模型对异常值有一定鲁棒性。
  • 基于距离的模型:如KNN、SVM(使用RBF核),对异常值非常敏感,需要提前处理。
  • 统计模型:如普通最小二乘线性回归,对异常值极其敏感;可以改用岭回归、Lasso(通过正则化约束系数),或者更鲁棒的Huber回归分位数回归

我的经验法则

  1. 先理解,后处理:永远尝试从业务角度理解异常值的成因。是bug?是特殊活动?还是一个新模式的开始?
  2. 可视化是关键:在处理前后,使用箱线图、散点图、直方图可视化特征分布,直观感受处理效果。
  3. 分而治之:对于明确由错误导致的异常,剔除或修正。对于真实但极端的值,如果希望模型学习主流模式,考虑缩尾或转换;如果这些极端事件本身就是预测目标的一部分,则考虑使用鲁棒模型或将其作为特殊类别处理
  4. 评估影响:在建模流水线中,将异常值处理作为一个步骤,并通过交叉验证来评估不同处理策略对最终模型性能的影响。这是最客观的评判标准。

5. 实战流程与建模框架集成

在实际的数学建模项目或数据科学工作中,缺失值和异常值处理不是两个独立的步骤,而是紧密相连、需要迭代进行的数据清洗核心环节。下面是一个我总结的、可复用的标准化流程框架。

5.1 系统化清洗流程六步走

第一步:探索性数据分析与问题标注

  • 使用df.info(),df.describe()df.isnull().sum()全面了解数据形状、类型和缺失概况。
  • 绘制每个特征的分布直方图、箱线图,对缺失和异常情况做可视化标记。
  • 产出:一份数据质量报告,明确列出每个特征的问题(缺失率、疑似异常值比例、分布形状)。

第二步:区分特征类型与建模角色

  • 区分特征类型:数值型连续、数值型离散(分类)、分类型文本、时间型。
  • 明确建模角色:是目标变量(Y)、核心特征、还是辅助特征?对目标变量和核心特征的处理要格外谨慎。

第三步:制定并执行缺失值处理策略

  1. 高缺失率特征:对于缺失率 > 40%的特征,考虑直接剔除该特征,除非业务上极其重要。
  2. 低缺失率特征
    • 若为分类型:考虑用“未知”或众数填充,并创建缺失指示符。
    • 若为数值型
      • 若业务明确(如未购买则金额为0),按业务逻辑填充。
      • 若为时间序列,用插值或前后向填充。
      • 其他情况,优先使用MICEKNN进行多变量填充。对于基线模型,可用中位数填充。
    • 创建缺失指示符:对于任何经过填充的、且怀疑为MAR或MNAR的特征,强烈建议创建布尔型缺失指示符。

第四步:异常值检测与诊断

  1. 对处理完缺失值的数值型特征,使用箱线图进行单变量初筛。
  2. 对于多变量场景或复杂数据,运行孤立森林LOF算法,获取每个样本的异常分数。
  3. 关键步骤:将检测出的异常样本索引输出,人工或基于业务规则进行抽样审查。尝试回答:这些点为什么异常?是错误还是特殊模式?

第五步:制定并执行异常值处理策略

  • 根据诊断结果:
    • 确认为错误:按业务逻辑修正或剔除。
    • 真实极端值
      • 若想保留其影响但减弱程度:使用缩尾法
      • 若特征整体偏斜:对整列进行对数变换Box-Cox变换
      • 若该特征非核心,且异常点很少:可考虑剔除
    • 不确定或情况复杂:进入下一步,让鲁棒模型或集成策略来决定。

第六步:将清洗步骤管道化使用sklearn.pipeline.PipelineColumnTransformer将你的清洗逻辑封装起来,确保训练集和测试集以完全相同的方式处理,避免数据泄露。

from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import FunctionTransformer # 定义数值型列的处理管道:中位数填充 -> 缩尾 num_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='median')), ('winsorize', FunctionTransformer(winsorize_func)) # winsorize_func是自定义的缩尾函数 ]) # 定义分类型列的处理管道:众数填充 -> 独热编码 cat_transformer = Pipeline(steps=[ ('imputer', SimpleImputer(strategy='most_frequent')), ('onehot', OneHotEncoder(handle_unknown='ignore')) ]) # 组合起来 preprocessor = ColumnTransformer( transformers=[ ('num', num_transformer, numerical_cols), ('cat', cat_transformer, categorical_cols) ]) # 最终建模管道 model_pipeline = Pipeline(steps=[ ('preprocessor', preprocessor), ('classifier', RandomForestClassifier()) ])

5.2 在交叉验证中评估处理策略

永远不要凭感觉选择处理方式。最可靠的方法是将数据清洗作为模型训练的一部分,通过交叉验证来评估不同策略的组合效果。

from sklearn.model_selection import GridSearchCV # 定义不同的填充策略参数网格 param_grid = { 'preprocessor__num__imputer__strategy': ['mean', 'median', 'most_frequent'], 'preprocessor__num__winsorize__func': [winsorize_weak, winsorize_strong], # 不同缩尾强度 'classifier__n_estimators': [100, 200] } grid_search = GridSearchCV(model_pipeline, param_grid, cv=5, scoring='accuracy') grid_search.fit(X_train, y_train) print(f"最佳参数: {grid_search.best_params_}") print(f"最佳交叉验证分数: {grid_search.best_score_:.4f}")

通过这种方式,你可以客观地知道,对于当前的数据和任务,是“中位数填充+强缩尾”效果好,还是“众数填充+对数变换”效果好。

6. 避坑指南与高级技巧

走过不少弯路后,我总结了一些在处理缺失值和异常值时容易忽略的“坑”和能提升效果的高级技巧。

6.1 时间序列数据的特殊性

时间序列数据(如销量、股价、传感器读数)的缺失和异常处理需要特别小心,因为数据点之间存在时间依赖。

  • 缺失处理

    • 线性/样条插值:适用于短期、随机缺失,且数据变化平滑的场景。
    • 季节性+趋势分解填充:使用STL或季节性分解方法,将序列分解为趋势、季节性和残差,对分解后的部分进行填充后再组合。这能更好地保持序列的季节和趋势模式。
    • 前向填充的陷阱:在存在长期缺失或突变点时,前向填充会制造出虚假的“平台”,严重误导模型。
  • 异常检测

    • 基于预测的方法:先用一个稳健的模型(如Holt-Winters, ARIMA)预测每个点的值,将实际值与预测值相差过大的点视为异常。Facebook的Prophet库内置了这种异常检测能力。
    • 滚动统计法:计算滚动窗口内的均值、标准差,将超出均值±3倍滚动标准差的值视为异常。这能适应序列的局部变化。

6.2 分类数据中的“异常”

对于分类特征,异常往往表现为稀有类别。例如,在“国家”字段中,99%是“中国”,突然出现一个“圣多美和普林西比”。

  • 处理策略
    1. 保留:如果稀有类别具有重要业务意义(如“欺诈”标签),必须保留。
    2. 归并为“其他”:将出现频率低于某个阈值(如1%)的所有类别合并为一个“其他”类别。这是最常用的方法,能防止模型过拟合到噪声,并减少独热编码后的维度。
    3. 目标编码:用该类别下目标变量的均值(对于回归)或比例(对于分类)来替换类别标签。这能将类别信息转化为数值,同时自然地将稀有类别平滑到与相似类别相近的值。

6.3 警惕“多峰分布”误判为异常

很多数据并非单峰的正态分布。例如,一个城市的餐厅消费数据,可能包含“快餐消费”和“高档餐厅消费”两个子群体,形成双峰分布。用基于单峰假设的Z-Score或标准箱线图去检测,会把其中一个峰的大部分正常数据误判为异常。

解决方法

  • 可视化,可视化,再可视化:画分布图、核密度估计图。
  • 聚类后检测:先使用聚类算法(如K-Means、DBSCAN)将数据分成若干子群,然后在每个簇内部应用异常检测。这样能发现“全局正常但局部异常”的点。
  • 使用更通用的方法:如直方图-based outlier detection,或者直接使用不假设分布的模型如孤立森林。

6.4 处理中的“数据泄露”陷阱

这是建模中最致命的错误之一:在训练模型之前,使用了来自测试集或未来信息来处理训练集。

  • 错误示例:在填充缺失值或缩尾处理时,先在整个数据集(训练+测试)上计算均值、分位数,然后用这个全局统计量去处理训练集和测试集。这相当于让训练集“偷看”了测试集的信息。
  • 正确做法:所有从数据中学习到的参数(如填充用的均值、缩尾用的分位数、编码用的映射关系),必须且只能从训练集中计算,然后固定这些参数去处理测试集。这正是使用sklearn.pipelinefit_transform/transform模式的意义所在。

6.5 一种进阶思路:将处理与否作为超参数优化

在自动化机器学习(AutoML)框架或高级实践中,你可以将缺失值/异常值的处理策略本身作为超参数进行优化。

例如,你可以定义几个候选的“清洗策略”:

  • 策略A:数值列用中位数填充+创建缺失指示符;分类列用众数填充;对所有数值列进行IQR缩尾。
  • 策略B:用IterativeImputer进行多变量填充;使用孤立森林剔除5%的异常样本。
  • 策略C:对右偏分布列做对数变换后,再用KNN填充。

然后,在模型选择和调参的同时,让优化器(如Optuna, Hyperopt)去尝试这些不同的数据清洗策略,寻找对最终验证集指标提升最大的组合。这虽然计算成本高,但往往能找到针对特定数据集和任务的最优数据准备方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 5:09:50

具身智能的“评估基准与测试床”:封闭系统 Vs.开放世界

前沿技术探索&#xff1a;TVA智能体&#xff08;简称TVA&#xff09;TVA智能体&#xff08;亦称“AI智能体视觉”或“TVA视觉智能体”&#xff09;是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习&#xff08;DRL&#xff09;、卷积…

作者头像 李华
网站建设 2026/9/2 5:09:25

具身智能的“学习范式”:从模仿到创造

前沿技术探索&#xff1a;TVA智能体&#xff08;简称TVA&#xff09;TVA智能体&#xff08;亦称“AI智能体视觉”或“TVA视觉智能体”&#xff09;是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习&#xff08;DRL&#xff09;、卷积…

作者头像 李华
网站建设 2026/9/3 15:22:23

多重集组合数问题:从暴力枚举到动态规划的优化解法

1. 多重集组合数问题&#xff1a;从暴力枚举到动态规划的思维跃迁 在算法竞赛和实际编程中&#xff0c;我们经常会遇到一类经典的计数问题&#xff1a;给定一个多重集&#xff08;即元素可以重复的集合&#xff09;&#xff0c;从中选取特定数量的元素&#xff0c;问有多少种不…

作者头像 李华
网站建设 2026/9/3 8:34:44

模拟退火算法:从物理隐喻到工程实践,解决复杂优化问题

1. 项目概述&#xff1a;从“烧铁淬火”到求解复杂优化如果你在数学建模、运筹优化或者算法设计的圈子里待过一阵子&#xff0c;大概率会听过“模拟退火”这个名字。它不像深度学习那样自带光环&#xff0c;也不像遗传算法那样充满生物隐喻&#xff0c;但它在解决那些“组合爆炸…

作者头像 李华
网站建设 2026/9/3 18:27:26

慢就是快 - 03pyCharm快捷键

可参考的快捷键&#xff0c;可以自定义自定义快捷键右击自定义重置快捷键 - 恢复默认设置设置了很多后&#xff0c;可以导出设置&#xff0c;换电脑等情况下使用

作者头像 李华
网站建设 2026/9/2 9:18:26

AI Agent实战:从browser-use到video-use的自动化探索

网页自动化领域有一个长期存在的矛盾&#xff1a;脚本越写越多&#xff0c;维护成本却越来越高。传统自动化工具解决的是“操作稳定性”&#xff0c;但始终没有解决“理解能力”——页面结构一变&#xff0c;XPath 失效&#xff1b;元素加载方式调整&#xff0c;等待条件要重写…

作者头像 李华