千户余音
作者千户余音·2017-10-17 18:09
系统架构师·njiairport

如何使用scikit-learn实现用于机器学习的文本数据准备

字数 4048阅读 2073评论 1赞 3

这篇文章中,我们将介绍如何使用 scikit-learn 来实现用于机器学习的文本数据准备。文章主要介绍了三个 scikit-learn 自带的文本数据量化工具——CountVectorizer、TfidfVectorizer 和 HashingVectorizer。

在使用文本数据来搭建预测模型前,都需要特殊的准备工作。

文本首先要通过解析来提出单词,这一过程称为词条化。然后单词需要编码为整数或浮点值,作为机器学习算法的输入,称为特征提取(或量化)。

scikit-learn 提供了使用简单的工具来对你的文本数据进行词条化和特征提取。

在这篇文章中,你会学到在 Python 中如何使用 scikit-learn 实现用于机器学习的文本数据准备。

在读完这篇文章后,你会了解到:

  1. 如何使用 CountVectorizer 将文本的转化成单词频数向量
  2. 如何使用 TfidfVectorizer 提取文本的单词权重向量
  3. 如何使用 HashingVectorizer 将文本映射到特征索引

让我们开始吧。

“词袋(Bag-of-words)”模型

在使用机器学习算法时,我们不能直接用文本进行运算。相反,我们需要将文本转换成数字。

我们想对文档进行分类时,每个文档作为“输入”,文档的类别标签是我们预测算法的“输出”。算法只能接受数字向量作为输入,所以需要将文档转换成固定长度的数字向量。

机器学习领域有一个简单且有效的模型,适用于文本文档,叫做“词袋”(Bag-of-Words)模型,简称为 BOW。

该模型的简单之处在于,它舍弃了单词中的所有顺序信息,并主要关注文档中单词的出现频率。

这一点可以通过分配给每个单词一个独一无二的数字来实现。这样一来,我们看到的任何文档都可以编码成一个固定长度的向量,长度为已知单词所构成的词汇表的长度。该向量中每个位置的值是编码文档中的每个单词的计数或频率。

这就是“词袋”模型,我们只关心编码方法,能表示哪些词语在文档中出现了,或者他们在编码文档中出现的频率的,而不考虑任何关于顺序的信息。

这个简单的方法有很多种扩展,既可以更好地解释“单词”的含义,也可以定义向量中每个单词的编码方式。

scikit-learn 提供了 3 种可供我们使用的不同方法,我们将简要地看一下每种方法。

CountVectorizer——量化单词数量

CountVectorizer 提供了一种简单的方法,不仅可以将文本文档的数据集转化成词条并建立一个已知单词的词汇表,而且还可以用该词汇表对新文本进行编码。

使用方法如下:

  1. 创建 CountVectorizer 类的一个实例 ;
  2. 调用 fit() 函数,从一或多个文件中学习出一个词汇表 ;
  3. 对一或多个文档应用 transform() 函数,将每个文档编码成一个向量。

编码得到的向量能够返回整个词汇表的长度,以及每个单词在该文档中出现次数的整数计数。

由于这些向量含有许多零值,所以我们称之为稀疏的。Python 在 scipy.sparse 库中提供了一种处理这类稀疏向量的有效方法。

调用 transform() 所返回的向量是稀疏向量,你可以将它们转换为 numpy 数组,看起来更直观也更好理解,这一步可以通过调用 toarray() 函数完成。

下面是一个使用 CountVectorizer 来词条化、构造词汇表,以及编码文档的示例。

微信图片_20171017180330.jpg

微信图片_20171017180330.jpg

上例中,可以看到,我们通过词汇表来查看到底是什么被词条化了:

微信图片_20171017180427.jpg

微信图片_20171017180427.jpg

可以看到,所有单词默认情况下是小写,并且忽略掉标点符号。词条化的这些参数以及其他方面是可配置的,我建议你在 API 文档 中查看所有选项。

API 文档链接:

http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html

运行这个样例,可以首先显示出词汇表,然后显示出编码文档的形状。我们可以看到,词汇表中有 8 个单词,于是编码向量的长度为 8。

可以看出,编码向量是一个稀疏矩阵。最后,我们可以看到以数组形式出现的编码向量,显示出每个单词的出现次数为 1,除了索引号为 7 的单词出现次数为 2。

微信图片_20171017180458.jpg

微信图片_20171017180458.jpg

重要的是,该量化方法可以用于含有词汇表中没有出现的单词的文档。这些单词会被忽略掉,然后在得到的向量结果中不会给出出现次数。

下面是一个使用上述的词条化工具对文档进行编码的示例,该文档中含有一个词汇表中的词,以及一个不在词汇表中的词。

微信图片_20171017180514.jpg

微信图片_20171017180514.jpg

运行示例,显示出编码稀疏向量的矩阵形式,可以看出词汇表中的单词出现了 1 次,而没在词汇表中的单词完全被忽略了。

微信图片_20171017180529.jpg

微信图片_20171017180529.jpg

编码的向量可以直接用于机器学习算法。

TfidfVectorizer——计算单词权重

单词出现次数是一个很好的开始,但也是很基础的特征。

简单的出现次数统计的一个问题在于,有些单词,例如“the”会出现很多次,他们巨大的统计数量对于编码向量没有太大意义。

一个替代方法是统计单词权重,目前最流行的方法是 TF-IDF。这是一个缩写词,代表“词频 - 逆文档频率”(Term Frequency–Inverse Document),代表一个词对于一个文档的重要程度。

词频(Term Frequency):指的是某一个给定的词语在一篇文档中出现的次数。逆文档频率(Inverse Document Frequency):单词在文档中出现的频率越高,IDF 值则下降。

撇开数学不说,TF-IDF 给出的是单词权重的程度,会把更有意思的单词标注出来,例如仅在某篇文档中频率很高,而不是所有文档中都频繁出现的词。

TfidfVectorizer 可以词条化文档,学习词汇表以及逆文档频率权重,并且可以编码新文档。或者,如果你已经用 CountVectorizer 学习得到了向量,你可以对它使用 Tfidftransformer 函数,计算逆文档频率并且开始编码文件。

同样的,创建(create)、拟合(fit)以及变换(transform)函数的调用都与 CountVectorizer 相同。

下面是一个使用 TfidfVectorizer 来学习词汇表和 3 篇小文档的逆文档频率的示例,并对其中一篇文档进行编码。

微信图片_20171017180605.jpg

微信图片_20171017180605.jpg

上例中,我们从文档中学到了含有 8 个单词的词汇表,在输出向量中,每个单词都分配了一个独特的整数索引。

我们计算了词汇表中每个单词的逆文档频率,给观测到的最常出现的单词“the”,索引号为 7,分配了最低的分数 1.0。

最终,第一个文档被编码成一个 8 个元素的稀疏矩阵,我们可以查看每个单词的最终权重分数,可以看到“the”、“fox”,以及“dog”的值与词汇表中其他单词的值不同。

微信图片_20171017180632.jpg

微信图片_20171017180632.jpg

这些分数被归一化为 0 到 1 之间的值,编码的文档向量可以直接用于大多数机器学习算法。

HashingVectorizer——哈希量化文本

单词频率和权重是很有用的,但是当词汇表变得十分大时,以上两种方法就会出现局限性。

反过来,这将需要巨大的向量来编码文档,并对内存要求很高,而且会减慢算法的速度。

一种很好的方法是使用单向哈希方法来将单词转化成整数。好处是该方法不需要词汇表,可以选择任意长的固定长度向量。缺点是哈希量化是单向的,因此无法将编码转换回单词(对与许多有监督的学习任务来说或许并不重要)。

HashingVectorizer 类实现了这一方法,所以可以使用它对单词进行连续哈希量化,然后按需求词条化并编码文档。

下面是对单一文档使用 HashingVectorizer 进行编码的示例。

我们选择了一个固定长度为 20 的任意向量。这个值对应哈希函数的范围,小的值(例如 20)可能会导致哈希碰撞。在之前的计算机科学课程中,我们介绍过一些启发式算法,可以根据估计的词汇量来选择哈希长度和碰撞概率。

要注意这种量化方法不要求调用函数来对训练数据文件进行拟合。相反,在实例化之后,它可以直接用于开始编码文档。

微信图片_20171017180656.jpg

微信图片_20171017180656.jpg

运行该示例代码可以把样例文档编码成一个含有 20 个元素的稀疏矩阵。

编码文档的值对应于正则化的单词计数,默认值在 -1 到 1 之间,但是可以修改默认设置,然后设置成整数计数值。

微信图片_20171017180728.jpg

微信图片_20171017180728.jpg

深度阅读

这一节我们为大家提供了一些关于这篇文章的深度阅读材料。

自然语言处理

  1. 维基百科“词袋”(Bag-of-words)模型介绍
  2. 维基百科“词条化”(Tokenization)介绍
  3. 维基百科“TF-IDF”

sciki-learn

  1. scikit-learn 使用手册 4.2 节,特征提取
  2. sckit-learn 特征提取 API
  3. scikit-learn 教程:文本数据处理

类 API

  1. CountVectorizer scikit-learn API
  2. TfidfVectorizer scikit-learn API
  3. TfidfTransformer scikit-learn API
  4. HashingVectorizer scikit-learn API

总结

在这篇教程中,你会学习到如何用 scikit-learn 来准备用于机器学习的文本数据。

我们只是在这些例子中接触了皮毛,我想强调的是这些类有许多设置细节会影响文档词条化的结果,值得我们继续探究。

查看英文原文:https://machinelearningmastery.com/prepare-text-data-machine-learning-scikit-learn/

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

3

添加新评论1 条评论

wuwenpinwuwenpin软件开发工程师南京
2017-10-17 20:57
学习了。
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广