One-Hot-Encoding 训练和测试数据时形状不匹配。在将 get_dummies 与管道一起使用时,Train_Data 的虚拟列多于 Test_data
Shape mismatch when One-Hot-Encoding Train and Test data. Train_Data has more Dummy Columns than Test_data while using get_dummies with pipeline
我正在尝试为我的数据创建一个 get_dummies Class,稍后我想在管道中使用它:
class Dummies(BaseEstimator, TransformerMixin):
def transform(self, df):
dummies=pd.get_dummies(df[self.cat],drop_first=True) ## getting dummy cols
df=pd.concat([df,dummies],axis=1) ## concatenating our dummies
df.drop(self.cat,axis=1,inplace=True) ## dropping our original cat_cols
def fit(self, df):
self.cat=[]
for i in df.columns.tolist():
if i[0]=='c': ## My data has categorical cols start with 'c'
self.cat.append(i) ## Storing all my categorical_columns for dummies
else:
continue
现在当我在 X_train 上调用 fit_transform 然后转换 X_test
z=Dummies()
X_train=z.fit_transform(X_train)
X_test=z.transform(X_test)
X_train和X_test的列形状不同:
X_train.shape
X_test.shape
输出:
(10983, 1797)
(3661, 1529)
X_train 中的假人比我的 X_test 中的假人多。
显然,我的 X_test 的类别少于 X_train。我如何在我的 Class 中编写逻辑,以便 X_test 中的类别广播到 X_train 的形状?我希望 X_test 具有与我的 X_train.
相同数量的虚拟变量
您可以附加两个数据帧,然后执行 get_dummies()。
如果我们从两个小示例数据帧开始:
train = pd.DataFrame({'job=carpenter': [0, 1, 0],
'job=plumber': [0, 0, 1],
'job=electrician': [1, 0, 0]})
job=carpenter job=plumber job=electrician
0 0 0 1
1 1 0 0
2 0 1 0
test = pd.DataFrame({'job=carpenter': [0, 1, 0],
'job=plumber': [1, 1, 0]})
job=carpenter job=plumber
0 0 1
1 1 1
2 0 0
我们可以使用字典推导来获取训练集中测试集中缺失的每一列,并将其赋值为 0,然后将使用该值将特定列添加到测试集中,并且用零填充它(因为测试集中没有任何行包含任何这些缺失的类别):
train_cols = list(train.columns)
test_cols = list(test.columns)
cols_not_in_test = {c:0 for c in train_cols if c not in test_cols}
test = test.assign(**cols_not_in_test)
这为我们提供了以下测试数据帧:
test
job=carpenter job=plumber job=electrician
0 0 1 0
1 1 1 0
2 0 0 0
你想在这里使用的(我认为)是 scikit learn 的 OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncode(categories = "auto")
X_train_encoded = encoder.fit_transform("X_train")
X_test_encoded = encoder.transform("X_test")
这将保留 fit_transform
语法并确保 X_test_encoded 具有与 X_train_encoded 相同的形状。它也可以用于您提到的管道中,而不是 Dummies()
。示例:
pipe1=make_pipeline(OneHotEncoder(categories = "auto"), StandardScaler(), PCA(n_components=7), LogisticRegression())
我正在尝试为我的数据创建一个 get_dummies Class,稍后我想在管道中使用它:
class Dummies(BaseEstimator, TransformerMixin):
def transform(self, df):
dummies=pd.get_dummies(df[self.cat],drop_first=True) ## getting dummy cols
df=pd.concat([df,dummies],axis=1) ## concatenating our dummies
df.drop(self.cat,axis=1,inplace=True) ## dropping our original cat_cols
def fit(self, df):
self.cat=[]
for i in df.columns.tolist():
if i[0]=='c': ## My data has categorical cols start with 'c'
self.cat.append(i) ## Storing all my categorical_columns for dummies
else:
continue
现在当我在 X_train 上调用 fit_transform 然后转换 X_test
z=Dummies()
X_train=z.fit_transform(X_train)
X_test=z.transform(X_test)
X_train和X_test的列形状不同:
X_train.shape
X_test.shape
输出:
(10983, 1797) (3661, 1529)
X_train 中的假人比我的 X_test 中的假人多。 显然,我的 X_test 的类别少于 X_train。我如何在我的 Class 中编写逻辑,以便 X_test 中的类别广播到 X_train 的形状?我希望 X_test 具有与我的 X_train.
相同数量的虚拟变量您可以附加两个数据帧,然后执行 get_dummies()。
如果我们从两个小示例数据帧开始:
train = pd.DataFrame({'job=carpenter': [0, 1, 0],
'job=plumber': [0, 0, 1],
'job=electrician': [1, 0, 0]})
job=carpenter job=plumber job=electrician
0 0 0 1
1 1 0 0
2 0 1 0
test = pd.DataFrame({'job=carpenter': [0, 1, 0],
'job=plumber': [1, 1, 0]})
job=carpenter job=plumber
0 0 1
1 1 1
2 0 0
我们可以使用字典推导来获取训练集中测试集中缺失的每一列,并将其赋值为 0,然后将使用该值将特定列添加到测试集中,并且用零填充它(因为测试集中没有任何行包含任何这些缺失的类别):
train_cols = list(train.columns)
test_cols = list(test.columns)
cols_not_in_test = {c:0 for c in train_cols if c not in test_cols}
test = test.assign(**cols_not_in_test)
这为我们提供了以下测试数据帧:
test
job=carpenter job=plumber job=electrician
0 0 1 0
1 1 1 0
2 0 0 0
你想在这里使用的(我认为)是 scikit learn 的 OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncode(categories = "auto")
X_train_encoded = encoder.fit_transform("X_train")
X_test_encoded = encoder.transform("X_test")
这将保留 fit_transform
语法并确保 X_test_encoded 具有与 X_train_encoded 相同的形状。它也可以用于您提到的管道中,而不是 Dummies()
。示例:
pipe1=make_pipeline(OneHotEncoder(categories = "auto"), StandardScaler(), PCA(n_components=7), LogisticRegression())