如何处理传统机器学习中的字符串特征数组?

too*_*ool 6 machine-learning feature-extraction deep-learning feature-engineering

问题

假设我们有一个如下所示的数据框:

age  job         friends                                    label
23   'engineer'  ['World of Warcraft', 'Netflix', '9gag']   1
35   'manager'   NULL                                       0
...
Run Code Online (Sandbox Code Playgroud)

如果我们有兴趣训练一个使用年龄工作朋友作为特征来预测标签的分类器,我们将如何将这些特征转换为可以输入模型的数值数组?

  • 年龄非常简单,因为它已经是数字了。
  • 作业可以被散列/索引,因为它是一个分类变量。
  • Friends 是一个分类变量列表。我将如何表示此功能?

方法:

散列列表的每个元素。使用示例数据帧,让我们假设我们的哈希函数具有以下映射:

NULL                -> 0
engineer            -> 42069
World of Warcraft   -> 9001
Netflix             -> 14
9gag                -> 9
manager             -> 250
 
Run Code Online (Sandbox Code Playgroud)

让我们进一步假设朋友的最大长度为 5。任何较短的都会在右侧填充零。如果好友大小大于 5,则选择前 5 个元素。

方法一:散列和堆栈

特征转换后的数据框如下所示:

feature                             label
[23, 42069, 9001, 14, 9, 0, 0]      1
[35, 250,   0,    0,  0, 0, 0]      0
Run Code Online (Sandbox Code Playgroud)

限制

考虑以下:

age  job           friends                                        label
23   'engineer'    ['World of Warcraft', 'Netflix', '9gag']       1
35   'manager'      NULL                                          0
26   'engineer'    ['Netflix', '9gag', 'World of Warcraft']       1
...
Run Code Online (Sandbox Code Playgroud)

比较第一条记录和第三条记录的特征:

feature                             label
[23, 42069, 9001, 14, 9, 0, 0]      1
[35, 250,   0,    0,  0, 0, 0]      0
[26, 42069, 14,    9, 9001, 0]      1
Run Code Online (Sandbox Code Playgroud)

两条记录都有相同的朋友集,但顺序不同,导致不同的特征散列,即使它们应该是相同的。

方法 2:散列、顺序和堆栈

为了解决方法 1 的限制,只需从朋友特征中排序哈希。这将导致以下特征转换(假设降序):

feature                             label
[23, 42069, 9001, 14, 9, 0, 0]      1
[35, 250,   0,    0,  0, 0, 0]      0
[26, 42069, 9001, 14, 9, 0, 0]      1
Run Code Online (Sandbox Code Playgroud)

这种方法也有局限性。考虑以下:

age  job           friends                                        label
23   'engineer'    ['World of Warcraft', 'Netflix', '9gag']       1
35   'manager'      NULL                                          0
26   'engineer'    ['Netflix', '9gag', 'World of Warcraft']       1
42   'manager'     ['Netflix', '9gag']                            1
...
Run Code Online (Sandbox Code Playgroud)

通过排序应用特征变换,我们得到:

row  feature                             label
1    [23, 42069, 9001, 14, 9, 0, 0]      1
2    [35, 250,   0,    0,  0, 0, 0]      0
3    [26, 42069, 9001, 14, 9, 0, 0]      1
4    [44, 250, 14, 9, 0, 0, 0]           1
Run Code Online (Sandbox Code Playgroud)

上述功能有什么问题?好吧,Netflix 和 9gag 在第 1 行和第 3 行中的哈希在数组中具有相同的索引,但在第 4 行中没有。这会干扰训练。

方法 3:将数组转换为列

如果我们将朋友转换为一组 5 列并像处理任何分类变量一样处理每个结果列会怎样?

好吧,让我们假设朋友的词汇量很大(> 100k)。然后创建 > 100k 列,其中每列负责相应 vocab 元素的散列,这将是疯狂的。

方法 4:One-Hot-Encoding 然后 Sum

这个怎么样?将每个散列转换为单热向量,并将所有这些向量相加。

在这种情况下,例如第一行中的特征将如下所示:

[23, 42069, 01x8, 1, 01x4, 1, 01x8986, 1, 01x(max_hash_size-8987)]
Run Code Online (Sandbox Code Playgroud)

其中 0 1x8表示一行 8 个零。

这种方法的问题在于这些向量将非常庞大且稀疏。

方法 5:使用嵌入层和 1D-Conv

通过这种方法,我们将friends 数组中的每个单词输入到嵌入层,然后进行卷积。类似于 Keras IMDB 示例:https : //keras.io/examples/imdb_cnn/

限制:需要使用深度学习框架。我想要一些适用于传统机器学习的东西。我想做逻辑回归或决策树。

你对此有何看法?