【问题标题】:Specify list of possible values for Pandas get_dummies指定 Pandas get_dummies 的可能值列表
【发布时间】:2013-08-19 07:02:13
【问题描述】:

假设我有一个如下所示的 Pandas DataFrame,并且我正在编码 categorical_1 以在 scikit-learn 中进行训练:

data = {'numeric_1':[12.1, 3.2, 5.5, 6.8, 9.9], 
        'categorical_1':['A', 'B', 'C', 'B', 'B']}
frame = pd.DataFrame(data)
dummy_values = pd.get_dummies(data['categorical_1'])

“categorical_1”的值是 A、B 或 C,所以我最终在 dummy_values 中有 3 列。但是,categorical_1 实际上可以采用值 A、B、C、D 或 E,因此没有代表值 D 或 E 的列。

在 R 中,我会在分解该列时指定级别 - 是否有相应的方法可以使用 Pandas 执行此操作,或者我是否需要手动处理?

在我看来,这是必要的,因为该列的值超出了训练集中使用的值,但作为机器学习的新手,也许这没有必要,所以我愿意接受不同的方法来解决这个问题。

【问题讨论】:

    标签: python machine-learning pandas


    【解决方案1】:

    处理我使用的训练集和测试集中的分类值集之间的不匹配;

        length = train_categorical_data.shape[0]
        empty_col = np.zeros((length,1))
        test_categorical_data_processed = pd.DataFrame()
        for col in train_categorical_data.columns:
            test_categorical_data_processed[col] = test_categorical_data.get(col, empty_col)
    

    【讨论】:

      【解决方案2】:

      首先,如果您希望 pandas 获取更多值,只需将它们添加到发送到 get_dummies 方法的列表中

      data = {'numeric_1':[12.1, 3.2, 5.5, 6.8, 9.9], 
              'categorical_1':['A', 'B', 'C', 'B', 'B']}
      frame = pd.DataFrame(data)
      dummy_values = pd.get_dummies(data['categorical_1'] + ['D','E'])
      

      在 python 中,+ 在列表中作为concatenate 操作,所以

      ['A','B','C','B','B'] + ['D','E']
      

      结果

      ['A', 'B', 'C', 'B', 'B', 'D', 'E']
      

      在我看来,这是必要的,因为该列的值超出了训练集中使用的值,但作为机器学习的新手,也许这没有必要,所以我愿意接受不同的方法来解决这个问题。

      从机器学习的角度来看,这是相当多余的。此列是分类列,因此值“D”对模型完全没有意义,以前从未见过。如果您正在编写一元特征(我假设在看到您为每个值创建列之后),只需用

      表示这些“D”、“E”值就足够了
      A   B   C
      0   0   0
      

      (我假设您用0 1 0 表示“B”值,用0 0 1 表示“C”等)

      因为如果训练集中没有这样的值,在测试期间 - 没有模型会区分给出值“D”或“大象”

      这样做的唯一原因是假设将来您希望添加具有“D”值的数据,并且根本不想修改代码,那么现在就这样做是合理的,即使它可能会使训练变得更加复杂(因为您添加了一个就目前而言 - 完全没有知识的维度),但这似乎是一个小问题。

      如果您不打算以一元格式对其进行编码,而是希望将这些值用作一个特征,只需使用分类值,那么您根本不需要创建这些“假人”,而是使用模型它可以使用这样的值,例如朴素贝叶斯,可以简单地使用“拉普拉斯平滑”进行训练,以便能够解决不存在的值。

      【讨论】:

        【解决方案3】:

        这不是更好的答案吗?

        data = pd.DataFrame({
            "values": [1, 2, 3, 4, 5, 6, 7],
            "categories": ["A", "A", "B", "B", "C", "C", "D"]
        })
        
        possibilites = ["A", "B", "C", "D", "E", "F"]
        
        exists = data["categories"].tolist()
        
        difference = pd.Series([item for item in possibilites if item not in exists])
        
        target = data["categories"].append(pd.Series(difference))
        
        target = target.reset_index(drop=True)
        
        dummies = pd.get_dummies(
            target
        )
        
        dummies = dummies.drop(dummies.index[list(range(len(dummies)-len(difference), len(dummies)))])
        

        【讨论】:

          【解决方案4】:

          我遇到了和你一样的问题,就是在 Pandas 中使用get_dummies() 时如何统一训练数据和测试数据之间的虚拟类别。然后我在探索 Kaggle 的房价竞赛时找到了一个解决方案,那就是同时处理训练数据和测试数据。假设您有两个数据框 df_traindf_test(其中不包含目标数据)。

          all_data = pd.concat([df_train,df_test], axis=0)
          all_data = pd.get_dummies(all_data) 
          X_train  = all_data[:df_train.shape[0]]  # select the processed training data  
          X_test   = all_data[-df_test.shape[0]:]  # select the processed testing data
          

          希望对你有帮助。

          【讨论】:

            猜你喜欢
            • 2016-09-19
            • 1970-01-01
            • 1970-01-01
            • 2021-08-11
            • 2019-08-11
            • 1970-01-01
            • 2015-09-24
            • 1970-01-01
            • 2015-09-27
            相关资源
            最近更新 更多