指定Pandas get_dummies的可能值列表

时间:2013-08-16 19:22:20

标签: python machine-learning pandas

假设我有一个像下面这样的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执行此操作,还是需要手动处理?

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

3 个答案:

答案 0 :(得分:4)

首先,如果您希望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'或'Elephant'

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

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

答案 1 :(得分:1)

这不是一个更好的答案吗?

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)))])

答案 2 :(得分:0)

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

    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)