【问题标题】:How to encode multiple features at once with SciKit Learn transform如何使用 SciKit Learn 转换一次编码多个特征
【发布时间】:2019-04-28 06:49:45
【问题描述】:

我正在尝试对一些分类特征进行编码,以便能够将它们用作机器学习模型中的特征,目前我有以下代码:

data_path = '/Users/novikov/Assignment2/epl-training.csv'
data = pd.read_csv(data_path)
data['Date'] = pd.to_datetime(data['Date'])

le = preprocessing.LabelEncoder()


data['HomeTeam'] = le.fit_transform(data.HomeTeam.values)
data['AwayTeam'] = le.fit_transform(data.AwayTeam.values)
data['FTR'] = le.fit_transform(data.FTR.values)
data['HTR'] = le.fit_transform(data.HTR.values)
data['Referee'] = le.fit_transform(data.Referee.values)

这很好用,但这并不理想,因为如果要编码 100 个特征,手动完成会花费很长时间。我如何自动化这个过程?我试过实现一个循环:

label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']

for feature in label_encode:
    method = 'data.' + feature + '.values'
    data[feature] = le.fit_transform(method)

但我得到ValueError: bad input shape ():

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-1b8fb6164d2d> in <module>()
     11     method = 'data.' + feature + '.values'
     12     print(method)
---> 13     data[feature] = le.fit_transform(method)

/anaconda3/lib/python3.6/site-packages/sklearn/preprocessing/label.py in fit_transform(self, y)
    109         y : array-like of shape [n_samples]
    110         """
--> 111         y = column_or_1d(y, warn=True)
    112         self.classes_, y = np.unique(y, return_inverse=True)
    113         return y

/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in column_or_1d(y, warn)
    612         return np.ravel(y)
    613 
--> 614     raise ValueError("bad input shape {0}".format(shape))
    615 
    616 

ValueError: bad input shape ()

这段代码的所有变体(比如只输入data.feature.values)似乎都不起作用。除了手写之外,肯定还有其他方法。

【问题讨论】:

    标签: python pandas machine-learning encoding scikit-learn


    【解决方案1】:

    当然,method = 'data.' + feature + '.values' 不起作用 - 它本身就是一个字符串!试试吧

    method = data[feature].values
    

    for feature in label_encode:
        data[feature] = le.fit_transform(data[feature].values)
    

    【讨论】:

      【解决方案2】:

      这有点尴尬,但是您可以访问系列中的值,然后对其调用 fit 变换,同时在 for 循环“X[c]=”中选择系列以指示您要将值分配回 DF。

      X = pd.DataFrame({
          'A':[1, 3, 27],
          'B':[9, 8, 100],
          'C':['dog', 'cat', 'dog']})
      print(X.head())
      
      le = LabelEncoder()
      
      for c in X.columns:
      
          X[c] = le.fit_transform(X[c].values)
      
      X.head()
      

      【讨论】:

        【解决方案3】:

        我只是在修复你的代码添加pd.eval

        label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']
        
        for feature in label_encode:
            method = 'data.' + feature + '.values'
            data[feature] = le.fit_transform(pd.eval(method))
        

        【讨论】:

          【解决方案4】:

          编码器对象的工作方式是,当您fit 时,它会将一些元数据存储在对象的属性中。当您要转换数据时会使用这些属性。 fit_transformfittransform 的一种便捷方法。

          当您决定使用同一个对象执行另一个fit_transform 时,您将覆盖存储的元数据。如果您不想使用对象inverse_transform,那很好。

          设置

          df = pd.DataFrame({
              'HomeTeam':[1, 3, 27],
              'AwayTeam':[9, 8, 100],
              'FTR':['dog', 'cat', 'dog'],
              'HTR': [*'XYY'],
              'Referee': [*'JJB']
          })
          

          回答您的问题

          updateapply

          le = preprocessing.LabelEncoder()
          label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']
          
          df.update(df[label_encode].apply(le.fit_transform))
          df
          
             AwayTeam FTR HTR  HomeTeam Referee
          0         1   1   0         0       1
          1         0   0   1         1       1
          2         2   1   1         2       0
          

          我会怎么做

          每个单独的编码器都被捕获在le 字典中以供以后使用

          from collections import defaultdict
          le = defaultdict(preprocessing.LabelEncoder)
          label_encode = ['HomeTeam', 'AwayTeam', 'FTR', 'HTR', 'Referee']
          
          df = df.assign(**{k: le[k].fit_transform(df[k]) for k in label_encode})
          df
          
             AwayTeam FTR HTR  HomeTeam Referee
          0         1   1   0         0       1
          1         0   0   1         1       1
          2         2   1   1         2       0
          

          pandas.factorize

          如果你只想要代码,你可以使用 Pandas 的factorize。请注意,这不会对最终值进行排序并按照它们首次出现的顺序对其进行标记。

          df.update(df[label_encode].apply(lambda x: x.factorize()[0]))
          df
          
             AwayTeam FTR HTR  HomeTeam Referee
          0         0   0   0         0       0
          1         1   1   1         1       0
          2         2   0   1         2       1
          

          Numpy 的 unique

          这会对最终值进行排序,看起来像LabelEncoder

          df.update(df[label_encode].apply(lambda x: np.unique(x, return_inverse=True)[1]))
          
             AwayTeam FTR HTR  HomeTeam Referee
          0         1   1   0         0       1
          1         0   0   1         1       1
          2         2   1   1         2       0
          

          【讨论】:

            猜你喜欢
            • 2016-02-25
            • 1970-01-01
            • 2018-11-23
            • 2018-02-24
            • 2016-12-18
            • 2020-01-29
            • 2019-07-13
            • 2014-02-17
            • 2014-11-05
            相关资源
            最近更新 更多