【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

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

  • 2017-10-31
  • 本文字数:4004 字

    阅读完需:约 13 分钟

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

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

scikit-learn 提供了简单的工具帮助我们对你的文本数据进行词条化和特征提取。

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

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

  • 如何使用 CountVectorizer 将文本的转化成单词频数向量。
  • 如何使用 TfidfVectorizer 提取文本的单词权重向量。
  • 如何使用 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 来词条化、构造词汇表,以及编码文档的示例。

复制代码
from sklearn.feature_extraction.text import CountVectorizer
# 文本文档列表
text = ["The quick brown fox jumped over the lazy dog."]
# 构造变换函数
vectorizer = CountVectorizer()
# 词条化以及建立词汇表
vectorizer.fit(text)
# 总结
print(vectorizer.vocabulary_)
# 编码文档
vector = vectorizer.transform(text)
# 总结编码文档
print(vector.shape)
print(type(vector))
print(vector.toarray())

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

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

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

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

复制代码
{'dog': 1, 'fox': 2, 'over': 5, 'brown': 0, 'quick': 6, 'the': 7, 'lazy': 4, 'jumped': 3}
(1, 8)
<class 'scipy.sparse.csr.csr_matrix'>
[[1 1 1 1 1 1 1 2]]
{1}

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

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

复制代码
# 编码其他文档
text2 = ["the puppy"]
vector = vectorizer.transform(text2)
print(vector.toarray())

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

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

TfidfVectorizer——计算单词权重

统计单词出现次数是一个很好的切入点,但也是很基础的特征。

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

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

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

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

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

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

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

复制代码
from sklearn.feature_extraction.text import TfidfVectorizer
# 文本文档列表
text = ["The quick brown fox jumped over the lazy dog.",
"The dog.",
"The fox"]
# 创建变换函数
vectorizer = TfidfVectorizer()
# 词条化以及创建词汇表
vectorizer.fit(text)
# 总结
print(vectorizer.vocabulary_)
print(vectorizer.idf_)
# 编码文档
vector = vectorizer.transform([text[0]])
# 总结编码文档
print(vector.shape)
print(vector.toarray())

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

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

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

复制代码
{'fox': 2, 'lazy': 4, 'dog': 1, 'quick': 6, 'the': 7, 'over': 5, 'brown': 0, 'jumped': 3}
[ 1.69314718 1.28768207 1.28768207 1.69314718 1.69314718 1.69314718
1.69314718 1. ]
(1, 8)
[[ 0.36388646 0.27674503 0.27674503 0.36388646 0.36388646 0.36388646
0.36388646 0.42983441]]

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

HashingVectorizer——哈希量化文本

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

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

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

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

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

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

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

复制代码
from sklearn.feature_extraction.text import HashingVectorizer
# 文本文档列表
text = ["The quick brown fox jumped over the lazy dog."]
# 创建变换函数
vectorizer = HashingVectorizer(n_features=20)
# 编码文档
vector = vectorizer.transform(text)
# 总结编码文档
print(vector.shape)
print(vector.toarray())

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

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

复制代码
(1, 20)
[[ 0. 0. 0. 0. 0. 0.33333333
0. -0.33333333 0.33333333 0. 0. 0.33333333
0. 0. 0. -0.33333333 0. 0.
-0.66666667 0. ]]

深度阅读

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

自然语言处理

scikit-learn

类 API

总结

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

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

查看英文原文: How to Prepare Text Data for Machine Learning with scikit-learn

感谢薛命灯对本文的审校。

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2017-10-31 17:483615
用户头像

发布了 52 篇内容, 共 28.1 次阅读, 收获喜欢 72 次。

关注

评论

发布
暂无评论
发现更多内容

运行程序提示路径错误?

矩视智能

深度学习 机器视觉

HarmonyOS NEXT带来的DevEco Profiler助您轻松分析应用性能问题

Geek_2d6073

华为云CodeArts Check代码检查服务用户声音反馈集锦(1)

华为云PaaS服务小智

云计算 软件开发 华为云

9.19-21,openEuler与您相约2023欧洲开源峰会

openEuler

Linux 开源 操作系统 openEuler

生成式AI的发展与内容质量及安全性的挑战

百度开发者中心

#人工智能 生成式AI 文心一言 千帆大模型平台

基于YOLOv2和传感器的多功能门禁系统

timerring

YOLOv2

GLTF-pipeline

3D建模设计

gltf编辑器

如何在Blender中压缩/减小GLTF模型的大小

3D建模设计

blender GLTF

预告!网络安全红队GPT大模型训练直播来袭

云起无垠

使用Docker构建轻量级Linux容器

互联网工科生

Docker 容器

Red Giant Magic Bullet Suite for Mac(红巨人调色降噪插件合集下载) v2024.0.0永久激活版

mac

苹果mac Windows软件 Red Giant Magic Bullet 视频后期处理软件

OpenCloudOS + 英特尔第四代至强处理器:完美适配,加速未来

OpenCloudOS

Linux intel

解决方案| anyRTC远程检修应用场景

anyRTC开发者

人工智能 音视频 视频会议 远程协助 电话会议

国产化操作系统有哪些?适配国产化操作系统堡垒机哪款好用?

行云管家

信创 堡垒机 国产化 国产操作系统 国产

基于Web的智慧污水厂2D组态系统

2D3D前端可视化开发

组态软件 智慧水务 智慧污水处理 污水厂组态图 污水厂监控系统

文心一言 VS 讯飞星火 VS chatgpt (93)-- 算法导论9.2 1题

福大大架构师每日一题

福大大架构师每日一题

HarmonyOS应用侧与前端页面数据通道建立

HarmonyOS开发者

HarmonyOS

5 个适合出海离岸公司的地区推荐

出海的猹

出海企业

文字图像转换的创新技术

百度开发者中心

#人工智能 生成式AI 千帆大模型平台

创新生产力的新引擎

百度开发者中心

#人工智能 生成式AI 文心一言

医院如何实现安全又稳定的跨网文件数据交换呢?

镭速

跨网文件数据交换

揭秘 ChunJun:如何实现 e2e&session 日志隔离

袋鼠云数栈

大数据 开源

为什么选择事件驱动的微服务架构?

这我可不懂

微服务

创新力量重塑生产力

百度开发者中心

文学 #人工智能 生成式AI 文心一言

反驳来了!放弃TypeScript?说明你无知!

树上有只程序猿

typescript 代码质量 js

2023百度教育再出发,探索经营增长新空间

彭飞

如何将 OBJ 模型转换和压缩为 GLTF 以与 AWS IoT TwinMaker 配合使用

3D建模设计

GLTF

GLTF文件格式解析与预览、编辑

3D建模设计

GLTF

glTF 中基于物理的渲染(PBR)

3D建模设计

莆田市属于哪个省?有正规等保测评机构吗?

行云管家

等保 等保测评 等保等级保护

北京大上科技发布全球首款25.3英寸彩色墨水屏显示器

硬科技星球

如何使用Scikit-learn实现用于机器学习的文本数据准备_语言 & 开发_Jason Brownlee_InfoQ精选文章