数据集各列存在约95%异常值,使用IQR替换处理是否合理?
数据集异常值处理问题解决方案
核心问题定位
你提供的IQR计算代码存在逻辑错误,这是你观测到每列95%异常值、模型结果异常的核心原因:
原代码中higherLimit = Q3 - 1.5*IQR写法错误,IQR方法的上限计算公式应为Q3 + 1.5*IQR,你误将加号写为减号,导致上限阈值远低于正常水平,绝大多数合法数据被判定为异常值,全量替换后特征分布被严重压缩,最终得到失真的模型效果。
修正后的处理代码
import numpy as np def check_outliers(col) : outliers = [] Q1 = col.quantile(.25) Q3 = col.quantile(.75) IQR = Q3 - Q1 lowerLimit = Q1 - 1.5*IQR # 修正上限计算公式 higherLimit = Q3 + 1.5*IQR for elt in col : if elt < lowerLimit or elt > higherLimit : outliers.append(elt) return np.array(outliers), lowerLimit, higherLimit # 建议先拆分训练集验证集后,仅用训练集统计量做处理,避免数据泄露 for col in train.columns : arr,lowerLimit,higherLimit = check_outliers(train[col]) print(col, len(arr)) train[col] = np.where(train[col]>higherLimit,higherLimit,train[col]) train[col] = np.where(train[col]<lowerLimit,lowerLimit,train[col])
后续优化建议
- 修正代码后重新统计各列异常值占比,正常情况下天然分布的数据不会出现95%的异常占比,若修正后仍有高比例异常,先通过箱线图、直方图查看特征分布:如果是天然长尾分布的特征(如交易金额、用户活跃度等),不要直接用IQR截断,可选择对数变换、分位数编码等方式保留分布特征。
- 不要对所有特征统一执行异常值截断:先结合业务逻辑校验异常值合理性,比如年龄字段出现200、负数属于明确的采集错误可做修正,符合业务逻辑的极值(如高价值用户的消费额)不要随便截断,避免丢失有效信息。
- 严格避免数据泄露:做特征处理前先完成训练集、验证集、测试集的拆分,仅使用训练集的统计量(分位数、均值等)处理验证集和测试集,不要用全量数据集的统计量做统一处理,否则会导致模型效果虚高。
内容的提问来源于stack exchange,提问作者Khadija
相关产品推荐
相关产品推荐

