Python OneHotEncoder 使用许多虚拟变量还是更好的做法?

数据挖掘 Python 神经网络 机器学习模型
2021-10-15 03:42:44

我正在构建一个神经网络,并且正在对许多独立(分类)变量使用 OneHotEncoder。我想知道我是否使用虚拟变量正确处理这个问题,或者由于我的所有变量都需要虚拟变量,因此可能有更好的方法。

df  
    UserName    Token                       ThreadID    ChildEXE       
0   TAG     TokenElevationTypeDefault (1)   20788       splunk-MonitorNoHandle.exe  
1   TAG     TokenElevationTypeDefault (1)   19088       splunk-optimize.exe 
2   TAG     TokenElevationTypeDefault (1)   2840        net.exe 
807 User    TokenElevationTypeFull (2)      18740       E2CheckFileSync.exe 
808 User    TokenElevationTypeFull (2)      18740       E2check.exe 
809 User    TokenElevationTypeFull (2)      18740       E2check.exe 
811 Local   TokenElevationTypeFull (2)      18740       sc.exe  

ParentEXE           ChildFilePath               ParentFilePath   
splunkd.exe         C:\Program Files\Splunk\bin C:\Program Files\Splunk\bin 0
splunkd.exe         C:\Program Files\Splunk\bin C:\Program Files\Splunk\bin 0
dagent.exe          C:\Windows\System32         C:\Program Files\Dagent 0
wscript.exe         \Device\Mup\sysvol          C:\Windows  1
E2CheckFileSync.exe C:\Util                     \Device\Mup\sysvol\ 1
cmd.exe             C:\Windows\SysWOW64         C:\Util\E2Check 1
cmd.exe             C:\Windows                  C:\Windows\SysWOW64 1

DependentVariable
0
0
0
1
1
1
1

我导入数据并在自变量上使用 LabelEncoder

from sklearn.preprocessing import LabelEncoder, OneHotEncoder

#IMPORT DATA
#Matrix x of features
X = df.iloc[:, 0:7].values
#Dependent variable
y = df.iloc[:, 7].values

#Encoding Independent Variable
#Need a label encoder for every categorical variable
#Converts categorical into number - set correct index of column
#Encode "UserName"
labelencoder_X_1 = LabelEncoder()
X[:, 0] = labelencoder_X_1.fit_transform(X[:, 0])
#Encode "Token"
labelencoder_X_2 = LabelEncoder()
X[:, 1] = labelencoder_X_2.fit_transform(X[:, 1])
#Encode "ChildEXE"
labelencoder_X_3 = LabelEncoder()
X[:, 3] = labelencoder_X_3.fit_transform(X[:, 3])
#Encode "ParentEXE"
labelencoder_X_4 = LabelEncoder()
X[:, 4] = labelencoder_X_4.fit_transform(X[:, 4])
#Encode "ChildFilePath"
labelencoder_X_5 = LabelEncoder()
X[:, 5] = labelencoder_X_5.fit_transform(X[:, 5])
#Encode "ParentFilePath"
labelencoder_X_6 = LabelEncoder()
X[:, 6] = labelencoder_X_6.fit_transform(X[:, 6])

这给了我以下数组:

X
array([[2, 0, 20788, ..., 46, 31, 24],
       [2, 0, 19088, ..., 46, 31, 24],
       [2, 0, 2840, ..., 27, 42, 15],
       ...,
       [2, 0, 20148, ..., 17, 40, 32],
       [2, 0, 20148, ..., 47, 23, 0],
       [2, 0, 3176, ..., 48, 42, 32]], dtype=object)

现在对于所有自变量,我必须创建虚拟变量:

我应该使用:

onehotencoder = OneHotEncoder(categorical_features = [0, 1, 2, 3, 4, 5, 6])
X = onehotencoder.fit_transform(X).toarray() 

这给了我:

X
array([[0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       ...,
       [0., 0., 1., ..., 1., 0., 0.],
       [0., 0., 1., ..., 0., 0., 0.],
       [0., 0., 1., ..., 1., 0., 0.]])

还是有更好的方法来解决这个问题?

2个回答

是的。您可以使用get_dummies(). get_dummies() 方法执行 LabelEncoder 和 OneHotEncoder 所做的事情,此外,如果您打算构建线性回归,您可以删除每个类别的第一个虚拟列以防止虚拟变量陷阱。

示例: 1. 创建数据框:

df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['b', 'a', 'c'],
                 'C': [1, 2, 3]})
df.head()
A   B   C
0   a   b   1
1   b   a   2
2   a   c   3

2. 应用 get_dummies():

df2 = pd.get_dummies(df, prefix=['A', 'B'], drop_first=True)
df2.head()

输出:

    C   A_b B_b B_c
0   1   0   1   0
1   2   1   0   0
2   3   0   0   1

如果您的分类变量包括建议一些数值的变量,如排名,您应该考虑只对它们进行标签编码。(例如,First、Second、Third 等可以编码为 1、2、3 等)。

另外,找出所有这些类别是否重要。绘制一些图形(如直方图、分布图)以可视化数据集。删除似乎不需要的类别。(例如,在上面的示例中,如果 First 出现超过 80%,您应该考虑某些特征是否真的对您的模型有贡献。)