Scikit-learn中OneHotEncoder和KNNImpute之间的循环依赖问题

3

我正在处理一个非常简单的数据集。它包含一些分类和数值特征的缺失值。因此,我尝试使用sklearn.preprocessing.KNNImpute来获取最准确的插补结果。然而,当我运行以下代码时:

imputer = KNNImputer(n_neighbors=120)

imputer.fit_transform(x_train)

我遇到了错误:ValueError: could not convert string to float: 'Private'

这很合理,它显然无法处理分类数据。但是当我尝试使用以下代码运行 OneHotEncoder 时:

encoder = OneHotEncoder(drop="first")

encoder.fit_transform(x_train[categorical_features])

它会抛出错误:ValueError: 输入包含NaN 我更喜欢使用KNNImpute,即使对于分类数据,因为我感觉如果只使用ColumnTransform并分别用数字和分类数据填充,我可能会失去一些准确性。有没有办法让OneHotEncoder忽略这些缺失值?如果没有,那么使用ColumnTransform或更简单的imputer来解决这个问题哪种方法更好?
提前致谢

1
使用KNNImpute填充独热编码分类变量通常会产生0到1之间的值(除非n_neighbors=1); 对于您的用途来说这样可以吗?如果可以,您希望如何编码缺失值:作为新列还是全部为零? - Ben Reiniger
@BenReiniger 只要我将值四舍五入在0和1之间,那应该没问题了,对吧?至于你问题的第二部分,我认为对于缺失的分类变量,默认值为0可能是最好的选择。然而,我希望有一种方法来忽略OneHotEncoder()中的这些NAs,以便我也可以在分类变量中KNNImpute这些NAs。难道没有真正的办法做到这一点吗? - DuplicitousManowar
1个回答

3

目前还有一些问题/PR需要处理 OneHotEncoder 中的缺失值,但尚不清楚选项是什么。在此期间,可以使用以下手动方法。

  • 使用 pandas 或 SimpleImputer 将分类缺失值填充为字符串 "missing"。
  • 然后使用 OneHotEncoder
  • 使用 one-hot 编码器的 get_feature_names 来识别每个原始特征对应的列,特别是 "missing" 指示符所在的列。
  • 对于每行和每个原始分类特征,在 "missing" 列中为 1 时,将 0 替换为 np.nan;然后删除缺失指示符列。
  • 现在一切都准备就绪,可以运行 KNNImputer
  • 最后,如果需要,可以后处理填补后的分类编码列。(简单地四舍五入可能会得到一个所有元素为零的行,但我认为使用 KNNImputer 不可能在同一行中获得多个 1。您可以使用 argmax 来确保只返回一个 1。)

谢谢,这真的帮了我很多,非常感激。 - DuplicitousManowar
我们能否在SimpleImputer中使用strategy="most_frequent",而不是用"missing"字符串替换它?但这将返回一个数组,没有列名,这会导致OneHotEncoder出现问题。 - curiouscheese
@xkderhaka 这不会实现问题所要求的功能;你将无法区分缺失值和最常见的值,并且 KNNImputer 无法处理分类特征的缺失值。 - Ben Reiniger
我的理解是,如果我们使用 strategy=most_frequent,它将用最常见的数据替换 NaN,对吗?之后,在数据框中就不再有 NaN 了(因为被最常见的数据替换了)。如果没有了 NaN,我们就可以继续进行 OHE,对吗? - curiouscheese

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接