Menu
CoddyTech

在管道中填补缺失值

本课属于 Coddy Machine Learning 学习旅程的“监督学习”单元。第 47 课,共 58 课。

真实日志中会有缺失值,而大多数模型无法处理这些缺失值。SimpleImputer 会用所在列的平均值、中位数或最常见值填补每个缺失值。

在划分数据之前填补缺失值,而测试行也参与了这个值的选择:这会造成数据泄漏。7 个潜水深度,其中有一个缺失值:

两份包含 8 个潜水深度的列副本,最后两行标记为测试行,其中一个单元格缺失。左侧,先填补再划分:缺失值被填为 21.3,这是所有 7 个已知深度的平均值,测试行也被计入了,造成数据泄漏。右侧,先划分再使用管道:缺失值被填为 18.0,这是仅根据训练行计算出的平均值

在流水线中,fit 只会根据训练行学习填充值:

from sklearn.impute import SimpleImputer

pipe = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(), model)
pipe.fit(X_train, y_train)
print(pipe[0].statistics_)  # 第一步的填充值

对于潜水记录(深度、分钟数、水温),这会打印:

[19. 44. 21.]

对于文本,数字的处理步骤也会成为 ColumnTransformer 中的一条流程:

lane = make_pipeline(SimpleImputer(strategy="median"), StandardScaler())
("numbers", lane, ["depth_m", "minutes"])
challenge icon

挑战

中等

林业部门会预测哪些雷击会引发火灾,但有些读数缺失。起始代码会拆分 wildfire.csv,并读取一种策略:mean 或 median。

  1. 使用该策略的填补器、缩放器和逻辑回归创建流水线并进行拟合。打印测试准确率。
  2. 对于每一列,打印流水线填入的值,以及使用 X 的所有行计算出的值,保留 1 位小数。

另一个森林,使用 median:

Test accuracy: 0.840
humidity_pct: fill 46.0, all rows would give 46.0
wind_kmh: fill 29.0, all rows would give 32.0
temp_c: fill 25.0, all rows would give 26.0
days_without_rain: fill 23.0, all rows would give 23.0

在两者不同的地方,如果在拆分前填补缺失值,测试行就会影响训练数据。

亲手试试

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline

# 干燥的森林遭到雷击:雷击是否引发了火灾(1 表示是,0 表示否)?
# 部分天气观测数据缺失。
strikes = pd.read_csv("wildfire.csv")
columns = ["humidity_pct", "wind_kmh", "temp_c", "days_without_rain"]
X = strikes[columns]
y = strikes["fire"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
strategy = input()

# 在下方编写你的代码
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

监督学习中的所有课

自己练习: Python 在线编译器