当前位置: 首页 > news >正文

【机器学习【7】】数据预处理:数据准备、数据转换、数据输出

文章目录

  • 一、 数据准备
    • 1、加载数据并初步检查
    • 2、处理缺失值
    • 3、剔除无效数据
    • 4、去除冗余维度(特征选择)
      • 4.1、构建监督学习数据
      • 4.2、删除方差为0的特征
      • 4.3、删除与目标变量相关性低的特征
      • 4.4、使用SelectKBest选择最相关的特征
  • 二、 数据转换
    • 1、概述
      • 1.1、 什么是“量纲影响”?
      • 1.2、统一的数据转换入口:fit_transform
    • 2、 常用数据预处理方法
      • 2.1. Min-Max Scaling(最小-最大缩放)
      • 2.2. Z-Score标准化
      • 2.3. 正态化(Normalizer)
      • 2.4. 二值化
  • 三. 数据输出

本文学习目标

掌握机器学习项目中 “数据预处理” 三大步骤(数据准备、数据转换、数据输出),学会处理缺失值、无效数据与冗余维度,并能够利用 scikit-learn 对数据进行尺度调整、正态化、标准化及二值化,从而为后续模型训练奠定高质量数据基础。

 

一、 数据准备

本章通过加载数据、处理缺失值、剔除无效数据、删除方差为0特征、基于相关性筛选和SelectKBest自动选择,最终从原始7个特征筛选出2个最相关特征(id、age),完成了从数据清洗到特征选择的完整数据准备流程。

1、加载数据并初步检查

import pandas as pd
df = pd.read_csv('data.csv')
print("原始数据:")
print(df)
print(df.info())
原始数据:id    age gender  score  height  weight status
0    1   23.0      M   85.0     175      70    已完成
1    2   21.0      F   90.0     160      55    已完成
2    3   22.0      M   78.0     180      80    进行中
3    4   20.0      F   95.0     158      50    已完成
4    5    NaN      M  120.0     170      68    已取消
5    6   25.0      F    NaN     165      60    已完成
6    7   19.0      M   70.0     172      65    已完成
7    8   24.0      F  105.0     162      54    进行中
8    9  130.0      M   82.0     178      75    已完成
9   10   23.0      F   85.0     160      55    已完成
10  11   22.0      M   88.0     300      75    已完成
11  12   -5.0      F   92.0     150      45    已完成
12  13   28.0      M  110.0     180     200    已完成
13  14   30.0      F   99.0     165      60    已完成
14  15   27.0      M  101.0     170      68    已完成
15  16   26.0      F    NaN     165      60    已完成
16  17   23.0      M   85.0     175      70    已完成
17  18   21.0      F    NaN     160      55    已完成
18  19   22.0      M   78.0     180      80    进行中
19  20   20.0      F   95.0     158      50    已完成
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 7 columns):#   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  0   id      20 non-null     int64  1   age     19 non-null     float642   gender  20 non-null     object 3   score   17 non-null     float644   height  20 non-null     int64  5   weight  20 non-null     int64  6   status  20 non-null     object 
dtypes: float64(2), int64(3), object(2)
memory usage: 1.2+ KB
None

age和score有些空值。


2、处理缺失值

常见做法:

  • 删除含缺失值的行
  • 用均值/中位数/众数/指定值填充

代码示例:

# 删除含缺失值的行
df_clean = df.dropna()# # 用0填充所有缺失值
# df_filled = df.fillna(0)
#
# # 用每列均值填充
# df_mean = df.fillna(df.mean(numeric_only=True))
#
# # 针对某一列用中位数填充
# df['age'] = df['age'].fillna(df['age'].median())# 查看前几行,确认格式和字段
print(df_clean.head())
# 查看字段类型和缺失情况
print(df_clean.info())

去掉了含有空值的行

   id   age gender  score  height  weight status
0   1  23.0      M   85.0     175      70    已完成
1   2  21.0      F   90.0     160      55    已完成
2   3  22.0      M   78.0     180      80    进行中
3   4  20.0      F   95.0     158      50    已完成
6   7  19.0      M   70.0     172      65    已完成
<class 'pandas.core.frame.DataFrame'>
Index: 16 entries, 0 to 19
Data columns (total 7 columns):#   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  0   id      16 non-null     int64  1   age     16 non-null     float642   gender  16 non-null     object 3   score   16 non-null     float644   height  16 non-null     int64  5   weight  16 non-null     int64  6   status  16 non-null     object 
dtypes: float64(2), int64(3), object(2)
memory usage: 1.0+ KB
None

3、剔除无效数据

常见做法:

  • 过滤掉不合理的数值(如年龄为负、成绩大于100等)
  • 只保留业务需要的记录

代码示例:

# 只保留年龄在0~120之间的记录
df_valid = df[(df['age'] >= 0) & (df['age'] <= 120)]# 只保留成绩在0~100之间的记录
df_valid = df_valid[(df_valid['score'] >= 0) & (df_valid['score'] <= 100)]# 只保留状态为“已完成”的订单
df_valid = df_valid[df_valid['status'] == '已完成']# 查看前几行,确认格式和字段
print(df_valid.head())

筛选符合要求的数据

   id   age gender  score  height  weight status
0   1  23.0      M   85.0     175      70    已完成
1   2  21.0      F   90.0     160      55    已完成
3   4  20.0      F   95.0     158      50    已完成
6   7  19.0      M   70.0     172      65    已完成
9  10  23.0      F   85.0     160      55    已完成

4、去除冗余维度(特征选择)

常见做法:

  • 删除方差为0的特征(即所有值都一样)
  • 删除与目标变量无关或高度相关的特征
  • 用特征选择算法自动筛选

4.1、构建监督学习数据

准备机器学习模型的输入特征(X)和目标变量(y)

# 作用:从数据集中分离出输入特征(X)。axis=1:按列删除(axis=0是按行删除)
X = df_valid.drop(['score', 'gender', 'status'], axis=1)
# 作用:提取目标变量(y)。选择 'score' 列作为预测目标
# 这是监督学习中的标签(label)
y = df_valid['score']
print("\n数值型特征X:")
print(X)
print("\n目标变量y:")
print(y)
数值型特征X:id   age  height  weight
0    1  23.0     175      70
1    2  21.0     160      55
3    4  20.0     158      50
6    7  19.0     172      65
9   10  23.0     160      55
10  11  22.0     300      75
13  14  30.0     165      60
16  17  23.0     175      70
19  20  20.0     158      50目标变量y:
0     85.0
1     90.0
3     95.0
6     70.0
9     85.0
10    88.0
13    99.0
16    85.0
19    95.0
Name: score, dtype: float64

 

4.2、删除方差为0的特征

删除方差为0特征的作用:
提升计算效率:移除无变化特征,减少模型训练的计算开销
避免特征干扰:防止无信息特征对模型学习造成负面影响
保证特征质量:确保每个保留的特征都具有区分样本的能力

from sklearn.feature_selection import VarianceThreshold
# 创建方差阈值选择器,设置阈值为0.0。
# threshold=0.0:删除方差为0的特征(即所有值都相同的列)
# 也可以设置其他阈值,如 threshold=0.1 删除方差小于0.1的特征
selector = VarianceThreshold(threshold=0.0)# 对特征矩阵X进行方差阈值选择。
# fit_transform():先拟合(计算每列方差),再转换(删除低方差列)
# 返回的是NumPy数组,列名信息丢失
X_var = selector.fit_transform(X)
# 获取被保留的列名。
# selector.get_support():返回布尔数组,True表示保留的列
# indices=True:返回索引而不是布尔值
# X.columns[...]:根据索引获取对应的列名
selected_columns = X.columns[selector.get_support(indices=True)]
# 将NumPy数组转换回pandas DataFrame,并恢复列名。
X_var = pd.DataFrame(X_var, columns=selected_columns)
print("\n删除方差为0特征后的X:")
print(X_var)
删除方差为0特征后的X:id   age  height  weight
0   1.0  23.0   175.0    70.0
1   2.0  21.0   160.0    55.0
2   4.0  20.0   158.0    50.0
3   7.0  19.0   172.0    65.0
4  10.0  23.0   160.0    55.0
5  11.0  22.0   300.0    75.0
6  14.0  30.0   165.0    60.0
7  17.0  23.0   175.0    70.0
8  20.0  20.0   158.0    50.0

 

4.3、删除与目标变量相关性低的特征

删除与目标变量相关性低的特征能够:

  • 提升模型性能:移除对预测目标贡献很小的特征,让模型专注于真正重要的变量
  • 降低过拟合风险:减少噪声特征,避免模型学习到无关的虚假模式
  • 提高训练效率:减少特征维度,加快模型训练和预测速度
  • 增强可解释性:只保留有意义的特征,使模型结果更容易理解和解释
# 作用:计算特征与目标变量的相关性矩阵。
# pd.concat([X_var, y], axis=1):将特征矩阵X和目标变量y合并
# .corr():计算皮尔逊相关系数矩阵
cor_matrix = pd.concat([X_var, y], axis=1).corr()
print("\n相关性矩阵:")
print(cor_matrix)# 作用:找出与目标变量'score'相关性很低的特征。
# 获取目标变量'score'与其他特征的相关性,并筛选出小于0.3的特征
low_corr = cor_matrix['score'].abs() < 0.3
print("===========")
print(low_corr)
# 作用:获取需要删除的列名。
# 这是布尔索引,只保留值为 True 的行:
drop_cols = low_corr[low_corr].index
X_corr = X_var.drop(columns=drop_cols)print("\n删除相关性低特征后的X:")
print(X_corr)
相关性矩阵:id       age    height    weight     score
id      1.000000  0.233823  0.069203 -0.031490 -0.674926
age     0.233823  1.000000 -0.016136  0.173211 -0.999220
height  0.069203 -0.016136  1.000000  0.681087  0.204757
weight -0.031490  0.173211  0.681087  1.000000  0.119523
score  -0.674926 -0.999220  0.204757  0.119523  1.000000
===========
id        False
age       False
height     True
weight     True
score     False
Name: score, dtype: bool删除相关性低特征后的X:id   age
0   1.0  23.0
1   2.0  21.0
2   4.0  20.0
3   7.0  19.0
4  10.0  23.0
5  11.0  22.0
6  14.0  30.0
7  17.0  23.0
8  20.0  20.0

 

4.4、使用SelectKBest选择最相关的特征

SelectKBest的作用基于统计检验 自动选择与目标变量最相关的k个特征,通过F统计量评估特征重要性并保留得分最高的特征,实现自动化的特征筛选。

from sklearn.feature_selection import SelectKBest, f_regression
# 创建特征选择器
# score_func=f_regression:使用F统计量作为评分函数
# k=min(3, X_corr.shape[1]):选择前k个特征,最多选3个,不超过现有特征数
# X_corr.shape[1]:当前特征矩阵的列数
selector = SelectKBest(score_func=f_regression, k=min(3, X_corr.shape[1]))
# 执行特征选择
# fit_transform():先拟合(计算F统计量),再转换(选择特征)
# X_corr:输入特征矩阵、y:目标变量、 返回NumPy数组,只包含选中的特征
X_best = selector.fit_transform(X_corr, y)
# 获取被选中特征的列名
# selector.get_support():返回布尔数组,True表示被选中的特征
# indices=True:返回索引而不是布尔值
# X_corr.columns[...]:根据索引获取对应的列名
best_columns = X_corr.columns[selector.get_support(indices=True)]
print("\nSelectKBest筛选后的特征:", list(best_columns))
print(pd.DataFrame(X_best, columns=best_columns))
SelectKBest筛选后的特征: ['id', 'age']id   age
0   1.0  23.0
1   2.0  21.0
2   4.0  20.0
3   7.0  19.0
4  10.0  23.0
5  11.0  22.0
6  14.0  30.0
7  17.0  23.0
8  20.0  20.0

 

二、 数据转换

1、概述

在机器学习项目中,原始数据往往存在不同的取值范围、单位(量纲)、分布形态或异常点。如果不加处理,模型容易受到“量纲影响”——即某些数值范围大的特征主导模型训练,导致结果失真。因此,科学的数据预处理是提升模型效果的关键第一步

1.1、 什么是“量纲影响”?

量纲,也叫“单位”或“尺度”,指的是特征的取值范围和单位。例如,身高(cm)和体重(kg)在同一个数据集中,数值大小和单位完全不同。

量纲影响指的是:如果不同特征的数值范围差异很大,模型在计算距离或权重时,数值大的特征会主导结果,导致模型偏向这些特征,影响学习效果

 

1.2、统一的数据转换入口:fit_transform

scikit-learn 为各种数据转换器(如缩放、标准化、正态化、二值化等)提供了统一的 fit_transform 接口。它将“拟合参数”和“数据转换”合二为一,极大简化了数据预处理流程。

  • fit(X):计算并存储转换所需的统计量(如最大/最小值、均值、方差等)
  • transform(X):用已存储的统计量对数据进行转换
  • fit_transform(X):一步完成拟合和转换,推荐常用

拟合参数,指的是通过对训练数据进行分析、计算得到的、用于后续数据转换或建模的统计量或系数。
 
以数据预处理为例:

  • MinMaxScaler 的拟合参数:每一列的最小值和最大值(fit时计算,transform时用来缩放数据)。
  • StandardScaler 的拟合参数:每一列的均值和标准差(fit时计算,transform时用来标准化数据)。

 

2、 常用数据预处理方法

2.1. Min-Max Scaling(最小-最大缩放)

  1. 公式Xscaled=(X−Xmin)/(Xmax−Xmin)X_{scaled} = (X - X_{min}) / (X_{max} - X_{min})Xscaled=(XXmin)/(XmaxXmin)
  2. 作用:将特征缩放到指定区间(如0~1),消除不同量纲带来的影响。
  3. 适用场景:需要将数据限制在特定范围,如神经网络输入
# 1. Min-Max Scaling(调整数据尺度)
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = scaler.fit_transform(X_best)
print("1. Min-Max Scaling(0-1缩放):")
print("作用:将特征缩放到指定区间(0~1),消除不同量纲带来的影响")
print("适用场景:需要将数据限制在特定范围,如神经网络输入")
print("结果:")
print(pd.DataFrame(X_scaled, columns=best_columns))
print("\n" + "="*50)
1. Min-Max Scaling(0-1缩放):
作用:将特征缩放到指定区间(0~1),消除不同量纲带来的影响
适用场景:需要将数据限制在特定范围,如神经网络输入
结果:id       age
0  0.000000  0.363636
1  0.052632  0.181818
2  0.157895  0.090909
3  0.315789  0.000000
4  0.473684  0.363636
5  0.526316  0.272727
6  0.684211  1.000000
7  0.842105  0.363636
8  1.000000  0.090909==================================================

 

2.2. Z-Score标准化

  • 公式Xstandardized=(X−μ)/σX_{standardized} = (X - μ) / σXstandardized=(Xμ)/σ
  • 作用:将特征转换为均值为0、方差为1的分布,适合大多数机器学习算法。
  • 适用场景:线性回归、SVM、神经网络等需要标准化特征的算法
# 2. Z-Score标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_standardized = scaler.fit_transform(X_best)
print("2. Z-Score标准化:")
print("作用:将特征转换为均值为0、方差为1的分布,适合大多数机器学习算法")
print("适用场景:线性回归、SVM、神经网络等需要标准化特征的算法")
print("结果:")
print(pd.DataFrame(X_standardized, columns=best_columns))
print("\n" + "="*50)
2. Z-Score标准化:结果:id       age
0 -1.363740  0.218218
1 -1.204342 -0.436436
2 -0.885545 -0.763763
3 -0.407351 -1.091089
4  0.070844  0.218218
5  0.230242 -0.109109
6  0.708436  2.509506
7  1.186631  0.218218
8  1.664825 -0.763763==================================================

 

2.3. 正态化(Normalizer)

  1. 公式Xnormalized=X/∣∣X∣∣X_{normalized} = X / ||X||Xnormalized=X/∣∣X∣∣
  2. 作用:将每个样本缩放为单位范数,常用于文本特征或距离计算场景。
  3. 适用场景:文本分类、聚类算法、需要计算样本间距离的场景,但注意可能丢失原始数据的比例信息。
# 3. 正态化(Normalizer)
from sklearn.preprocessing import Normalizer
normalizer = Normalizer(norm='l2')
X_normalized = normalizer.fit_transform(X_best)
print("3. 正态化(L2范数):")
print("作用:将每个样本缩放为单位范数,常用于文本特征或距离计算场景")
print("适用场景:文本分类、聚类算法、需要计算样本间距离的场景")
print("结果:")
print(pd.DataFrame(X_normalized, columns=best_columns))
print("\n" + "="*50)
3. 正态化(L2范数):
作用:将每个样本缩放为单位范数,常用于文本特征或距离计算场景
适用场景:文本分类、聚类算法、需要计算样本间距离的场景
结果:id       age
0  0.043437  0.999056
1  0.094809  0.995495
2  0.196116  0.980581
3  0.345705  0.938343
4  0.398726  0.917070
5  0.447214  0.894427
6  0.422885  0.906183
7  0.594391  0.804176
8  0.707107  0.707107==================================================

 

2.4. 二值化

  1. 公式XbinaryX_{binary}Xbinary = 1 if X > threshold else 0
  2. 作用:按阈值将特征转换为0或1,适合需要离散特征的模型。
  3. 特点:简化数据,适合某些算法,但会丢失大量信息
  4. 适用场景:朴素贝叶斯、决策树等需要离散特征的算法
# 4. 二值化
from sklearn.preprocessing import Binarizer
# 创建一个二值化转换器,设置阈值为0.5。
# 含义:对于每个特征值,如果大于0.5则转换为1,否则为0。
binarizer = Binarizer(threshold=0.5)
X_binary = binarizer.fit_transform(X_normalized)
print("4. 二值化:")
print("作用:按阈值将特征转换为0或1,适合需要离散特征的模型")
print("适用场景:朴素贝叶斯、决策树等需要离散特征的算法")
print("结果:")
print(pd.DataFrame(X_binary, columns=best_columns))
print("\n" + "="*50)
4. 二值化:
作用:按阈值将特征转换为0或1,适合需要离散特征的模型
适用场景:朴素贝叶斯、决策树等需要离散特征的算法
结果:id  age
0  0.0  1.0
1  0.0  1.0
2  0.0  1.0
3  0.0  1.0
4  0.0  1.0
5  0.0  1.0
6  0.0  1.0
7  1.0  1.0
8  1.0  1.0==================================================

 

三. 数据输出

将处理后的数据保存为NumPy数组或pandas DataFrame,供下游模型使用。可通过pd.to_csv('processed.csv', index=False)导出到文件系统。

df_out.to_csv('processed.csv', index=False)
# index=False 表示不保存行索引到文件df_loaded = pd.read_csv('processed.csv')
print(df_loaded.head())
     id   age  score
0   1.0  23.0   85.0
1   2.0  21.0   90.0
2   4.0  20.0   95.0
3   7.0  19.0   70.0
4  10.0  23.0   85.0

 

合理的数据预处理能够显著提升多数机器学习算法的准确度与收敛速度。实验表明,在相同算法下,经过标准化或正态化的数据往往获得更稳定、更优的评估指标(如准确率、AUC)。

http://www.dtcms.com/a/284162.html

相关文章:

  • 「Trae IDE 全流程实战」——从 0 下载安装,到在本地跑起一个可玩的 2048 小游戏
  • Java项目:基于SSM框架实现的在线视频点播管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • Redis学习系列之—— JDHotKey 热点缓存探测系统
  • 4.PCL点云的数据结构
  • Kotlin抽象类
  • Kotlin属性重写
  • 【web安全】DVWA反射型XSS漏洞分析与利用
  • web安全入门 | 记新手小白初次尝试挖越权漏洞
  • Java行为型模式---命令模式
  • AR智能巡检:制造业零缺陷安装的“数字监工”
  • 深入理解Java中的Collections.max()方法
  • Adobe Photoshop:数字图像处理的终极工具指南
  • 编译原理第六到七章(知识点学习/期末复习/笔试/面试)
  • 关于pytorch虚拟环境及具体bug问题修改
  • 摩尔投票法:高效寻找数组中的多数元素
  • Rabbitmq Direct Exchange(直连交换机)可以保证消费不被重复消费吗,可以多个消费者,但是需要保证同一个消息,不会被投递给多个消费者
  • 力扣.1312让字符串成为回文串的最少插入次数力扣.105从前序和中序遍历构造二叉树牛客.拼三角力扣.57插入区间​编辑
  • Vue3入门-计算属性+监听器
  • 分解质因数算法:从基础实现到高级应用
  • 【中等】题解力扣16:最接近的三数之和
  • 区块链共识机制:技术演进与行业突破
  • 【后端】.NET Core API框架搭建(8) --配置使用RabbitMQ
  • 算法训练营day23 39. 组合总和、 40.组合总和II 、131.分割回文串
  • 单发测量突破能域限制!Nature发布X射线拉曼超分辨新范式
  • Linux内存系统简介
  • 解决Python爬虫访问HTTPS资源时Cookie超时问题
  • Py-Clipboard :iOS与Windows互相共享剪贴板(半自动)
  • QT配置Quazip外部库
  • C++性能优化
  • 2021市赛复赛 初中组