【大模型学习】第九章 机器学习中的数据预处理技术详解

目录

引言

[一、清洗数据(Data Cleaning)](#一、清洗数据(Data Cleaning))

[1. 定义与目的](#1. 定义与目的)

[2. 常见问题及解决方法](#2. 常见问题及解决方法)

[2.1 重复记录](#2.1 重复记录)

[2.2 异常值检测](#2.2 异常值检测)

[2.3 不一致性修正](#2.3 不一致性修正)

[二、填充缺失值(Handling Missing Values)](#二、填充缺失值(Handling Missing Values))

[1. MCAR(Missing Completely at Random)原理及处理方式](#1. MCAR(Missing Completely at Random)原理及处理方式)

示例代码

[2. MAR(Missing at Random)原理及处理方式](#2. MAR(Missing at Random)原理及处理方式)

[3. MNAR(Missing Not at Random)原理及处理方式](#3. MNAR(Missing Not at Random)原理及处理方式)

[4. 缺失值的处理总结](#4. 缺失值的处理总结)

[三、转换数据格式(Data Transformation)](#三、转换数据格式(Data Transformation))

[1. 标准化/归一化(Normalization/Standardization)](#1. 标准化/归一化(Normalization/Standardization))

[2. 类别编码](#2. 类别编码)

[1. 独热编码(One-Hot Encoding)](#1. 独热编码(One-Hot Encoding))

[2. 标签编码(Label Encoding)](#2. 标签编码(Label Encoding))

[3. 独热编码 vs 标签编码:优缺点对比](#3. 独热编码 vs 标签编码:优缺点对比)

四、总结


引言

在构建和训练机器学习模型之前,数据预处理是一个至关重要的步骤。它确保了输入到模型的数据是干净、一致且易于理解的,从而提高模型性能和准确性。本文将详细介绍几种主要的数据预处理技术,包括清洗数据、填充缺失值以及转换数据格式等,并解释其实现原理。

一、清洗数据(Data Cleaning)

1. 定义与目的

数据清洗是指识别并纠正或删除数据集中的错误、不完整或无关的信息的过程。其目的是为了保证数据的质量,使得后续分析更加准确可靠。

2. 常见问题及解决方法

2.1 重复记录

重复数据可能会影响模型的训练,导致偏差。通过检查是否存在完全相同的记录,并决定是否保留一条副本。

  • 实现原理 :使用drop_duplicates()函数可以轻松移除DataFrame中的重复行。

  • 代码示例

    python 复制代码
    # 创建包含重复数据的示例
    data = {'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
            'Age': [25, 30, 35, 25, 30],
            'Score': [85, 90, 95, 85, 90]}
    
    df = pd.DataFrame(data)
    
    # 显示原始数据
    print("原始数据:")
    print(df)
    
    # 删除重复记录(保留第一次出现的记录)
    df_dropped_duplicates = df.drop_duplicates()
    print("\n删除重复数据后的数据:")
    print(df_dropped_duplicates)
    
    
    
    
    ################输出结果#######################
    
    
    原始数据:
         Name  Age  Score
    0   Alice   25     85
    1     Bob   30     90
    2  Charlie   35     95
    3   Alice   25     85
    4     Bob   30     90
    
    删除重复数据后的数据:
         Name  Age  Score
    0   Alice   25     85
    1     Bob   30     90
    2  Charlie   35     95

2.2 异常值检测

异常值是与其他数据显著不同的数据点,可能是噪声或极端值,需要检测并处理。也就是识别那些显著偏离其他观测值的数据点。

  • 实现原理:可以通过统计方法(如Z分数)或可视化手段(如箱形图)来识别异常值。对于数值型数据,计算每个样本点的标准得分(Z-score),如果绝对值超过某个阈值(通常是3),则认为该点为异常值。

  • 代码示例

    python 复制代码
    import numpy as np
    import pandas as pd
    
    # 创建示例数据(包含异常值)
    data = {'Age': [25, 30, 35, 40, 45, 100]}
    df = pd.DataFrame(data)
    
    # 使用Z-score检测异常值
    mean = df['Age'].mean()
    std = df['Age'].std()
    z_scores = (df['Age'] - mean) / std
    
    # 阈值为3,绝对值超过3则为异常值
    threshold = 3
    outliers = z_scores.abs() > threshold
    
    # 删除异常值
    df_clean = df[~outliers]
    print("删除异常值后的数据:")
    print(df_clean)
    
    
    #################################输出结果#############################################
    删除异常值后的数据:
       Age
    0   25
    1   30
    2   35
    3   40
    4   45

    2.3 不一致性修正

不一致性主要是用于统一数据格式,数据中某些字段的类型可能不正确,需要更正类型或清理数据,例如日期格式的一致性、拼写错误等。

  • 实现原理:可以通过正则表达式或者其他数据统一函数实现

  • 代码示例

    python 复制代码
    # 创建示例数据(包含错误类型)
    data = {'Name': ['Alice', 'Bob', 'Charlie'],
            'Age': ['25', '30', '35']}  # 年龄应该是整数类型
    
    df = pd.DataFrame(data)
    
    # 显示原始数据类型
    print("原始数据类型:")
    print(df.dtypes)
    
    # 转换Age为整数类型
    df['Age'] = df['Age'].astype('int64')
    
    # 显示转换后的数据类型
    print("\n转换后的数据类型:")
    print(df.dtypes)
    
    
    ###########输出结果#################
    
    原始数据类型:
    Name    object
    Age     object
    dtype: object
    
    转换后的数据类型:
    Name    object
    Age      int64
    dtype: object

二、填充缺失值(Handling Missing Values)

缺失值可能导致模型训练不稳定甚至失败,因此必须妥善处理。处理方式取决于数据的特性和丢失机制(MCAR, MAR, MNAR)。

1. MCAR(Missing Completely at Random)原理及处理方式

  • 定义: MCAR表示缺失值的分布是完全随机的,与任何其他变量(包括未观测的变量)无关。
  • 处理方式: 对于MCAR,缺失值通常不会引入偏差。可以通过以下方法处理:
  1. 删除含有缺失值的记录: 适用于缺失值比例较小的情况。
  2. 均值/中位数/众数填充: 对于数值型变量,可以用均值、中位数或众数填充;对于类别型变量,可以用众数填充。
示例代码
python 复制代码
import pandas as pd
import numpy as np

# 创建示例数据
data = {
    'Age': [25, np.nan, 30, np.nan, 35],
    'Salary': [50000, 60000, np.nan, 70000, 80000],
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve']
}

df = pd.DataFrame(data)

# 方法1: 删除含有缺失值的记录
df_dropped = df.dropna()
print("删除缺失值后的数据:")
print(df_dropped)

# 方法2: 用均值填充Age的缺失值
mean_age = df['Age'].mean()
df_filled = df.copy()
df_filled['Age'].fillna(mean_age, inplace=True)
print("\n用均值填充缺失值后的数据:")
print(df_filled)


##########################输出结果#######################

输出结果:

删除缺失值后的数据:
       Age   Salary    Name
0  25.0000  50000.0   Alice
3     NaN  70000.0   David
4  35.0000  80000.0     Eve

用均值填充缺失值后的数据:
       Age   Salary    Name
0  25.0000  50000.0   Alice
1  25.0000  60000.0     Bob
2  30.0000     NaN  Charlie
3  30.0000  70000.0   David
4  35.0000  80000.0     Eve

2. MAR(Missing at Random)原理及处理方式

  • 定义: MAR表示缺失值的分布与观测到的变量有关,但与未观测到的变量无关。
  • 处理方式: 对于MAR,可以通过其他变量的信息来填补缺失值。常用方法包括:
  1. 均值/中位数/众数填充: 使用其他变量的信息填补缺失值。

  2. 预测填充: 使用其他变量训练一个模型来预测缺失值。

  3. 均值填充示例代码

    python 复制代码
    # 数据已经填充,假设Salary的缺失值是 MAR,使用Age来填补
    # 由于 Salary 和 Age 可能相关,可以按照年龄段填补 Salary
    df_filled = df.copy()
    
    # 按照 Age 分组,计算每组的 Salary 均值
    groups = df_filled.groupby('Age')['Salary']
    
    # 填补缺失值
    df_filled['Salary'].fillna(groups.transform('mean'), inplace=True)
    print("\n用均值填充后的数据:")
    print(df_filled)
    
    
    #######输出结果#############
    输出结果:
    
    用均值填充后的数据:
           Age   Salary    Name
    0  25.0000  50000.0   Alice
    1  25.0000  60000.0     Bob
    2  30.0000  60000.0  Charlie
    3  30.0000  70000.0   David
    4  35.0000  80000.0     Eve
  4. 预测填充示例代码

    python 复制代码
    import pandas as pd
    from sklearn.ensemble import RandomForestRegressor
    
    # 创建示例数据
    data = {
        'Age': [25, np.nan, 30, np.nan, 35],
        'Salary': [50000, 60000, np.nan, 70000, 80000],
        'Experience': [2, 3, 5, 4, 6]
    }
    
    df = pd.DataFrame(data)
    
    # 将数据分割为训练集和测试集(仅用于预测缺失值)
    X_train = df[['Experience', 'Salary']].dropna()
    y_train = df[['Age']].dropna()
    
    X_test = df[['Experience', 'Salary']][df['Age'].isna()]
    
    # 训练随机森林模型来预测缺失的 Age
    model = RandomForestRegressor()
    model.fit(X_train, y_train.values.ravel())
    
    # 预测缺失值
    predicted_ages = model.predict(X_test)
    
    # 填补到原始数据中
    df.loc[df['Age'].isna(), 'Age'] = predicted_ages
    
    print("预测填充后数据:")
    print(df)
    
    
    ##########输出结果##########
    输出结果:
    
    预测填充后数据:
           Age   Salary  Experience
    0  25.0000  50000.0           2
    1  30.0000  60000.0           3
    2  30.0000     NaN            5
    3  30.0000  70000.0           4
    4  35.0000  80000.0           6

3. MNAR(Missing Not at Random)原理及处理方式

  • 定义: MNAR表示缺失值的分布与未观测到的变量有关,即缺失值本身含有信息。
  • 处理方式: 对于MNAR,通常无法通过简单的方法填补缺失值,需要更复杂的方法。常用方法包括:
  1. 模型预测: 使用其他特征训练一个模型来预测缺失值。

  2. 引入指示变量: 为缺失值引入指示变量,表示该值是否缺失。

  3. 多重插值法: 通过多次插值来估计缺失值的分布。

  4. 示例代码(模型预测)

    python 复制代码
    import pandas as pd
    from sklearn.ensemble import RandomForestRegressor
    
    # 创建示例数据
    data = {
        'Age': [25, np.nan, 30, np.nan, 35],
        'Salary': [50000, 60000, np.nan, 70000, 80000],
        'Experience': [2, 3, 5, 4, 6]
    }
    
    df = pd.DataFrame(data)
    
    # 将数据分割为训练集和测试集(仅用于预测缺失值)
    X_train = df[['Experience', 'Salary']].dropna()
    y_train = df[['Age']].dropna()
    
    X_test = df[['Experience', 'Salary']][df['Age'].isna()]
    
    # 训练随机森林模型来预测缺失的 Age
    model = RandomForestRegressor()
    model.fit(X_train, y_train.values.ravel())
    
    # 预测缺失值
    predicted_ages = model.predict(X_test)
    
    # 填补到原始数据中
    df.loc[df['Age'].isna(), 'Age'] = predicted_ages
    
    print("预测填充后数据:")
    print(df)
    
    
    
    ########输出结果##############
    
    输出结果:
    
    预测填充后数据:
           Age   Salary  Experience
    0  25.0000  50000.0           2
    1  30.0000  60000.0           3
    2  30.0000     NaN            5
    3  30.0000  70000.0           4
    4  35.0000  80000.0           6

4. 缺失值的处理总结

缺失值的处理需要根据其缺失机制(MCAR, MAR, MNAR)选择合适的方法:

  1. MCAR: 删除记录或均值/中位数填充。
  2. MAR: 均值填充或预测填充。
  3. MNAR: 预测填充或引入指示变量。

每种方法都有其优缺点,选择时需要结合数据特性和业务背景。

三、转换数据格式(Data Transformation)

1. 标准化/归一化(Normalization/Standardization)

使不同尺度的数据具有相同的范围或分布,有助于某些算法(如SVM、KNN)更好地工作。

  • 标准化:标准化将数据缩放到均值为0,标准差为1的范围;

  • 归一化:使数据在0到1之间。

    • 标准化实现原理:使用公式

      其中μ是均值,σ是标准差。

    • 归一化实现原理:使用公式

    • 代码示例

      from sklearn.preprocessing import StandardScaler, MinMaxScaler
      
      # 示例数据
      X = [[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]]
      
      # 标准化
      scaler = StandardScaler()
      X_std = scaler.fit_transform(X)
      print("标准化后的数据:")
      print(X_std)
      
      # 归一化
      min_max_scaler = MinMaxScaler()
      X_normalized = min_max_scaler.fit_transform(X)
      print("\n归一化后的数据:")
      print(X_normalized)
      
      ########输出结果########
      
      标准化后的数据:
       [[-1.06904497 -1.06904497 -1.06904497]
       [ 0.         0.         0.        ]
       [ 1.06904497 1.06904497 1.06904497]]
      
      归一化后的数据:
       [[0.         0.         0.        ]
       [0.5        0.5        0.5       ]
       [1.         1.         1.        ]]
      

2. 类别编码

类别编码是将非数值型特征(类别型特征)转换为数值形式的过程,以便机器学习算法能够处理。常见的类别编码方法包括独热编码(One-Hot Encoding)标签编码(Label Encoding)。这两种方法有不同的实现原理和适用场景,下面分别详细说明并提供代码示例。

1. 独热编码(One-Hot Encoding)

实现原理:

  • 独热编码为每个类别创建一个新的二进制列(0或1),表示该类别是否存在。
  • 例如,一个类别型特征有3个取值(A、B、C),独热编码会生成3个新列,每个列对应一个类别,值为1表示该类别存在,0表示不存在。

适用场景:

  • 当类别之间没有自然的顺序关系时(例如:颜色、性别等)。

  • 适合线性模型,因为可以避免引入类别之间的虚假顺序。

  • 代码示例:

    Matlab 复制代码
    import pandas as pd
    
    # 创建示例数据
    data = {
        'Color': ['Red', 'Green', 'Blue', 'Red', 'Green'],
    }
    
    df = pd.DataFrame(data)
    print("原始数据:")
    print(df)
    
    # 独热编码实现
    df_encoded = pd.get_dummies(df, columns=['Color'])
    print("\n独热编码后数据:")
    print(df_encoded)
    
    ####输出结果#######
    
    输出结果:
    
    原始数据:
        Color
    0    Red
    1  Green
    2   Blue
    3    Red
    4  Green
    
    独热编码后数据:
       Color_Red  Color_Green  Color_Blue
    0          1             0            0
    1          0             1            0
    2          0             0            1
    3          1             0            0
    4          0             1            0

2. 标签编码(Label Encoding)

实现原理:

  • 标签编码为每个类别分配一个唯一的整数值(通常是0到n-1),表示该类别的唯一标识。
  • 例如,一个类别型特征有3个取值(A、B、C),标签编码会将其转换为0、1、2。

适用场景:

  • 当类别之间存在自然的顺序关系时(例如:Low < Medium < High)。

  • 适用于树模型(如随机森林、梯度提升树等),因为树模型可以自然处理类别与整数的映射关系。

  • 代码示例:

    Matlab 复制代码
    from sklearn.preprocessing import LabelEncoder
    
    # 创建示例数据
    data = {
        'Size': ['Small', 'Medium', 'Large', 'Small', 'Medium'],
    }
    
    df = pd.DataFrame(data)
    print("原始数据:")
    print(df)
    
    # 标签编码实现
    encoder = LabelEncoder()
    df_encoded = df.copy()
    df_encoded['Size'] = encoder.fit_transform(df['Size'])
    print("\n标签编码后数据:")
    print(df_encoded)
    
    
    ####输出结果#######
    
    输出结果:
    
    原始数据:
        Size
    0  Small
    1 Medium
    2  Large
    3  Small
    4 Medium
    
    标签编码后数据:
       Size
    0     2
    1     1
    2     0
    3     2
    4     1

3. 独热编码 vs 标签编码:优缺点对比

方法 优点 缺点
独热编码(One-Hot) 1. 处理无序类别时不引入顺序关系 1. 会增加数据维度(特征膨胀)
2. 适合线性模型 2. 当类别数较多时,计算效率较低
标签编码(Label) 1. 不会增加数据维度 1. 如果类别之间无序,会引入虚假顺序关系
2. 适合树模型(如随机森林、XGBoost) 2. 无法处理缺失值(需要提前处理)

四、总结

有效的数据预处理不仅能提升模型的表现,还能减少不必要的计算成本。通过对数据进行清洗、填充缺失值和转换数据格式等操作,我们可以确保输入到机器学习模型中的数据是高质量的,从而获得更准确可靠的预测结果。

相关推荐
problc22 分钟前
Manus AI 全球首款通用型 Agent,中国制造
大数据·人工智能·制造
xiangzhihong824 分钟前
GitHub神秘组织3小时极速复刻Manus
人工智能·深度学习·机器学习
上官-王野37 分钟前
大模型day01自然语言+大模型+环境
python·ai·conda
博云技术社区44 分钟前
DeepSeek×博云AIOS:突破算力桎梏,开启AI普惠新纪元
人工智能·博云·deepseek
ZHOU_WUYI1 小时前
Process-based Self-Rewarding Language Models 论文简介
人工智能·深度学习
优维科技EasyOps1 小时前
优维眼中的Manus:AI工程化思维重构Agent的运维端启示
运维·人工智能·重构
碣石潇湘无限路1 小时前
【奇点时刻】通义千问开源QwQ-32B技术洞察报告(扫盲帖)
人工智能·开源
西猫雷婶1 小时前
神经网络|(十五)|霍普菲尔德神经网络-Storkey 训练
人工智能·深度学习·神经网络
d3soft1 小时前
【清华大学】实用DeepSeek赋能家庭教育 56页PDF文档完整版
ai·pdf·deepseek
张申傲1 小时前
DeepSeek + ReAct 实现 Agent
人工智能·ai·chatgpt·aigc·deepseek