为虚拟变量创建模型

Create a Model for Dummy Variables

从变量 var1 的训练数据集开始:

var1
A
B
C
D

我想创建一个模型(我们称之为 dummy_model1),然后将训练数据集转换为:

var1_A  var1_B  var1_C  var1_D
1       0       0       0
0       1       0       0
0       0       1       0
0       0       0       1

此功能(或类似功能)存在于 R 中的 dummies 包和 Pandas 中的 get_dummies 包中,甚至存在于 caseSQL 中的语句。

然后我希望能够将 dummy_model1 应用于新数据集:

var1
C
7
#
A

并得到以下输出:

var1_A  var1_B  var1_C  var1_D
0       0       1       0
0       0       0       0
0       0       0       0
1       0       0       0

我知道我可以在 SQL 中使用 'case' 语句执行此操作,但如果我有大约 2,000 个变量,我很乐意自动执行该过程。此外,新数据集几乎总是有 "bad" 数据(例如,上例中的 7#)。

有点语言不可知论(只要它是开源的)但更喜欢 PythonR。请注意数据超过 500GB,因此限制了我的一些选择。提前致谢。

试一试:

# first set the variable to factor with levels specified
df$var1 <- factor(df$var1, levels = LETTERS[1:4])

model.matrix(data = df, ~var1-1)
#  var1A var1B var1C var1D
#1     0     0     1     0
#4     1     0     0     0

# or even 
sapply(LETTERS[1:4], function(x) as.numeric(x==df$var1))
#     A B C D
#[1,] 0 0 1 0
#[2,] 0 0 0 0
#[3,] 0 0 0 0
#[4,] 1 0 0 0

假设 var1 适合自己的内存,这是一个可能的解决方案:

首先,读入var1

接下来,使用 get_dummies 将所有 "training" 类别编码为虚拟变量。将列名称存储为列表或数组。

然后,读取训练数据集的前几行以获取列名并将它们存储为列表(或者如果您已经知道这些,则可以跳过此步骤)。

创建一个包含虚拟变量列名称和相关其他列的新列表或数组(这可能只是数据集中除 var1 之外的每一列)。这将是最后的列编码。

然后,读入你的测试数据。使用 get_dummies 对测试数据中的 var1 进行编码,知道它可能缺少类别或具有无关类别。然后重新索引数据以匹配最终列编码。

重建索引后,您将得到一个测试数据集,其中包含 var1 个与您的训练一致的假人 var1

举例说明:

import pandas as pd
import numpy as np

training = pd.DataFrame({
        'var1': ['a','b','c'],
        'other_var':[4,7,3],
        'yet_another':[8,0,2]
    })

print training
   other_var var1  yet_another
0          4    a            8
1          7    b            0
2          3    c            2

test = pd.DataFrame({
        'var1': ['a','b','q'],
        'other_var':[9,4,2],
        'yet_another':[9,1,5]
    })

print test
   other_var var1  yet_another
0          9    a            9
1          4    b            1
2          2    q            5


var1_dummied = pd.get_dummies(training.var1, prefix='var1')
var_dummy_columns =  var1_dummied.columns.values

print var_dummy_columns
array(['var1_a', 'var1_b', 'var1_c'], dtype=object)

final_encoding_columns = np.append(training.drop(['var1'], axis = 1).columns, var_dummy_columns)

print final_encoding_columns
array(['other_var', 'yet_another', 'var1_a', 'var1_b', 'var1_c'], dtype=object)


test_encoded = pd.get_dummies(test, columns=['var1'])

print test_encoded
   other_var  yet_another  var1_a  var1_b  var1_q
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       1

test_encoded_reindexed = test_encoded.reindex(columns = final_encoding_columns, fill_value=0)

print test_encoded_reindexed
   other_var  yet_another  var1_a  var1_b  var1_c
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       0

根据您的问题和评论中的预期输出,这应该是您想要的。

如果测试数据很容易放入内存,您可以轻松地将其扩展到多个变量。只需保存,然后迭代更新 final_encoding_columns 为每个要编码的训练变量。然后在重新索引测试数据时将所有这些列传递给 columns= 参数。使用完整的 final_encoding_columns 重新索引,您应该已经准备就绪。