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

本文学习目标

掌握机器学习项目中 “数据预处理” 三大步骤(数据准备、数据转换、数据输出),学会处理缺失值、无效数据与冗余维度,并能够利用 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     float64
 2   gender  20 non-null     object 
 3   score   17 non-null     float64
 4   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     float64
 2   gender  16 non-null     object 
 3   score   16 non-null     float64
 4   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. 公式 X s c a l e d = ( X − X m i n ) / ( X m a x − X m i n ) 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标准化

  • 公式 X s t a n d a r d i z e d = ( 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. 公式 X n o r m a l i z e d = 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. 公式 X b i n a r y X_{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)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roman_日积跬步-终至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值