def preprocessing(X_train):
cat_cols = []
num_cols = []
for cols in X_train.columns:
if X_train[cols].nunique()<10 and X_train[cols].dtype =="object":
cat_cols.append(cols)
elif X_train[cols].dtype in ["int64","float64"]:
num_cols.append(cols)
full_cols = cat_cols+num_cols
num_transformer = SimpleImputer(strategy = "constant")
cat_transformer = Pipeline(steps =[
("imputer", SimpleImputer(strategy = "most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore"))
])
preprocessor = ColumnTransformer(
transformers = [
("num", num_transformer, num_cols),
("cat", cat_transformer, cat_cols)
])
return preprocessor.fit_transform(X_train)
这段代码创建了一个用于数据转换的预处理函数。在训练模型时,我得到了226个特征。但当我尝试转换测试数据集进行预测时,我只得到了217个特征。
错误信息:特征形状不匹配,预期:226,实际得到:217
我使用的数据集:https://www.kaggle.com/competitions/home-data-for-ml-course
我想知道这是为什么以及如何解决这个问题
回答:
你应该在训练数据上拟合预处理器,但在测试数据上只进行转换。如果你在测试数据上重新拟合,它会找到一个完全不同的映射,特征形状不匹配是一个幸运的错误,因为否则你的代码会运行,但模型会得到完全混乱的表示。这在使用像独热编码这样的技术时尤为重要。想象一下,你的训练数据中,第一个特征的值是[“cat”, “dog”, “duck”],因此cat=>(1,0,0),dog=>(0,1,0),duck=>(0,0,1)。但在测试数据中,你只看到了[“cat”, “duck”],因此cat=>(1, 0),duck=>(0,1),这样你就有了形状不匹配的问题,而且duck变成了某种dog!