Featured image of post 数据处理基础

数据处理基础


🚲 转到 https://nlp.letout.cn 🔔 数据处理基础 ➡️


🌱 类别特征

机器学习的数据通常有 类别特征 Categorical Features ,我们需要把类别特征 Categorical Features 转化成机器学习模型能理解的数值特征,下面使用一个例子来具体讲解类别特征数据的处理。

这张表的每一行是一个人的数据,包括:年龄、性别、国籍,我们需要把这些数据变成机器学习模型可以理解的数值特征。

table

表格的第一列是年龄,年龄本身就是数值特征,所以可以不用做处理,数值特征的特点是可以比较大小,比如 35 岁的人比 31 岁的年龄大。

第二列是性别,性别是二元特征,我们可以用一个数来表示性别。用 0 表示女性,用 1 表示男性。这样一来,性别就表示为一个标量:0 / 1

第三列是国籍,比如中国,美国,印度。国籍是类别特征,机器学习并不理解国籍,所以我们要把国籍编码成数值向量。世界上约有 197 个国家,我们先用一个 [1 - 197] 的整数表示一个国家。可以建立一个字典,把国籍映射成一个 [1 - 197] 的整数。比如:China:1; US:2; India:3; Japan:4; Germany:5

我们要从 1 开始计算,而不能从 0 开始计算。

做这种映射,国籍就表示成 [1 - 197] 之间的整数。仅仅把国籍表示成 [1 - 197] 的整数还是不行,一个整数只是一种类别,它们之间不能比较大小。US:2; India:3 这个数字并不表示印度大于美国,这些整数只是类别而已,并不是真正的数值特征。

所以要进一步对国籍做 one-hot encoding ,用 one-hot 向量来表示国籍:

1
2
China  ->  1  -> [1,0,0,0,...,0]
US     ->  2  -> [0,1,0,0,...,0]

比如,中国对应 1,所以用 197 维的 one-hot 向量 [1,0,0,0...,0] 来表示,其中第一个元素为 1,其余元素都是 0;美国对应 2,这个 197 维的向量 [0,1,0,0...,0] 第二个元素是 1,其余元素都是 0。这样一来,每个国籍就由一个 one-hot 向量表示,一共有 197 个国家,所以每个向量都是 197 维的。

我们要从 1 开始计算,而不能从 0 开始计算。 因为我们要把 0 保留,用来表示未知或者缺失的国籍。数据库里面经常会有缺失的数据(比如用户没有填写国籍),这样缺失的国籍就用 0 来表示,它的 one-hot 向量就是一个全 0 的向量[0,0,0,0...,0]

下面这个例子中,我们用一个 199 维表示一个人的特征。比如这个人 28 岁,女性,国籍是中国。

1

其中,一个维度表示年龄,一个维度表示性别,一个 197 维的 one-hot 向量表示国籍。

这个例子里,这个 36 岁,男性,国籍未知的人的特征是这个 199 维的向量,我们用一个 197 维的全 0 向量表示未知国籍。

🔖 为什么要用 one-hot 向量表示特征

在处理类别特征的时候,我们使用 one-hot 向量表示国籍,每个国籍都用 197 维的向量表示。为什么要用 one-hot 向量而不用一个数字表示呢?比如用 1 表示中国,2 表示美国,3 表示印度。这样一来,名字就变成了数字,可以做数值计算,而且用一个数字表示的话,可以节省 197 倍的存储空间。当然这是不行的。否则我们就不需要 one-hot encoding 了。

假设我们使用 1 -> China; 2 -> US; 3 -> India。那么将中国 1 和美国 2 的特征加起来:1+2=3 ,相当于 “中国 + 美国 = 印度”。这样的特征完全不合理。

2

使用 one-hot 特征向量更合理。将 China 和 US 的 one-hot 向量加起来,得到 [1,1,0,0,...,0],第一个和第二个元素都是 1,其余元素都是 0,这个特征向量的解释是:既有中国国籍,又有美国国籍。

3

所以做机器学习的时候,不能用一个标量来表示一个类别特征,这种特征做法求和等数值计算是没有意义的。正确的做法是使用 one-hot 向量来表示类别特征。

🚀 处理文本数据的流程

在自然语言处理的应用中,数据就是文本 document,文本可以分割成很多单词,我们需要把单词表示成数值向量。其中每个单词都是一个类别,如果字典里有一万个单词,那么就有一万的类别,显然单词就是类别特征。我们需要使用处理类别特征的方法,把单词变成数值向量。

文本处理主要分为三个步骤:

  • 🔔 把文本分割成单词
  • 🔔 计算每个单词出现的次数
  • 🔔 进行 one-hot 编码

文本处理的第一步是把文本分割成单词。一段话,一篇文章或者一本书可以表示为一个字符串,可以把文本分割成很多单词,这个步骤称为 Tokenization

比如说这句话 ... to be or not to be ..., 可以分割成这些单词 [to, be, or, not, to, be]。Tokenization 就是把文本变成单词的列表。

文本处理的第二步是计算词频,也就是每个单词出现的次数。我们可以用一个哈希表 hash Map 来计算,计算开始之前,哈希表是空的,我们根据以下方式更新哈希表:如果单词 w 不在表里面,说明到目前为止,w 还没有出现在文本里,所以我们要把 w 加入哈希表,并让它的词频等于 1;如果 w 在哈希表里面,说明 w 之前在文本里出现过,只需要把 w 的词频加 1 即可。

4

接下来举个例子,我们将挨个处理这个列表里的单词。当处理到单词 to 的时候,首先查一下哈希表,发现哈希表里面有 to,它的词频是 398,说明 to 在文章里已经出现过 398 次了,现在这个单词又出现了一次,于是把表里的词频加 1,变成了 399;当处理到单词 or的时候,在表里找不到,这说明文章里还没有出现过 or 这个单词,第一次出现在文章里,于是我们把 or 插入表里,将词频设置为 1。

5

完成统计词频之后,需要把哈希表做一个排序,按照词频递减的顺序进行排列,表的最前面是词频最高的,表最后是词频最低的。然后就把词频换成下标 index,从 1 开始数计数,词频最高的词的 index 是 1。这个例子里,一共有 8 个单词,每个词对应一个 [1, 8] 之间的正整数。这个表称为字典 ,可以把单词映射为一个数字。

字典里单词的个数称为词汇量 vocabulary。这例子里词汇量等于 8。

6

英语里大概有 1 万个常用词,但是统计词频之后,你会发现字典会有几十万甚至上百万个单词。统计词频的目的就是保留常用词,去掉低频词。比如,我们可以保留词频最高的 1 万个单词,删掉其余单词。

为什么要删掉低频词呢?

  • 🌰 低频词通常没有意义

很多低频词都是名字实体 name entities,比如我们的名字就是个名字实体,假如我们的名字出现在一个数据集里面,他的频率肯定会很低,在大多数的应用里名字实体没有意义。

低频词很多都是拼写错误造成的,如果把 prince 的 c 误写成 s,prinse,那么就创造了一个新的单词,这种词的频率也很低,在很多应用里,去掉这种词没有危害。

  • 🌰 去掉低频词的另一个原因是我们不希望 vocabulary 太大。

下一个步骤做 one-hot encoding 的时候,向量的维度就是字典的大小。字典越大,向量的维度就越高,这会让计算变慢。下一节详细说明词嵌入 Word Embedding 的时候就会看到,字典越大,模型的参数就越会越多,就会容易造成过拟合 overfitting,删掉低频词就会大幅减小 vocabulary

文本处理的第三步就是对单词做 one-hot encoding,通过查字典,把单词映射成一个正整数,一个单词的列表就映射成了一个正整数的列表;如果有必要就继续把这些正整数变成 one-hot 向量。这些 one-hot 向量的维度正好等于 vocabulary,在这个例子里面,字典的长度是 8,所以 one-hot 维度就等于 8。

7

上面说过,字典里的低频词可能会被删掉,所以有些词在字典里找不到,例如把 be 错误拼写成单词 bi,这个词在字典里找不到,one-hot encoding 时,可以忽略这个词,也可以把它编码成全 0 向量。

🎐 总结

最后总结一下这一节的内容。

部分机器学习的数据会具备类别特征 Categorical Features,机器学习模型无法理解,我们需要将其转换成数值特征。类别特征的类别会被映射成一个从 1 开始计算的整数,0 被用来表示缺失或者未知的类别,并且使用 one-hot 向量,能很好的表示类别特征的意义。

文本处理主要有三个步骤,第一步 tokenization 把文本分割成单词的列表;第二步建立了一个字典vocabulary,把单词映射成一个正整数;第三步进行 one-hot encoding,将分割后的单词列表映射成正整数的列表或变成 one-hot 向量。