📦 模块1:"数据质量:您的模型只与您的数据一样好"

目标:

理解为什么预处理不是可选项——它 是任何成功机器学习模型的核心。学会在接触任何算法之前诊断数据集的健康状况。


1.1 为什么预处理占80%的工作?

"数据科学80%是数据清理,20%是抱怨清理数据。" ——匿名

在现实世界中,数据从不干净、有序且准备就绪。它通常带有:

  • 缺失值(NaNNone""?
  • 打字错误("Madird"、"Barcelonaa")
  • 极端异常值(在平均收入调查中出现9999999的工资)
  • 不一致的格式(日期如"2024/05/01"、"01-May-2024"、"1 de mayo")
  • 非标准化的分类变量("Sí"、"si"、"SI"、"yes")

直接后果: 将脏数据输入模型会导致其学习错误的模式。垃圾进→垃圾出。


1.2 初始数据集诊断

在做任何事情之前,像侦探一样探索您的数据集。

关键Pandas工具:

import pandas as pd

# 加载数据集
df = pd.read_csv("欺诈数据.csv")

# 快速预览
print(df.head())
print(df.info())  # 数据类型和非空计数
print(df.describe())  # 描述性统计(仅数值)

# 查看分类列中的唯一值
print(df['交易类型'].unique())
print(df['国家'].value_counts())

# 检查空值
print(df.isnull().sum())

使用Seaborn进行诊断可视化:

import seaborn as sns
import matplotlib.pyplot as plt

# 数值变量的直方图
sns.histplot(df['交易金额'], bins=50, kde=True)
plt.title("交易金额分布")
plt.show()

# 箱线图检测异常值
sns.boxplot(x=df['交易金额'])
plt.title("箱线图:发现金额中的异常值")
plt.show()

# 分类变量的条形图
sns.countplot(data=df, x='卡片类型')
plt.title("卡片类型分布")
plt.xticks(rotation=45)
plt.show()

1.3 处理缺失值

如何处理NaN?

选项1:删除行或列

# 删除包含任何NaN的行
df_clean = df.dropna()

# 删除包含超过50% NaN的列
df_clean = df.dropna(axis=1, thresh=len(df)*0.5)

⚠️ 注意: 仅在丢失少量数据点时建议使用。如果您删除了30%的行,您的模型可能会产生偏差。


选项2:插补(用值填充)

from sklearn.impute import SimpleImputer

# 对数值变量进行均值插补
imputer_num = SimpleImputer(strategy='mean')
df[['年龄', '交易金额']] = imputer_num.fit_transform(df[['年龄', '交易金额']])

# 对分类变量进行众数插补
imputer_cat = SimpleImputer(strategy='most_frequent')
df[['卡片类型']] = imputer_cat.fit_transform(df[['卡片类型']])

最佳实践: 使用ColumnTransformer对不同列应用不同策略(我们将在模块3中详细讨论)。


1.4 处理异常值

什么是异常值?

显著偏离其余数据的值。它可能是:

  • 输入错误(例如,年龄=999)
  • 真实但极端的情况(例如,在平均购买金额为50美元的数据集中出现1,000,000美元的交易)

检测方法:

  • IQR规则(四分位距):
Q1 = df['交易金额'].quantile(0.25)
Q3 = df['交易金额'].quantile(0.75)
IQR = Q3 - Q1

下限 = Q1 - 1.5 * IQR
上限 = Q3 + 1.5 * IQR

异常值 = df[(df['交易金额'] < 下限) | (df['交易金额'] > 上限)]
print(f"检测到的异常值:{len(异常值)}")

如何处理它们?

  • 删除它们(如果是明显错误)
  • 封顶: 用上下限替换
df['交易金额'] = df['交易金额'].clip(lower=下限, upper=上限)
  • 对数变换(如果分布高度偏斜)
df['对数金额'] = np.log1p(df['交易金额'])  # log(1+x)避免log(0)

📝 练习1.1:诊断和清理

建议数据集: 欺诈数据.csv(模拟数据,包含列:用户ID金额年龄国家卡片类型一天中的时间是否欺诈

任务:

  1. 加载数据集并显示.info().describe()
  2. 识别哪些列有缺失值并决定如何插补它们(请说明您的选择理由)。
  3. 使用箱线图识别金额中的异常值。应用基于IQR的封顶。
  4. 检查年龄分布。是否存在不可能的值(例如,年龄<0或>120)?纠正它们。
  5. 将清理后的数据集保存为欺诈_清理.csv

💡 附加说明:

  • 永远不要假设数据是干净的。 总是先探索。
  • 记录每个更改。 使用注释或markdown单元格解释为什么要删除或插补某些内容。
  • 异常值并不总是坏的。 在欺诈检测中,异常值可能正是您要寻找的!

Course Info

Course: AI-course1

Language: ZH

Lesson: Module1