机器学习实践-01数据准备流程

机器学习实践-01数据准备流程

  • 1.导入库
  • 2.加载数据
  • 3.数据探索
    • [3.1 打印数据信息(辅助删除无意义字段、识别类别/数值特征)](#3.1 打印数据信息(辅助删除无意义字段、识别类别/数值特征))
    • 3.2绘图(使用matplotlib和seaborn库)
      • [3.2.1 直方图](#3.2.1 直方图)
      • [3.2.2 箱线图](#3.2.2 箱线图)
      • [3.2.3 散点图](#3.2.3 散点图)
      • [3.2.4 相关性热力图](#3.2.4 相关性热力图)
      • [3.2.5 特征配对图](#3.2.5 特征配对图)
      • [3.2.6 小提琴图](#3.2.6 小提琴图)
      • [3.2.7 计数图](#3.2.7 计数图)
  • 4.缺失值、异常值处理
    • [4.1 缺失值处理](#4.1 缺失值处理)
    • [4.2 异常值处理](#4.2 异常值处理)
  • 5.离散数据编码
    • [6.1 标签编码(LabelEncoder,适合有序分类 / 标签列)](#6.1 标签编码(LabelEncoder,适合有序分类 / 标签列))
    • [6.2 离散特征独热编码(鸢尾花数据集没有离散特征,因此以最后一列作为示例)](#6.2 离散特征独热编码(鸢尾花数据集没有离散特征,因此以最后一列作为示例))
  • [6.划分训练集 / 测试集](#6.划分训练集 / 测试集)
  • 7.数据标准化
  • 8.输出可训练数据(可选)

机器学习比较完整的实践流程为
①问题定义(回归、分类、聚类)
②数据采集(公开数据集、自采数据集)
③数据探索及预处理(缺失值、异常值)
④离散特征编码
⑤数据集划分(聚类不需要)
⑥数据标准化 / 归一化
⑦特征工程
⑧模型评估(留出法、交叉验证法等等)
⑨模型构建与训练
⑩模型预测
最后调参优化模型

其中,数据探索及预处理就像做饭前的洗菜切菜工作。下列是较为详细的过程。

1.导入库

导入核心工具库,包括numpy(数值、矩阵运算)、pandas(处理表格数据)、sklearn(机器学习各种方法)、matplotlib(任何图)、seaborn(好看的统计图表,Matplotlib的升级、美化版)等。

安装方法(后面是清华源镜像地址,可以不用科学上网快速安装所有库):

bash 复制代码
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install seaborn -i https://pypi.tuna.tsinghua.edu.cn/simple

导入:

bash 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.XXX import XXX(这里XXX需要看具体的需求,数据预处理\数据集划分\模型训练\模型评估等)

2.加载数据

读取数据,有两种形式,一种是读取sklearn内置数据,一种是读取本地数据集,这里以鸢尾花数据集为例。

2.1 读取sklearn内置数据

bash 复制代码
import pandas as pd
from sklearn.datasets import load_iris  # 自带数据集
# 1. 加载数据
iris = load_iris()

X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = pd.Series(iris.target)

2.2读取本地数据集

bash 复制代码
import pandas as pd
df = pd.read_csv("iris.csv")  #文件需要和代码在同一文件夹
#读取本地Excel文件
# df = pd.read_excel("iris.xlsx")

3.数据探索

数据探索包括

①打印数据信息 (文本形式)

②绘图

3.1 打印数据信息(辅助删除无意义字段、识别类别/数值特征)

bash 复制代码
print(df.head()) #打印数据集前几行,默认为前5行
print(df.info()) #打印数据基本信息
print(df.describe())#打印数据集统计信息,包括总数、最大值、最小值等

df.drop("Unnamed: 0", axis=1, inplace=True)##删除索引列

3.2绘图(使用matplotlib和seaborn库)

3.2.1 直方图

查看单个特征的数据分布、是否对称、有无异常值、是否接近正态分布

bash 复制代码
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure(figsize=(8,4))
plt.hist(df['sepal_length'], bins=15, color='skyblue', edgecolor='black')
plt.title('花萼长度直方图')
plt.xlabel('sepal_length')
plt.ylabel('count')
plt.show()

3.2.2 箱线图

检测异常值、查看数据离散程度、对比不同类别特征的分布差异

bash 复制代码
import seaborn as sns

plt.figure(figsize=(8,5))
sns.boxplot(x='species', y='sepal_length', data=df)
plt.title('不同品种花萼长度箱线图')
plt.show()

3.2.3 散点图

查看两个特征之间的关系、是否线性相关、不同品种是否能明显区分

bash 复制代码
plt.figure(figsize=(8,6))
sns.scatterplot(x='sepal_length', y='petal_length', hue='species', data=df)
plt.title('花萼长度 vs 花瓣长度')
plt.show()

3.2.4 相关性热力图

直观展示所有数值特征之间的相关性强弱,用于特征筛选

bash 复制代码
# 只取数值列计算相关系数
df.drop("Unnamed: 0", axis=1, inplace=True)
numeric_df = df.select_dtypes(include=['number'])

plt.figure(figsize=(8,6))
sns.heatmap(numeric_df.corr(), annot=True, cmap='coolwarm', fmt='.2f')
plt.title('特征相关性热力图')
plt.show()

3.2.5 特征配对图

一次性查看所有特征两两之间的关系 + 单特征分布,最适合分类任务

bash 复制代码
sns.pairplot(df, hue='species')
plt.show()

3.2.6 小提琴图

结合箱线图 + 密度分布,同时展示数据分布形状、离散度、密度

python 复制代码
plt.figure(figsize=(8,5))
sns.violinplot(x='species', y='petal_length', data=df)
plt.title('不同品种花瓣长度小提琴图')
plt.show()

3.2.7 计数图

查看每个类别样本数量是否均衡,判断数据集是否平衡

bash 复制代码
plt.figure(figsize=(6,4))
sns.countplot(x='species', data=df)
plt.title('鸢尾花品种数量统计')
plt.show()

4.缺失值、异常值处理

4.1 缺失值处理

bash 复制代码
print(df.isnull().sum())#检查缺失值

col = '含有空白值的列名'
方法名称 方法作用 可直接运行代码 适用场景
均值填充 使用整列特征的平均值填充缺失值 df[col] = df[col].fillna(df[col].mean()) 数据服从正态分布、无明显异常值
中位数填充 使用整列特征的中位数填充 df[col] = df[col].fillna(df[col].median()) 数据分布偏态、存在异常值(机器学习最常用)
众数填充 使用出现次数最多的数值填充 df[col] = df[col].fillna(df[col].mode()[0]) 离散数值特征、整数型数据
固定值填充 使用自定义常数填充 df[col] = df[col].fillna(0) 缺失本身代表特定含义(未记录/未测量)
前向填充 使用上方一行数据向下填充 df[col] = df[col].ffill() 时序数据、顺序有连续性的数据
后向填充 使用下方一行数据向上填充 df[col] = df[col].bfill() 时序数据、顺序有连续性的数据
线性插值填充 根据前后数值线性推算缺失值 df[col] = df[col].interpolate(method='linear') 连续变化特征、时序数据
分组填充 按分类标签分组后填充 df[col] = df.groupby('species')[col].transform(lambda x: x.fillna(x.median())) 分类任务,缺失值与类别高度相关
KNN 模型填充 通过邻近样本特征预测缺失值 from sklearn.impute import KNNImputer numeric_cols = df.select_dtypes(include=[np.number]).columns imputer = KNNImputer(n_neighbors=5) df[numeric_cols] = imputer.fit_transform(df[numeric_cols]) 缺失值较多、追求高精度填充
直接删除 删除包含缺失值的行/列 df = df.dropna(subset=[col]) 缺失率极低(<5%),删除不影响数据量

4.2 异常值处理

箱线图外面的点 → 异常值

直方图远离群体 → 异常值

散点图孤零零的点 → 异常值

print(df.describe ()) 最大 / 最小值极端 → 异常值

方法名称 方法作用 可直接运行代码 适用场景
箱线图法(IQR 法) 基于四分位数识别并删除异常值,最常用且稳定 见下方完整代码 适用于绝大多数数值特征,无严格分布要求
3σ 原则(Z 分数法) 正态分布下,将超出 ±3σ 的值视为异常值 见下方完整代码 数据近似服从正态分布时适用
百分位法 通过上下百分位截断,消除极端值影响 df = df[(df[col] > 0.01) & (df[col] < 0.99)] 存在极端大/小值的情况
盖帽法(分位数替换) 保留样本,将异常值替换为分位数边界值 见下方完整代码 样本量小且不希望删除数据时适用
直接删除法 直接删除包含异常值的行 `df = df[~((df[col] < lower) (df[col] > upper))]`
按类别处理异常值 按不同类别分别处理异常值,提高精准度 df = df.groupby('species').apply(remove_outliers) 适用于分类任务(如鸢尾花数据集)
bash 复制代码
# 异常值处理:箱线图法(IQR法)
import numpy as np

# 定义异常值处理函数
#箱线图法(IQR)
def remove_outliers(df, col):
    Q1 = df[col].quantile(0.25)  # 下四分位数
    Q3 = df[col].quantile(0.75)  # 上四分位数
    IQR = Q3 - Q1                # 四分位距
    lower_bound = Q1 - 1.5 * IQR # 下界
    upper_bound = Q3 + 1.5 * IQR # 上界
    # 保留正常范围内的数据
    df_clean = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]
    return df_clean

# 对鸢尾花所有数值特征批量处理异常值
numeric_cols = ['sepal_length','sepal_width','petal_length','petal_width']
for col in numeric_cols:
    df = remove_outliers(df, col)

print("异常值处理完成,数据形状:", df.shape)
bash 复制代码
# 异常值处理:3σ原则(Z分数法)
 #3σ 原则(Z 分数法)
def remove_outliers_zscore(df, col):
    mean = df[col].mean()
    std = df[col].std()
    lower_bound = mean - 3 * std
    upper_bound = mean + 3 * std
    df_clean = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]
    return df_clean

# 批量处理所有数值列
numeric_cols = df.select_dtypes(include=[np.number]).columns
for col in numeric_cols:
    df = remove_outliers_zscore(df, col)

print("异常值处理完成,数据形状:", df.shape)

5.离散数据编码

6.1 标签编码(LabelEncoder,适合有序分类 / 标签列)

bash 复制代码
# 对species列做标签编码(0,1,2对应3个品种)
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
le = LabelEncoder()
df['species'] = le.fit_transform(df['species'])
print(df.head())

6.2 离散特征独热编码(鸢尾花数据集没有离散特征,因此以最后一列作为示例)

bash 复制代码
# 对species列做独热编码(生成3列0/1特征)
# 方式1:pandas原生get_dummies(简单易用)
df_onehot = pd.get_dummies(df, columns=['species'], drop_first=True)
print(df_onehot.head())
bash 复制代码
#方式2 OneHotEncoder编码

# 1. 创建编码器
ohe = OneHotEncoder()
# 2. 对species列编码
encoded = ohe.fit_transform(df[["species"]]).toarray()
# 3. 转成 DataFrame
encoded_df = pd.DataFrame(encoded, columns=ohe.get_feature_names_out(["species"]))
# 4. 和原来的数字列合并(完整表格)
df_final = pd.concat([df.drop("species", axis=1), encoded_df], axis=1)

#不隐藏行列
pd.set_option("display.max_columns", None)
pd.set_option("display.width", None)
# pd.set_option('display.max_columns', 10)  # 显示最多10列
# pd.set_option('display.max_rows', 20)     # 显示最多20行
print(df_final.head())

6.划分训练集 / 测试集

bash 复制代码
from sklearn.model_selection import train_test_split
X = df.drop('species', axis=1)
y = df['species']

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)

# 查看结果
print("训练集特征形状:", X_train.shape)
print("测试集特征形状:", X_test.shape)
print("\n训练集标签分布:\n", y_train.value_counts())
print("\n测试集标签分布:\n", y_test.value_counts())

7.数据标准化

bash 复制代码
# 7. 数据标准化(Z-score 标准化)
from sklearn.preprocessing import StandardScaler

# 初始化标准化器
scaler = StandardScaler()

# 只在训练集上拟合(防止数据泄露)
X_train_scaled = scaler.fit_transform(X_train)

# 测试集直接用训练集的规则转换
X_test_scaled = scaler.transform(X_test)

# 查看结果
print("标准化前 训练集前2行:")
print(X_train[:2])
print("\n标准化后 训练集前2行:")
print(X_train_scaled[:2])

8.输出可训练数据(可选)

bash 复制代码
# 8. 输出处理完成的可训练数据(可选)
import pandas as pd

# 合并训练集(特征 + 标签)
train_df = pd.DataFrame(X_train_scaled, columns=X.columns)
train_df['species'] = y_train.reset_index(drop=True)

# 合并测试集
test_df = pd.DataFrame(X_test_scaled, columns=X.columns)
test_df['species'] = y_test.reset_index(drop=True)

# 保存为 CSV
train_df.to_csv("train_iris.csv", index=False, encoding="utf-8")
test_df.to_csv("test_iris.csv", index=False, encoding="utf-8")

print("可训练数据已保存!")
print("训练集:train_iris.csv")
print("测试集:test_iris.csv")
相关推荐
美团技术团队2 小时前
LongCat-Flash-Prover:AI 攻克数学定理证明,不仅要“算得对”,更要“证得严”
人工智能
Zero2 小时前
机器学习概率论与统计学--(13)线性回归
机器学习·线性回归·概率论·统计学
2301_764441332 小时前
2026年GitHub中比较热门的skills技能
人工智能·自然语言处理·开源·github
无心水2 小时前
OpenClaw与多Agent架构在HR数字化转型中的深度实践
人工智能·架构·多agent·openclaw·养龙虾·hr数字化转型
VBsemi-专注于MOSFET研发定制2 小时前
AI边缘计算网关功率MOSFET选型方案——高效、紧凑与高可靠电源系统设计指南
人工智能
IDCF社区2 小时前
重磅嘉宾|麻省理工学院(MIT)CSAIL 副主任 Daniel Jackson 分享:解码软件工程底层范式
人工智能
w_t_y_y2 小时前
Jupyter Notebook工具
人工智能
东方隐侠安全团队-千里2 小时前
基于SAST+AI代码审计 架构与功能详解
人工智能·microsoft·架构
极昆仑智慧2 小时前
NL2X技术正从模型驱动到系统工程驱动的范式转变
人工智能·自然语言处理·chatgpt