欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~

文本数据需要特殊处理,然后才能开始将其用于预测建模。

我们需要解析文本,以删除被称为标记化的单词。然后,这些词还需要被编码为整型或浮点型,以用作机器学习算法的输入,这一过程称为特征提取(或矢量化)。

scikit-learn 库提供易于使用的工具来对文本数据进行标记和特征提取。

在本教程中,您可以学到如何使用 scikit-learn 为 Python 中的预测建模准备文本数据。

完成本教程后,您可以学到:

  • 如何使用 CountVectorizer 将文本转换为文字计数向量。
  • 如何使用 TfidfVectorizer 将文本转换为词频向量。
  • 如何使用 HashingVectorizer 将文本转换为唯一的整数。

让我们开始吧。

词袋模型( Bag-of-Words Model )

使用机器学习算法时,我们不能直接使用文本。

相反,我们需要将文本转换为数字。

我们可能想对文档进行分类,每一类文档都是“输入”,而类别标签是我们预测算法的“输出”。算法将数字向量作为输入,因此我们需要将文档转换为固定长度的数字向量。

在机器学习中,Bag-of-Words 模型(BoW)是一种简单而有效的让计算机“理解”文本文档的模型。

这个模型非常简单,它移除了单词的诸如词序、语法等顺序信息,只关注文档中该单词的出现情况。

上面这一步可以通过为每个单词分配一个唯一的编码来完成。我们所看到的任何文档都可以被编码为一个固定长度的矢量,其长度为文档中全部已知单词的词汇量。矢量中每个位置的值可以用编码文档中每个单词的出现个数或频率填充。

在词袋模型中,我们只关心编码方案,而编码方案描述了文档中出现了什么单词,以及这些单词在编码文档中出现的频率,而没有任何关于顺序的信息。

有很多方法来扩展这个简单的方法,例如,我们可以想办法更好地解释一个单词的含义,或是更好地规定向量中每个单词的编码方式。

scikit-learn 库提供了3种不同的方案供我们使用,下面简要地介绍一下。

使用 CountVectorizer 计算字数

CountVectorizer 提供了一个简单的方法,既可以标记文本文档的集合, 也可以生成每个已知单词的索引, 还可以使用这一套索引对新文档进行编码。

下面是一种使用方法:

  1. 实例化一个 CountVectorizer 类。
  2. 调用 fit() 函数以从一个或多个文档中建立索引。
  3. 根据需要在一个或多个文档中调用 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

API

概要

在本教程中,你可以了解如何使用scikit-learn为机器学习准备文本文档。

这些例子只是抓住了表面,但是,这些类有很多配置细节影响着文档的标记,这些都是值得深究的。

翻译人:Bay,该成员来自云+社区翻译社

原文链接:https://machinelearningmastery.com/prepare-news-articles-text-summarization/

原文作者:Jason Brownlee

相关阅读

Android图像处理 - 高斯模糊的原理及实现

通过Pandas实现快速别致的数据分析

如何使用scikit-learn在Python中生成测试数据集


此文已由作者授权云加社区发布,转载请注明文章出处

如何使用 scikit-learn 为机器学习准备文本数据的更多相关文章

  1. scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类 (python代码)

    scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类数据集 fetch_20newsgroups #-*- coding: UTF-8 -*- import ...

  2. (原创)(三)机器学习笔记之Scikit Learn的线性回归模型初探

    一.Scikit Learn中使用estimator三部曲 1. 构造estimator 2. 训练模型:fit 3. 利用模型进行预测:predict 二.模型评价 模型训练好后,度量模型拟合效果的 ...

  3. (原创)(四)机器学习笔记之Scikit Learn的Logistic回归初探

    目录 5.3 使用LogisticRegressionCV进行正则化的 Logistic Regression 参数调优 一.Scikit Learn中有关logistics回归函数的介绍 1. 交叉 ...

  4. Scikit Learn: 在python中机器学习

    转自:http://my.oschina.net/u/175377/blog/84420#OSC_h2_23 Scikit Learn: 在python中机器学习 Warning 警告:有些没能理解的 ...

  5. Scikit Learn

    Scikit Learn Scikit-Learn简称sklearn,基于 Python 语言的,简单高效的数据挖掘和数据分析工具,建立在 NumPy,SciPy 和 matplotlib 上.

  6. scikit-learning教程(三)使用文本数据

    使用文本数据 本指南的目标是探讨scikit-learn 一个实际任务中的一些主要工具:分析二十个不同主题的文本文档(新闻组帖子)集合. 在本节中,我们将看到如何: 加载文件内容和类别 提取适用于机器 ...

  7. Bulk Insert:将文本数据(csv和txt)导入到数据库中

    将文本数据导入到数据库中的方法有很多,将文本格式(csv和txt)导入到SQL Server中,bulk insert是最简单的实现方法 1,bulk insert命令,经过简化如下 BULK INS ...

  8. JAVASE02-Unit08: 文本数据IO操作 、 异常处理

    Unit08: 文本数据IO操作 . 异常处理 * java.io.ObjectOutputStream * 对象输出流,作用是进行对象序列化 package day08; import java.i ...

  9. JAVASE02-Unit07: 基本IO操作 、 文本数据IO操作

    基本IO操作 . 文本数据IO操作 java标准IO(input/output)操作 package day07; import java.io.FileOutputStream; import ja ...

随机推荐

  1. Entity Framework Core 懒加载

    众所周知在EF 6 及以前的版本中,是支持懒加载(Lazy Loading)的,可惜在EF Core 并不支持,必须使用Include方法来支持导航属性的数据加载.不过现在EF Core的开发团队打算 ...

  2. C#的改进特性

    1.初始器 当你新建一个对象实例的时候,是否遇到下面这种情况: class a = new class(); a.item1 = "; a.item2 = "; 或者写一个构造函数 ...

  3. 久未更 ~ 五之 —— 引入外部CSS样式表 小节

    > > > > > 久未更 系列一:在html中引入外部css样式表 //引入外部css样式表 //<lilnk>要放在<head>标签的第一行, ...

  4. dede后台登陆后一片空白的解决办法汇总

    dede后台登陆后一片空白的第一种解决办法: 找到:include/common.inc.php文件,打开,查找程序代码://error_reporting(E_ALL);error_reportin ...

  5. 如何设置让网站禁止被爬虫收录?robots.txt

    robot.txt只是爬虫禁抓协议,user-agent表示禁止哪个爬虫,disallow告诉爬出那个禁止抓取的目录. 如果爬虫够友好的话,会遵守网站的robot.txt内容. 一个内部业务系统,不想 ...

  6. SSH问题:系统启动时,spring配置文件解析失败,报”cvc-elt.1: 找不到元素 'beans' 的声明“异常

    现象:spring加载配置文件applicationContext.xml出错,抛出nested exception is og.xml.sax.SAXParseException; lineNumb ...

  7. 注释中不允许出现字符串 "--"。

    问题: 在启动tomcat时会出现如上错误,同时有可能会出现xml无法解析等错误 解决办法: 注释中不能出现字符串 "--",即需要把xml文件中多余的“--”去掉,例如: < ...

  8. 修真院java后端工程师学习课程--任务1(day four)

    今天学习的是spring框架,内容主要有: spring的概念,主要是做什么的: Spring是一个基于IOC和AOP的结构J2EE系统的框架 IOC 反转控制 是Spring的基础,Inversio ...

  9. BOM基础知识

    1.什么是BOM      BOM(Browser Object Document)即浏览器对象模型.      BOM提供了独立于内容 而与浏览器窗口进行交互的对象:      由于BOM主要用于管 ...

  10. python装饰器实现对异常代码出现进行监控

    异常,不应该存在,但是我们有时候会遇到这样的情况,比如我们监控服务器的时候,每一秒去采集一次信息,那么有一秒没有采集到我们想要的信息,但是下一秒采集到了, 而后每次的采集都能采集到,就那么一次采集不到 ...