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

机器学习中的数据准备关键技术

有效的数据准备对于构建强大的机器学习模型至关重要。本文档总结并阐述了为监督和非监督学习任务准备数据的关键技术。

1. 理解数据类型

有两种数据类型。定性数据描述对象的特征,而定量数据描述对象的数量。

定性(分类)数据

  • 名义:无序的命名类别(例如,性别,国家)。
    • 无法执行算术运算。
    • 使用独热编码或标签编码。
  • 有序:具有自然顺序的类别(例如,满意度:低,中,高)。
    • 通常用整数映射编码,保留顺序。

定量(数值)数据

  • 区间:具有有意义差异的数值数据,但无真实零点(例如,摄氏温度)。
    • 可以计算均值、中位数、标准差。
  • 比率:具有真实零点的数值数据(例如,收入,年龄)。
    • 所有算术运算有效。

离散与连续属性

  • 离散:可计数的值(例如,子女数量)。
  • 连续:范围内无限值(例如,身高,体重)。

2. 探索与总结数据

一旦从现实世界获取数据(数据收集),我们需要探索和总结数据(数据分析)。在这个阶段通常使用可视化来理解数据分布(数据分散度量)。

中心趋势度量

  • 均值:对异常值敏感。
  • 中位数:对异常值鲁棒,适用于偏态数据。
  • 众数:出现频率最高的值。

分布度量

  • 方差与标准差:显示数据如何围绕均值分布。
  • 范围、四分位数、四分位距:帮助检测异常值和数据偏态。

3. 数据可视化

可视化数据有很多方法。以下是一些常见的方法。
在示例中,我们将使用 matplotlib 库来绘制它们。

箱线图

  • 可视化五数概括:最小值,Q1,中位数,Q3,最大值。
  • 突出显示超出 1.5 × 四分位距的异常值。

直方图

  • 显示频率分布。
  • 帮助识别偏态、模态和分布范围。

散点图

  • 用于双变量关系。
  • 揭示两个变量之间的相关性和模式。

交叉表

  • 用于探索分类变量之间的关系。
  • 在矩阵中显示频率分布。

4. 数据质量问题与修复

处理缺失值和异常值是数据准备的重要步骤。现实世界的数据往往不完美。缺失数据、异常值和其他问题需要在此步骤中解决,以实现有效的机器学习。

缺失值

  • 原因:调查未响应、手动输入错误、数据损坏。
  • 修复方法
    • 删除:移除缺失数据的行/列(仅在安全的情况下)。
    • 插补
      • 均值/中位数(数值)
      • 众数(分类)
      • 基于组的插补(例如,按相似行)
    • 基于模型的估计:使用预测建模或相似性函数。

删除通常在删除一些数据行不会损失太多信息时应用。这通常与 dropna() 方法相关。另一方面,插补可能是一种更实际的方法,通过为缺失数据提供人工值来保留重要数据属性,同时不影响数据分布。

什么是插补?

插补是用替代值替换缺失数据的过程。这很关键,因为大多数机器学习算法无法直接处理缺失值。

常见的插补方法:

  1. 均值/中位数插补:用列的均值或中位数替换缺失值。
    • 适用于:无异常值的正态分布数据
    • 使用场景:数据完全随机缺失时
  2. 基于组的插补:用组的均值/中位数替换缺失值
    • 适用于:数据有意义的组
    • 示例:根据汽车气缸数填充缺失的马力
  3. KNN插补:使用k近邻插补缺失值
    • 适用于:数据存在模式
    • 最准确但计算成本高
  4. 任意值插补:用-999等值替换
    • 适用于:基于树的模型
    • 使用场景:希望缺失值突出时

异常值

异常值是与其他观测值显著不同的数据点。可能由测量错误、数据输入错误或自然变异引起。

异常值的影响:

  • 可能使统计度量偏斜
  • 可能影响模型性能
  • 可能导致模型受极端值影响过大

检测方法:

  1. 四分位距方法
    • 计算Q1(25th百分位)和Q3(75th百分位)
    • 四分位距 = Q3 - Q1
    • 下限 = Q1 - 1.5*四分位距
    • 上限 = Q3 + 1.5*四分位距
    • 超出这些界限的点被视为异常值
  2. Z分数方法
    • 计算Z分数:z = (x - 均值) / 标准差
    • |z| > 3 的点通常被视为异常值

处理技术:

  1. 封顶(Winsorization):将异常值替换为最近的非异常值
  2. 转换:应用对数、平方根或其他转换
  3. 移除:如果异常值是错误或不具代表性
  4. 单独建模:为异常值创建单独的模型

5. 特征缩放

许多机器学习算法在特征具有相似尺度时表现更好或收敛更快。缩放还确保不同量级的特征不会主导模型学习。

标准化(Z分数)

x ′ = x − μ σ x' = \frac{x - \mu}{\sigma} x=σxμ

  • 将数据中心化到均值为0,单位方差。
  • 用于数据有异常值或正态分布时。

归一化(最小-最大缩放)

x ′ = x − x min x max − x min x' = \frac{x - x_{\text{min}}}{x_{\text{max}} - x_{\text{min}}} x=xmaxxminxxmin

  • 将特征缩放到[0, 1]范围。
  • 对异常值敏感。

鲁棒缩放

  • 使用中位数和四分位距
  • 公式:(x - 中位数) / 四分位距
  • 适用于:有异常值的数据

何时缩放?

  • 需要缩放的场景
    • 基于距离的算法(KNN、K均值、带RBF核的SVM)
    • 神经网络
    • 正则化模型(Ridge、Lasso)
    • 主成分分析(PCA)
  • 无需缩放的场景
    • 基于树的模型(决策树、随机森林、XGBoost)
    • 朴素贝叶斯

6. 降维

减少特征数量,同时保留重要信息。

为什么降维?

  1. 维度灾难:随着维度增加,数据变得稀疏
  2. 减少过拟合:更少的特征意味着更少的参数需要学习
  3. 加速训练:减少计算需求
  4. 改进可视化:更容易可视化2D或3D数据

主成分分析(PCA)

  • 将数据投影到最大化方差的主成分上
  • 步骤:
    1. 标准化数据
    2. 计算协方差矩阵
    3. 计算特征向量和特征值
    4. 选择前k个特征向量
    5. 将数据转换到新空间

何时使用:

  • 当特征相关时
  • 用于可视化
  • 在训练具有许多特征的模型之前
  • 用于噪声减少

奇异值分解(SVD)

  • 矩阵分解方法,用于识别潜在特征。

7. 特征选择

选择最相关的特征子集以:

  • 减少过拟合
  • 提高模型可解释性
  • 降低计算成本

特征类型:

  • 无关:无预测能力。
  • 冗余:与其他特征重复信息。

方法:

  1. 过滤方法
    • 根据统计测试选择特征
    • 示例:相关系数、卡方检验
    • 快速但不考虑特征交互
  2. 包装方法
    • 使用特征子集训练模型
    • 示例:递归特征消除(RFE)
    • 计算成本高但更准确
  3. 嵌入方法
    • 特征选择作为模型训练的一部分
    • 示例:Lasso回归、决策树
    • 高效且准确,但特定于模型

总结表

任务技术
识别变量类型名义、有序、区间、比率
总结数值数据均值、中位数、标准差、四分位距
可视化数据直方图、箱线图、散点图
处理缺失值删除、插补、预测
处理异常值移除、封顶、调查
缩放特征标准化、归一化
降维主成分分析、奇异值分解
选择特征过滤、包装、嵌入方法

此笔记本使用关于汽车属性和燃油效率的假数据集说明数据准备的关键技术点。

示例数据集

# 导入所需库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
from sklearn.impute import SimpleImputer, KNNImputer
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest, f_regression, RFE
from sklearn.linear_model import LinearRegression# 假数据集
data = {"car_name": ["car_a", "car_b", "car_c", "car_d", "car_e", "car_f"],"cylinders": [4, 6, 8, 4, 4, 8],"displacement": [140, 200, 360, 150, 130, 3700],"horsepower": [90, 105, 215, 92, np.nan, 220], # np (numpy - 数字Python - 用于科学计算的库。nan: 非数字/空值)"weight": [2400, 3000, 4300, 2500, 2200, 4400],"acceleration": [15.5, 14.0, 12.5, 16.0, 15.0, 11.0],"model_year": [80, 78, 76, 82, 81, 77],"origin": [1, 1, 1, 2, 3, 1],"mpg": [30.5, 24.0, 13.0, 29.5, 32.0, 10.0]
}
df = pd.DataFrame(data)
df
car_namecylindersdisplacementhorsepowerweightaccelerationmodel_yearoriginmpg
0car_a414090.0240015.580130.5
1car_b6200105.0300014.078124.0
2car_c8360215.0430012.576113.0
3car_d415092.0250016.082229.5
4car_e4130NaN220015.081332.0
5car_f83700220.0440011.077110.0

数据类型

  • car_name:名义(分类)
  • cylinders, origin:有序/分类
  • displacement, horsepower, weight, acceleration, mpg:比率(数值)
  • model_year:区间

处理缺失值

# 1. 处理缺失值示例
print("=== 插补前的缺失值 ===")
print(df.isna().sum())# 均值插补
mean_imputer = SimpleImputer(strategy='mean')
df['horsepower_mean'] = mean_imputer.fit_transform(df[['horsepower']])# 基于组的插补
group_means = df.groupby('cylinders')['horsepower'].transform('mean')
df['horsepower_group'] = df['horsepower'].fillna(group_means)# KNN插补
knn_imputer = KNNImputer(n_neighbors=2)
df['horsepower_knn'] = knn_imputer.fit_transform(df[['horsepower']])print("\n=== 插补后 ===")
df[['horsepower', 'horsepower_mean', 'horsepower_group', 'horsepower_knn']]
=== 插补前的缺失值 ===
car_name        0
cylinders       0
displacement    0
horsepower      1
weight          0
acceleration    0
model_year      0
origin          0
mpg             0
dtype: int64=== 插补后 ===
horsepowerhorsepower_meanhorsepower_grouphorsepower_knn
090.090.090.090.0
1105.0105.0105.0105.0
2215.0215.0215.0215.0
392.092.092.092.0
4NaN144.491.0144.4
5220.0220.0220.0220.0

处理异常值

# 2. 处理异常值示例
def detect_and_handle_outliers(df, column):# 计算四分位距Q1 = df[column].quantile(0.25)Q3 = df[column].quantile(0.75)IQR = Q3 - Q1lower_bound = Q1 - 1.5 * IQRupper_bound = Q3 + 1.5 * IQR# 检测异常值outliers = df[(df[column] < lower_bound) | (df[column] > upper_bound)]print(f'在 {column} 中检测到 {len(outliers)} 个异常值')# 可视化前后对比plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)sns.boxplot(y=df[column])plt.title(f'原始 {column}')# 封顶异常值df[f'{column}_capped'] = np.where(df[column] > upper_bound, upper_bound,np.where(df[column] < lower_bound, lower_bound, df[column]))plt.subplot(1, 2, 2)sns.boxplot(y=df[f'{column}_capped'])plt.title(f'封顶后的 {column}')plt.tight_layout()plt.show()return dfdf = detect_and_handle_outliers(df, 'displacement')
在 displacement 中检测到 1 个异常值

请添加图片描述

特征缩放(标准化)

# 3. 特征缩放示例
# 原始数据
numeric_cols = ['weight', 'acceleration', 'displacement']
print('原始数据:')
print(df[numeric_cols].head())# 标准化
scaler = StandardScaler()
df_std = df.copy()
df_std[numeric_cols] = scaler.fit_transform(df[numeric_cols])# 最小-最大缩放
minmax = MinMaxScaler()
df_minmax = df.copy()
df_minmax[numeric_cols] = minmax.fit_transform(df[numeric_cols])print('\n标准化数据 (均值=0, 标准差=1):')
print(df_std[numeric_cols].head())print('最小-最大缩放数据 (范围 [0,1]):')
print(df_minmax[numeric_cols].head())
原始数据:weight  acceleration  displacement
0    2400          15.5           140
1    3000          14.0           200
2    4300          12.5           360
3    2500          16.0           150
4    2200          15.0           130标准化数据 (均值=0, 标准差=1):weight  acceleration  displacement
0 -0.820462      0.854242     -0.489225
1 -0.149175      0.000000     -0.443360
2  1.305280     -0.854242     -0.321054
3 -0.708580      1.138990     -0.481581
4 -1.044224      0.569495     -0.496869
最小-最大缩放数据 (范围 [0,1]):weight  acceleration  displacement
0  0.090909           0.9      0.002801
1  0.363636           0.6      0.019608
2  0.954545           0.3      0.064426
3  0.136364           1.0      0.005602
4  0.000000           0.8      0.000000

箱线图可视化

import matplotlib.pyplot as plt
import seaborn as snsplt.figure(figsize=(8, 5))
sns.boxplot(data=df[['mpg', 'weight', 'acceleration']])
plt.title("数值特征的箱线图")
plt.show()

请添加图片描述

直方图

df[['acceleration']].hist(bins=5, figsize=(6, 4))
plt.title("加速直方图")
plt.show()

请添加图片描述

散点图

sns.scatterplot(x='weight', y='mpg', data=df)
plt.title("散点图:重量 vs 每加仑英里数")
plt.show()

请添加图片描述

交叉表

pd.crosstab(df['origin'], df['cylinders'])
cylinders468
origin
1112
2100
3100

降维(主成分分析)

# 4. 降维示例
# 准备PCA数据
X = df[['weight', 'acceleration', 'displacement_capped']]
y = df['mpg']# 首先标准化数据
X_scaled = StandardScaler().fit_transform(X)# 应用PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)# 创建主成分的新数据框
df_pca = pd.DataFrame(data=X_pca, columns=['PC1', 'PC2'])
df_pca['mpg'] = y.values# 绘制结果
plt.figure(figsize=(8, 6))
scatter = plt.scatter(df_pca['PC1'], df_pca['PC2'], c=df_pca['mpg'], cmap='viridis')
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')
plt.colorbar(scatter, label='每加仑英里数')
plt.title('汽车特征的PCA')
plt.show()print(f'解释方差比例: {pca.explained_variance_ratio_}')
print(f'总解释方差: {sum(pca.explained_variance_ratio_):.2f}%')

请添加图片描述

解释方差比例: [0.95929265 0.02632386]
总解释方差: 0.99%

特征选择

如果通过特征重要性技术发现 car_namemodel_year 无关,我们可能会删除它们。

http://www.xdnf.cn/news/1014733.html

相关文章:

  • iOS性能调试完整流程实录:工具组合下的问题定位与修复实践(含keymob)
  • 云端求解热方程:源于傅里叶的洞察-AI云计算数值分析和代码验证
  • 前端处理后端对象类型时间格式通用方法封装,前端JS处理JSON 序列化后的格式 java.time 包中的日期时间类
  • TensorFlow 与 PyTorch区别
  • 新书速览|大模型核心技术与开发实践:基于Transformer、PyTorch及Hugging Face
  • 哈希表三种数据结构在leetcode中的使用情况分析
  • 【Linux】进程创建、终止、等待、替换
  • 精品可编辑PPT | 基于人工智能及大数据的综合智能交通管理平台AI大数据平替智慧交通
  • Text2SQL、Text2API基础
  • Windows安装Oracle19
  • Linux服务器如何诊断和解决网络问题
  • 应用探析|千眼狼高速摄像机、sCMOS相机、DIC测量、PIV测量在光学领域的应用
  • 04 - CoordAttention模块
  • 职业技能大赛视角下:高职院校课堂教学破局与提质之路
  • 位运算详解之与或非的巧妙运用
  • 【6-7-6.14学习周报】
  • 让 Deepseek 写电器电费计算器小程序
  • 朴朴超市小程序 sign-v2 分析
  • Docker Windows 配置国内镜像源方法
  • 堆排序详解:从理论到实践
  • Hadoop 002 — HDFS常用命令及SpringBoot整合操作
  • 微服务--消息队列mq
  • 准确--CentOS 7.9在线安装docker
  • 微服务--nacos+feign
  • 开发指南121-微服务的弹性伸缩
  • 20.excel制作图表,图表跟随数据行数的变化而自动更新
  • 【prometheus+Grafana篇】基于Prometheus+Grafana实现postgreSQL数据库的监控与可视化
  • 产品推荐|一款具有单光子级探测能力的科学相机千眼狼Gloria 1605
  • RabbitMQ的使用--项目创建、五种工作模式、高级特性
  • VR 虚拟云展:科技浪潮下的新趋势​