尧图精选

缺失值直接删除后模型F1跌到0.63,机器学习课程让我用这3招止血

🕒 发布时间:2026/9/6 2:42:59 📁 来源:尧图网络
缺失值直接删除后模型F1跌到0.63,机器学习课程让我用这3招止血发版推送后的第一个小时,监控面板的CTR曲线像断了线,一路向下滑了22%。我第一反应是模型权重出了问题,立马回滚到上一版。回滚后流量恢复正常,说明新版模型本身就有毒。我翻遍训练日志,最后对比训练集和线上特征的分布才发现问题出在三个月前的一次“省事”操作:我直接把包含缺失值的样本全删了。原本120万的训练样本缩水到83万,丢掉的不仅是数量,更是大量高价值用户的点击模式。那阵子我正好开始跟一门机器学习课程,在数据预处理那一章,讲师用一张变量分布对比图让我瞬间明白--简单删除会掐掉整片特征空间的关键信息,线上效果暴跌只是迟早的事。为什么我当初觉得直接删除没问题做推荐模型时,原始日志里有不少字段是选填的,比如“用户职业”“最近搜索关键词”,缺失率在15%左右。我当时看过几篇入门教程,都说样本量足够大时删掉缺失值影响不大,尤其是随机缺失的情况下。我当时的判断逻辑就是:120万样本删掉30万,还有90万,够用了。而且我用df.dropna(inplaceTrue)一行代码就搞定了,省去了琢磨插补方法的时间。那时我对机器学习基础里的数据预处理理解只停留在“去空值、去重、归一化”这种操作清单上,根本没有缺失机制的意识。后来在机器学习课程的第二章,我才真正搞清楚MCAR、MAR、MNAR这三种机制的差别,以及为什么哪怕是随机缺失,丢失17%的样本也会让模型对长尾用户的拟合变差。踩坑全过程:从F1 0.81跌到0.63模型是LightGBM二分类,目标是预测用户是否会点击某个广告位。训练时我用的指标是验证集的F1-score,当时跑出来是0.81,感觉还不错。# 当时的数据加载和清洗代码 import pandas as pd df pd.read_parquet(train_data.parquet) print(df.shape) # (1200000, 42) df df.dropna() print(df.shape) # (830000, 42)上线前我用最近7天的日志做了回溯测试,F1也能维持在0.80以上。但真正推全量后,线上F1直接掉到0.63。问题出在回溯测试的样本分布和线上实时流量分布不一致:线上有大量新用户,他们的“用户职业”字段缺失率高达35%,而训练集里这些样本早就被我删掉了,模型完全没见过这类特征模式,直接把高概率推成了低概率。当时我还没补机器学习课程,完全靠自己的排查,花了两个工作日才定位到是缺失值处理导致的特征分布偏移。那种眼看着指标往下掉却找不到原因的焦躁,让我下定决心系统学一遍数据预处理。机器学习课程教我的三种方案对比课程里有一整个模块讲数据预处理,讲师先让我们动手用一套电商数据做实验:分别用删除、中位数填充、随机森林预测填充三种方法处理缺失值,然后训练同一个XGBoost模型,观察验证集上的F1变化。我跟着做完那个实验后,彻底推翻了之前的认知。三种方案的对比结果大致如下:处理方案训练样本数验证集F1线上回溯F1说明直接删除83万0.810.63丢弃大量样本,线上分布偏移中位数填充120万0.800.75保留样本,但扭曲了原始分布随机森林预测填充120万0.820.80利用其他特征预测缺失值,更接近真实分布机器学习课程特别强调:对于缺失率超过20%且非随机缺失的字段,用模型预测填充往往是最优解,因为它可以保留特征间的相关性,避免简单插补带来的信息稀释。我还从机器学习基础模块里学到,缺失值的处理不能只看模型分数,还要考虑特征工程的后续步骤。如果填充的值与真实分布差距太大,在树模型里会改变分裂点位置,影响整个特征重要性排序。代码实战:随机森林填充和异常值处理学完理论后我重新处理数据,第一步就是用孤立森林检测异常值,然后再处理缺失值。因为有些字段的缺失本身就是异常行为的信号。from sklearn.ensemble import IsolationForest from sklearn.impute import SimpleImputer # 孤立森林找异常 iso IsolationForest(contamination0.01, random_state42) df[anomaly] iso.fit_predict(df[feature_cols].fillna(0)) df df[df[anomaly] 1] # 对关键字段用随机森林填充缺失值 from sklearn.ensemble import RandomForestRegressor def fill_na_with_rf(df, target_col, feature_cols): train df[df[target_col].notna()] test df[df[target_col].isna()] if len(test) 0: return df rf RandomForestRegressor(n_estimators50, random_state42) rf.fit(train[feature_cols], train[target_col]) df.loc[df[target_col].isna(), target_col] rf.predict(test[feature_cols]) return df df fill_na_with_rf(df, user_income, [age, city_level, device_price])这段代码是我在机器学习课程的课后项目里改良的。课程提供的AWS沙箱环境里预装了scikit-learn和pandas,直接上手就能跑,省去了配环境的烦躁。而且讲师还演示了如何用Amazon SageMaker Data Wrangler可视化缺失值矩阵,一眼就能看出哪些字段缺失率突然飙升。用AWS机器学习相关的沙箱做实验时,我特别注意了特征存储的概念--把填充后的特征版本管理起来,避免训练和线上推理使用不同版本的特征,这也是之前踩坑的一个延伸教训。差点又踩的坑:IQR法和直接删除异常值我在处理数值型字段的异常值时,本来想用经典的IQR法(箱线图判断上下界),直接把超出1.5倍IQR的点删掉。但在机器学习入门章节的练习题里,我发现把异常值一刀切会导致用户消费能力字段损失掉头部VIP用户的信息,模型对高价值人群的预测反而变差。正确做法应该是先分析异常值产生的原因:如果是数据录入错误,可以删除或修正;如果是真实存在的极端值,就该用对异常值不敏感的模型(比如基于树的算法),或者做分箱处理。机器学习课程在这一块给了一个很实用的决策框架:异常比例 1% 且明显是错误:直接删除或替换为缺失值再填充异常比例在1%~5%:尝试截尾或分箱异常比例 5%:考虑是不是指标本身波动大,用鲁棒缩放或换模型这个框架帮我在最近一个用户付费预测项目里至少省了三个晚上的试错时间。学完后的变化:不再盲目动手,模型也稳了跟着机器学习课程完整走完数据预处理和模型训练的实战后,我最大的变化有三个:训练前一定会看缺失矩阵和异常值分布,而不是dropna()一把梭能根据业务场景决定是保留信息还是优先简便,选择对应的缺失值策略模型上线后的F1波动从之前的±15%缩小到±3%最近一次面试,面试官问我“数据质量差的时候你一般怎么处理”,我把缺失值对比实验和异常值检测套路讲了一遍,对方直接追问“有没有做过模型预测填充”,我刚好看过机器学习基础里关于多重插补的内容,就顺带说了MICE的适用场景,当场就拿到了下一轮邀约。如果你现在正被缺失值折磨,或者模型线上效果老是和线下差一大截,强烈建议去翻一翻机器学习课程里数据预处理的章节,它不会只给代码,而是把每种方法背后的假设和失效边界讲得很清楚--这种知识才是让模型从0.63回到0.82的关键。给同样处境的人几条可执行建议先画缺失值矩阵热力图,搞清缺失模式和比例,不要一上来就删用机器学习课程做的那个对比实验自己跑一遍,直观感受三种方案对F1的影响关键业务字段优先尝试随机森林或KNN预测填充,比均值/中位数填充更能保留特征间关系异常值先溯源再处理,IQR删完记得验证是否损失了重要人群线上部署前用最近7天真实日志做回溯测试,确保分布不一致时不会翻车把填充策略和参数记入特征工程笔记,哪怕过三个月也能复现如果时间有限,机器学习课程的2-3小时动手实验就能覆盖缺失值和异常值处理的核心要点,值得点进去系统过一遍
上一篇/下一篇内容由系统自动关联 返回资讯列表 →