Python 一个热编码序列和测试数据时形状不匹配。在管道中使用get_假人时,Train_数据比Test_数据具有更多的伪列

Python 一个热编码序列和测试数据时形状不匹配。在管道中使用get_假人时,Train_数据比Test_数据具有更多的伪列,python,scikit-learn,pipeline,one-hot-encoding,Python,Scikit Learn,Pipeline,One Hot Encoding,我正在尝试为我的数据创建一个get_dummies类,我希望稍后在管道中使用它: 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)

我正在尝试为我的数据创建一个get_dummies类,我希望稍后在管道中使用它:

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_列上调用fit_变换,然后调用变换X_测试

z=Dummies()
X_train=z.fit_transform(X_train)
X_test=z.transform(X_test)
X_列和X_测试形状的立柱不同:

X_train.shape
X_test.shape
输出:

(109831797) (36611529)

X_火车上的假人比我的X_测试中的要多。
显然,我的X_测试的类别比X_train少。我如何在课堂上编写逻辑,使X_测试中的类别以X_列的形式传播?我希望X_测试与我的X_序列具有相同数量的虚拟变量。

您可以附加两个数据帧,然后获得虚拟变量()。

如果我们从两个小示例数据帧开始:

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,然后使用该值将特定列添加到测试集中,并用零填充(因为测试集中没有一行包含这些缺少的类别):

这为我们提供了以下测试数据帧:

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_变换
语法,并确保X_test_编码的形状与X_train_编码的形状相同。它也可以像您提到的那样用于管道中,而不是
Dummies()
。例如:

pipe1=make_pipeline(OneHotEncoder(categories = "auto"), StandardScaler(), PCA(n_components=7), LogisticRegression())

是的,我可以这样做,但我想在以后为ex构建模型时使用管道:
pipe1=make_管道(Dummies()、StandardScaler()、PCA(n_components=7)、LogisticRegression())
然后我安装我的火车
pipe1.fit(X_火车,y_火车)
然后我得到我的分数
pipe1.分数(X\u测试,y\u测试)
。在这里,我不必明确地OHE和缩放我的X_训练或X_测试。这个烟斗可以帮我。它将首先适合于X_列车,然后它将转换X_测试,然后给我的LogReg模型的分数。
pipe1=make_pipeline(OneHotEncoder(categories = "auto"), StandardScaler(), PCA(n_components=7), LogisticRegression())