
最近邻插值(`interpolate(method='nearest')`)仅基于一维索引顺序查找相邻非空值,无法利用多维特征相似性;当缺失值位于序列首尾或连续缺失段中时,该方法失效,导致 titanic 测试集中两个年龄值未能填充。
在 Pandas 中,Series.interpolate(method='nearest') 并非机器学习意义上的“K-Nearest Neighbors(KNN)”插补,而是一种基于索引位置的简单邻值填充:它只考察当前缺失位置在 Series 索引轴上的上一个/下一个非 NaN 元素,并取其值——完全不考虑 'pclass'、'sex'、'fare' 等其他特征的语义相似性。
例如,在你的 titanic_Test['age'] 中,若第 416 和 417 行的 age 均为 NaN,且其前后若干行(如 415、418)也均为 NaN(即存在连续缺失),则 interpolate(method='nearest') 将因找不到有效邻值而保留 NaN。同样,若缺失值出现在 Series 开头(索引最小处)或结尾(索引最大处),且单侧无有效值,该方法亦无法回填。
✅ 正确实现基于特征相似性的 KNN 插补,应使用 sklearn.impute.KNNImputer:
from sklearn.impute import KNNImputer
import pandas as pd
# 构造用于插补的特征(建议包含与 age 相关的数值型变量)
features = ['pclass', 'sex', 'sibsp', 'parch', 'fare']
X_test = titanic_Test[features].copy()
# 注意:KNNImputer 要求输入为数值型,且无 NaN(但目标列 age 可含 NaN)
imputer = KNNImputer(n_neighbors=5)
titanic_Test['age_imputed'] = imputer.fit_transform(X_test)[:, features.index('pclass')] # ❌ 错误示例(不能这样索引)
# ✅ 正确做法:将 age 列也纳入特征矩阵(作为待插补目标),并对整列统一处理
X_with_age = titanic_Test[features + ['age']] # 包含 age(含 NaN)
X_imputed = imputer.fit_transform(X_with_age)
titanic_Test['age'] = X_imputed[:, -1] # 替换原 age 列⚠️ 注意事项:
- KNNImputer 默认对所有列进行标准化(z-score),确保不同量纲特征贡献均衡;
- sex 为类别变量(如 0/1 编码)可直接使用,但若为字符串需先标签编码;
- 若数据中存在大量缺失或高维稀疏特征,KNN 效果可能下降,此时可结合 IterativeImputer 或分组均值(如 titanic_Test.groupby(['pclass','sex'])['age'].transform('mean'))作为稳健备选。
总之,interpolate(method='nearest') 是索引驱动的一维填充工具,不是多变量 KNN 插补;残留 NaN 正是其设计局限的体现。转向 KNNImputer 或领域感知策略,才能真正实现基于乘客特征的合理年龄推断。










