如何使用 scikit-learn 为机器学习准备文本数据
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~
文本数据需要特殊处理,然后才能开始将其用于预测建模。
我们需要解析文本,以删除被称为标记化的单词。然后,这些词还需要被编码为整型或浮点型,以用作机器学习算法的输入,这一过程称为特征提取(或矢量化)。
scikit-learn 库提供易于使用的工具来对文本数据进行标记和特征提取。
在本教程中,您可以学到如何使用 scikit-learn 为 Python 中的预测建模准备文本数据。
完成本教程后,您可以学到:
- 如何使用 CountVectorizer 将文本转换为文字计数向量。
- 如何使用 TfidfVectorizer 将文本转换为词频向量。
- 如何使用 HashingVectorizer 将文本转换为唯一的整数。
让我们开始吧。

词袋模型( Bag-of-Words Model )
使用机器学习算法时,我们不能直接使用文本。
相反,我们需要将文本转换为数字。
我们可能想对文档进行分类,每一类文档都是“输入”,而类别标签是我们预测算法的“输出”。算法将数字向量作为输入,因此我们需要将文档转换为固定长度的数字向量。
在机器学习中,Bag-of-Words 模型(BoW)是一种简单而有效的让计算机“理解”文本文档的模型。
这个模型非常简单,它移除了单词的诸如词序、语法等顺序信息,只关注文档中该单词的出现情况。
上面这一步可以通过为每个单词分配一个唯一的编码来完成。我们所看到的任何文档都可以被编码为一个固定长度的矢量,其长度为文档中全部已知单词的词汇量。矢量中每个位置的值可以用编码文档中每个单词的出现个数或频率填充。
在词袋模型中,我们只关心编码方案,而编码方案描述了文档中出现了什么单词,以及这些单词在编码文档中出现的频率,而没有任何关于顺序的信息。
有很多方法来扩展这个简单的方法,例如,我们可以想办法更好地解释一个单词的含义,或是更好地规定向量中每个单词的编码方式。
scikit-learn 库提供了3种不同的方案供我们使用,下面简要地介绍一下。
使用 CountVectorizer 计算字数
CountVectorizer 提供了一个简单的方法,既可以标记文本文档的集合, 也可以生成每个已知单词的索引, 还可以使用这一套索引对新文档进行编码。
下面是一种使用方法:
- 实例化一个 CountVectorizer 类。
- 调用 fit() 函数以从一个或多个文档中建立索引。
- 根据需要在一个或多个文档中调用 transform() 函数,将每个文档编码为一个向量。
最终会返回一个已编码的向量, 其长度为索引的个数,该向量还携带有文档中每个单词出现的次数信息。
包含很多零的向量被称为稀疏向量。Python 的 scipy.sparse 包中提供了一种处理稀疏向量的有效方法。
调用 transform() 返回的向量是稀疏向量,这里可以通过调用 toarray() 函数将它们转换回 numpy 数组以便查看并更好地理解这个过程。
下面是使用 CountVectorizer 标记,构建索引,然后编码文档的示例。
from sklearn.feature_extraction.text import CountVectorizer # 下面是一个文本文档的列表 text = ["The quick brown fox jumped over the lazy dog."] # 实例化 CountVectorizer 类 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。
从接下来输出的类型中可以看出,编码向量是一个稀疏向量。而最后的输出是编码向量的数组版本,其表达的含义是,索引值为 7 的单词出现次数为 2,其余单词出现次数为 1。
{'dog': , 'fox': , 'over': , 'brown': , 'quick': , 'the': , 'lazy': , 'jumped': }
(, )
<class 'scipy.sparse.csr.csr_matrix'>
[[ ]]
重要的是,同一个矢量化器可以用在包含词汇表中没有包括的单词的文档上。不过,没有包括的词会被忽略,并且不会在结果向量中计数。
举个例子,下面是使用上述向量化器对另一个文档进行编码的例子。这个文本文档包含两个词,一个词包含在索引中,另一个不包含在索引中。
将另一个文档编码
text2 = ["the puppy"] vector = vectorizer.transform(text2) print(vector.toarray())
运行这个例子,会输出编码的稀疏向量的数组版本,从这个输出中可以看出,在词汇中出现的单词的没有被忽略,而另一个不在词汇中的单词被忽略了。
[[ ]]
这之后,编码向量就可以直接使用到机器学习算法中了。
使用 TfidfVectorizer 统计词频
单词计数是一个非常好、非常简单的起点。
不过,简单计数也存在不足。例如,简单计数中像“ the ” 这样的词会出现很多次,在编码的向量中,这样的单词计数会很大,却没有太大意义。
除了统计个数外的另一种方法是计算词频,到目前为止,最流行的方法是TF-IDF。TF-IDF 是 Term Frequency - Inverse Document Frequency 的首字母缩写词,它是分配给每个单词的结果分数的组成部分。
- 词频(Term Frequency):该值表示给定单词在这份文档中出现的频率。
- 逆向文件频率(Inverse Document Frequency):该值用于降低其他文档中普遍出现的单词的最终评分。
没有进入数学,TF-IDF是词频分数,可以突出个性化的单词,例如在只在这份文档中频繁出现,但其他文档中较少出现的单词。
TfidfVectorizer将标记文件、建立索引、求出逆文档频率权重,并允许您编码新的文件。或者,如果您已经有了一个已经训练过的 CountVectorizer,您可以将其与 TfidfTransformer一起使用,以计算逆文档频率并开始编码文档。
TfidfVectorizer 的实例化、拟合和转换方法和 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(text0) # 查看编码后的向量 print(vector.shape) print(vector.toarray())
从文档中学习 8 个单词的得到索引,并且每个单词在输出向量中被分配唯一的整数索引值。
计算每个单词的逆文档频率,将最低分数 1.0 分配给最常见的词:索引值为 7 的“the”。
最后,第一个文档被编码为一个8元素的稀疏数组,我们可以从结果中的其他单词中查看诸如“the”,“fox”和“dog”等不同值的最终评分。
{'fox': , 'lazy': , 'dog': , 'quick': , 'the': , 'over': , 'brown': , 'jumped': }
[ 1.69314718 1.28768207 1.28768207 1.69314718 1.69314718 1.69314718
1.69314718 . ]
(, )
[[ 0.36388646 0.27674503 0.27674503 0.36388646 0.36388646 0.36388646
0.36388646 0.42983441]]
将评分标准化为 0 到 1 之间的值。在这之后,编码过的文档向量即可直接用于大多数机器学习算法中了。
使用 HashingVectorizer 建立散列表
统计个数和计算频率两种方法虽然非常实用,但是也由其局限性导致词汇量可能变得非常大。
词汇量过大又将导致需要非常大的矢量来编码文档,从而对内存产生很大的要求,同时拖慢算法的速度。
这里有一个巧妙的解决方法,即建立单词的单向散列表,进而将每个单词转换为整数。这么做的优点是不需要专门建立索引,并且你可以将定长向量的长度定为任意值。缺点是散列是一个单向函数,所以没有办法将编码转换回单词(不过这一步对于许多监督学习任务可能并不重要)。
HashingVectorizer 类实现了此方法,使其可用于一致地散列单词,然后根据需要标记和编码文件。
下面的示例演示了用于编码单个文档的 HashingVectorizer。
选择长度为 20 的定长向量。这个长度对应于散列函数的范围,不过例如 20 这样的小值可能导致散列表冲突。回想计算机科学课里相关的知识,这里可以使用试探法,根据估计的词汇量的大小和碰撞概率来挑选哈希长度。
请注意,这个矢量化器不需要调用 fit() 函数来训练数据文档。实例化之后,它可以直接用于编码文档。
from sklearn.feature_extraction.text import HashingVectorizer # 下面是一个文本文档的列表 text = ["The quick brown fox jumped over the lazy dog."] # 实例化 HashingVectorizer vectorizer = HashingVectorizer(n_features=) # 编码文档 vector = vectorizer.transform(text) # 查看编码后的向量 print(vector.shape) print(vector.toarray())
运行上述示例代码,样例文档将被编码为包含 20 个元素的稀疏数组。
编码文档的值默认将字数标准化到 -1 和 1 之间,这里也可以通过更改默认配置使其进行简单的整数计数。
(, ) [[ . . . . . 0.33333333 . -0.33333333 0.33333333 . . 0.33333333 . . . -0.33333333 . . -0.66666667 . ]]
进一步探究
如果您想进行深入研究,下面提供更多有关该主题的资源。
自然语言处理
sciki-learn
- 4.2节 特征提取,scikit-learn用户指南
- sckit-learn特征提取API
- 使用文本数据,scikit学习教程
API
- CountVectorizer scikit-learn API
- TfidfVectorizer scikit学习API
- TfidfTransformer scikit-learn API
- HashingVectorizer scikit学习API
概要
在本教程中,你可以了解如何使用scikit-learn为机器学习准备文本文档。
这些例子只是抓住了表面,但是,这些类有很多配置细节影响着文档的标记,这些都是值得深究的。
翻译人:Bay,该成员来自云+社区翻译社
原文链接:https://machinelearningmastery.com/prepare-news-articles-text-summarization/
原文作者:Jason Brownlee
相关阅读
如何使用scikit-learn在Python中生成测试数据集
此文已由作者授权云加社区发布,转载请注明文章出处
如何使用 scikit-learn 为机器学习准备文本数据的更多相关文章
- scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类 (python代码)
scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类数据集 fetch_20newsgroups #-*- coding: UTF-8 -*- import ...
- (原创)(三)机器学习笔记之Scikit Learn的线性回归模型初探
一.Scikit Learn中使用estimator三部曲 1. 构造estimator 2. 训练模型:fit 3. 利用模型进行预测:predict 二.模型评价 模型训练好后,度量模型拟合效果的 ...
- (原创)(四)机器学习笔记之Scikit Learn的Logistic回归初探
目录 5.3 使用LogisticRegressionCV进行正则化的 Logistic Regression 参数调优 一.Scikit Learn中有关logistics回归函数的介绍 1. 交叉 ...
- Scikit Learn: 在python中机器学习
转自:http://my.oschina.net/u/175377/blog/84420#OSC_h2_23 Scikit Learn: 在python中机器学习 Warning 警告:有些没能理解的 ...
- Scikit Learn
Scikit Learn Scikit-Learn简称sklearn,基于 Python 语言的,简单高效的数据挖掘和数据分析工具,建立在 NumPy,SciPy 和 matplotlib 上.
- scikit-learning教程(三)使用文本数据
使用文本数据 本指南的目标是探讨scikit-learn 一个实际任务中的一些主要工具:分析二十个不同主题的文本文档(新闻组帖子)集合. 在本节中,我们将看到如何: 加载文件内容和类别 提取适用于机器 ...
- Bulk Insert:将文本数据(csv和txt)导入到数据库中
将文本数据导入到数据库中的方法有很多,将文本格式(csv和txt)导入到SQL Server中,bulk insert是最简单的实现方法 1,bulk insert命令,经过简化如下 BULK INS ...
- JAVASE02-Unit08: 文本数据IO操作 、 异常处理
Unit08: 文本数据IO操作 . 异常处理 * java.io.ObjectOutputStream * 对象输出流,作用是进行对象序列化 package day08; import java.i ...
- JAVASE02-Unit07: 基本IO操作 、 文本数据IO操作
基本IO操作 . 文本数据IO操作 java标准IO(input/output)操作 package day07; import java.io.FileOutputStream; import ja ...
随机推荐
- Windows系统下文件的概念及c语言对其的基本操作(丙)
- 配置web.xml文件用于配置tomcat
<Context path = "/myweb" docBase = "E:\workspace1\myweb\WebRoot" reloadable = ...
- C++输出二进制文件和文本文件
所谓二进制文件和文本文件对于字母而言没有什么不同,都是存储该字母的ASCII码值.能引起不同的是数字和一些排版用符号的格式. 数字在二进制文件中会存储该数字的值,而文本文件中则首先将该数字视为字符量, ...
- Spark算子--foreach和foreachPartition
转载请标明出处http://www.cnblogs.com/haozhengfei/p/6776fe93f754daf60d00d2cb509422a1.html foreach和foreachPar ...
- CCF系列之窗口(201403-2)
试题编号: 201403-2时间限制: 1.0s 内存限制: 256.0MB 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域.窗口的边界上的点也属于该窗口 ...
- C#如何释放已经加载的图片
使用Image.FromFile取磁盘上的图片时,这个方法会锁定图片文件,而且会导致内存占用增大, 有几种方法解决:一:将Image类转换成Bitmap类System.Drawing.Image im ...
- Steeze框架之入门使用
一.介绍 steeze是一个优雅.简洁而又高效的PHP开源框架,在整合了知名框架ThinkPHP和Laravel优点的同时,重写了底层架构,增强了功能实现.支持swoole模型运行,支持容器.模型.依 ...
- scrapy_items
为什么要items? 当数据量多的时候,没有统一的数据管理,统一格式化麻烦 items中除了能添加字段,还能做什么? 1. 进行预先处理 2. 对从items出去的数据进行处理 3. 写上sql语句逻 ...
- python2.7.5 安装pip
1 先安装setuptools 下载地址:https://pypi.python.org/pypi/setuptools#downloads 将下载后的tar文件解压,用CMD模式进入到解压后的文件所 ...
- CopyOnWriteArrayList集合排序异常问题
1.集合自定义排序实现 对List集合的自定义排序想必大家都知道要使用如下的方式,通过实现Comparator接口并实现compare方法来实现. /** * * @方法名 changeChain * ...