为虚拟变量创建一个模型

时间:2017-01-05 18:37:48

标签: python r dummy-variable

从变量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

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

我希望能够将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个变量。此外,新的数据集几乎总是会出现“坏”的情况。数据(例如,上例中的7#)。

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

2 个答案:

答案 0 :(得分:1)

试一试:

# 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

答案 1 :(得分:1)

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

首先,请阅读var1

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

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

创建一个包含虚拟变量列名称和相关其他列的新列表或数组(这可能只是数据集中除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重新索引,您应该已经完成​​所有设置。