数据预处理通关指南:从混乱到有序,为机器学习铺路

一、缺失值处理:给数据 “补补丁”

现实中的数据往往不完美 —— 传感器故障、人工录入遗漏、系统报错等,都会导致数据缺失。如果直接忽略这些 “窟窿”,模型很可能学到错误的规律。处理缺失值,我们需要分两步走:先检测,再填补

1. 如何发现缺失值?

在 Python 中,pandas库的isnull()函数是检测缺失值的 “利器”。它会逐单元格判断是否为空,返回True(缺失)或False(非缺失)。但要注意:数据中可能存在 “伪装” 的缺失值,比如n/ana-等字符串,需要先用na_values参数统一标记为NaN(pandas 中标准的缺失值符号)。

import pandas as pd
# 定义“伪装”的缺失值
missing_values = ["n/a", "na", "-"]
# 读取数据时自动将这些值转为NaN
df = pd.read_csv('property-data.csv', na_values=missing_values)
# 检测NUM_BEDROOMS列的缺失值
print(df['NUM_BEDROOMS'].isnull())

2. 缺失值怎么处理?

根据数据特点和业务场景,缺失值的处理方式主要有两种:删除填充

  • 删除法(dropna ()):如果缺失值占比极低,且随机分布,可以直接删除包含缺失值的行或列。dropna()的参数很灵活:

    • axis=0(默认):删除含缺失值的行;axis=1:删除含缺失值的列。
    • how='any'(默认):只要有一个缺失值就删除;how='all':所有值都缺失才删除。
    • subset=['列名']:只检查指定列的缺失值。
    # 删除所有含缺失值的行
    new_df = df.dropna()
    
  • 填充法(fillna ()):大部分情况下,我们更倾向于填充缺失值而非删除,避免丢失有效信息。常用的填充策略有:

    • 常数填充:用固定值(如 0、666)填充,适合对缺失含义有明确假设的场景。
      df.fillna(666, inplace=True)  # 用666填充所有缺失值
      
    • 统计量填充:用均值(mean())、中位数(median())或众数(出现次数最多的值)填充,更贴合数据分布。例如,用均值填充街道编号(ST_NUM)的缺失值:
      x = df["ST_NUM"].mean()  # 计算均值
      df["ST_NUM"].fillna(x, inplace=True)  # 填充缺失值
      
    • 专业工具填充scikit-learnSimpleImputer支持更标准化的填充,尤其适合后续建模流程。比如用中位数填充年龄缺失值:
      from sklearn.impute import SimpleImputer
      imp_median = SimpleImputer(strategy="median")  # 定义中位数填充器
      age_filled = imp_median.fit_transform(age.reshape(-1, 1))  # 填充年龄列
      

二、数据标准化:让数据 “站在同一起跑线”

想象一下:如果你的数据中,“身高” 以厘米为单位(范围 150-190),“体重” 以千克为单位(范围 50-100),模型可能会错误地认为 “身高” 对结果的影响更大(因为数值范围更广)。这就是量纲不一致带来的问题。标准化的作用,就是通过转换让不同特征 “无量纲化”,消除这种偏差。

1. 标准化的核心目标

将数据转换为均值为 0、方差为 1 的标准正态分布(或固定范围),让不同特征的 “影响力” 趋于均衡。

2. 两种常用的标准化方法

  • 最大最小值标准化(MinMaxScaler):将数据压缩到指定范围(默认 [0,1]),公式为: \(x' = \frac{x - \text{min}(x)}{\text{max}(x) - \text{min}(x)}\) 适合需要明确数据范围的场景(如神经网络输入)。例如,将数据映射到 [5,10] 区间:

    from sklearn.preprocessing import MinMaxScaler
    data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
    scaler = MinMaxScaler(feature_range=[5, 10])  # 指定范围
    result = scaler.fit_transform(data)  # 输出:[[5.,5.], [6.25,6.25], ...]
    
  • Z 值标准化(StandardScaler):基于均值和标准差转换,公式为: \(x' = \frac{x - \mu}{\sigma}\)(\(\mu\)为均值,\(\sigma\)为标准差) 转换后的数据均值为 0、方差为 1,适合数据近似正态分布的场景。

    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    x_std = scaler.fit_transform(data)  # 标准化数据
    print(x_std.mean())  # 输出:0.0(均值为0)
    print(x_std.std())   # 输出:1.0(方差为1)
    

三、特征编码:给文字标签 “贴数字标签”

机器学习模型只能处理数值,而现实数据中常有 “性别(男 / 女)”“学历(小学 / 初中 / 高中)” 等分类特征。特征编码的作用,就是将这些文字标签转换为模型可理解的数字。

1. 先分清特征类型

  • 名义变量:无顺序关系(如性别、血型)。
  • 有序变量:有顺序但不可计算(如学历、评分等级)。

2. 对应编码方法

  • 独热编码(OneHotEncoder):适合名义变量。例如,将 “血型(A/B/AB/O)” 转换为 4 个二进制特征: A 型→(1,0,0,0),B 型→(0,1,0,0),以此类推。这样避免了模型误解 “数字大小”(如 A=1、B=2 会被认为 B>A)。

    from sklearn.preprocessing import OneHotEncoder
    encoder = OneHotEncoder()
    blood_type_encoded = encoder.fit_transform(blood_type.reshape(-1, 1)).toarray()
    
  • 序号编码(OrdinalEncoder):适合有序变量。例如,“学历” 可编码为:小学 = 1、初中 = 2、高中 = 3,保留顺序关系。

    from sklearn.preprocessing import OrdinalEncoder
    encoder = OrdinalEncoder(categories=[['小学', '初中', '高中']])
    education_encoded = encoder.fit_transform(education.reshape(-1, 1))
    
  • 目标标签编码(LabelEncoder):专门用于编码 “目标变量”(即预测结果 y),例如将 “ Survived(Yes/No)” 编码为 1/0。

    from sklearn.preprocessing import LabelEncoder
    encoder = LabelEncoder()
    survived_encoded = encoder.fit_transform(survived)  # Yes→1,No→0
    

四、数据二值化:非黑即白的 “简化术”

有时我们需要将连续数据 “一刀切”:比如将 “年龄 > 30 岁” 定义为 1,“≤30 岁” 定义为 0。这种将数据分为 0 和 1 的操作,就是二值化,常用sklearn.preprocessing.Binarizer实现。

from sklearn.preprocessing import Binarizer
# 将年龄按阈值30二值化
X = age.values.reshape(-1, 1)  # 转换为二维数组
transformer = Binarizer(threshold=30)  # 阈值设为30
age_binarized = transformer.fit_transform(X)  # 输出:>30→1,≤30→0

二值化适合突出 “是否满足某条件” 的场景,比如 “是否为高收入人群”“是否有逾期记录” 等。

总结:数据预处理的核心原则

数据预处理没有 “万能公式”,但遵循以下原则能让你少走弯路:

  1. 先理解数据:缺失值是随机还是有规律?特征的物理含义是什么?
  2. 结合业务场景:填充策略、标准化方法需匹配业务目标(如预测房价和预测疾病的预处理重点不同)。
  3. 工具选对事半功倍pandas适合数据清洗,scikit-learnpreprocessing模块适合标准化建模流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值