用scikit-learn的三种词袋(BoW)生成方法为机器学习任务准备文本数据

用scikit-learn的三种词袋(BoW)生成方法为机器学习任务准备文本数据

本文为翻译博客,详见: 原文

在使用文本数据建立预测模型之前,需要做特别的数据预处理工作。

文本必须先进行分词(tokenization)操作,然后进行特征提取,即向量化(vectorization)操作,将分词后的词编码成整形或浮点数据作为机器学习算法的输入。

scikit-learn库提供了易用的工具来对文本数据做分词和特征提取。

学完这个教程后,你将会知道:

  • 如何使用CountVectorizer 将文本转化成词统计向量
  • 如何使用TfidfVectorizer 将文本转化成词频向量
  • 如何使用HashingVectorizer 将文本转化成唯一数字向量

Bag-of-Words 模型

在进行模型训练之前,我们需要将文本转化成数字。如果我们对文档进行分类,那么每一个文档都是一个输入,并且有一个对应的输出类别。因为算法都是将数字向量作为输入,所以我们需要将文档转换成指定长度的数字向量。

一种简单有效的模型叫:Bag-of-Words(BoW)模型。这个模型之所以简单,是因为它将单词之间的顺序关系全部丢弃,只关注文档中单词出现的次数。该方法为每个单词分配一个唯一编号,这样一个文档就能够被编码成与已知词汇数量相同长度的向量。向量中每一个位置上的值就是其编号对应单词在文档中出现的次数。

BoW模型有许多优化版本,优化方向包括:1)对词义的更好阐述 2)对向量中每个词的编码方式

scikit-learn库中提供了三种可用的解决方案,下面作简要介绍。

用CountVectorizer统计词频

CountVectorier 不仅提供了一个简单的方法为一系列文本文件进行分词操作,从而用这些已有的词建立一个词汇表,同时还能用这个词汇表对新文档编码。

使用步骤如下:

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

返回一个与词汇表同长的向量,向量中每个位置对应词汇表该位置上的词在当前文件中出现的次数。因为向量中包含很多的0,所以很稀疏,Python在scipy.sparse 包中提供了一个有效的方法处理稀疏向量。

上述步骤3中的transform() 函数返回一个稀疏向量,为了直观理解,我们可以用toarray() 将稀疏向量转化成numpy数组。

下面是用CountVectorizer 进行分词、建立词汇表、编码一个文件的实例。

导入CountVectorizer 库和文件:

from sklearn.feature_extraction.text import CountVectorizer
text = ["The quick brown fox jumped over the lazy dog."]

建立词汇表:

# 创建transform
vectorizer = CountVectorizer()
# 分词并建立词汇表
vectorizer.fit(text)
# 结果输出
print vectorizer.vocabulary_

输出词汇表为:

{u'brown': 0, u'lazy': 4, u'jumped': 3, u'over': 5, u'fox': 2, u'dog': 1, u'quick': 6, u'the': 7}

按照词汇表,对文件进行编码:

vector = vectorizer.transform(text)
# 输出编码后的向量信息
print vector.shape
print type(vector)
print vector.toarray()

输出为:

(1, 8)
<class 'scipy.sparse.csr.csr_matrix'>
[[1 1 1 1 1 1 1 2]]

需要重点指出的是,相同的方法可以对包含词汇表之外词汇的文件进行编码,这些词汇表中不存在的词将在返回的向量中被忽略,举个例子:

# 对另一个文件进行编码
text2 = ["the puppy"]
vector = vectorizer.transform(text2)
print vector.toarray()

输出为:

[[0 0 0 0 0 0 0 1]]

只有词汇表中存在的第七个词”the”出现一次被编码了,词汇表中不存在的“puppy”直接被忽略。

用TfidfVectorizer进行词频统计

词数统计是一个好的着手点,但是很基础。简单的词数统计存在一个问题,比如:一些像“the”这样的单词可能出现很多次,虽然在编码的向量中他们对应的数值很大,但并没有什么意义。

一种解决方案是计算词频,TF-IDF 是眼下最流行的词频计算方法,它是“Term Frequency - Inverse Documentation Frequency” 首字母的缩写。

  • Term Frequency :指在一个文件中一个指定单词出现的次数
  • Inverse Document Frequency :它降低在多个文件中均出现的单词的重要性

本文不作数学计算解释,可参考weki 。TF-IDF是词频得分,它更偏重于某个文件中新颖的单词,比如:在一个文件中多次出现,但在其他文件很少出现的单词。

TfidfVectorizer 可以对文件进行分词、学习词汇表、计算词频得分,使你能够编码新文件。如果你已经学习了一个CountVectorizer ,你可以只需用TfidfTransformer 计算inverse document frequency ,然后编码新文件。

TfidfVectorizer的使用步骤和CountVectorizer一样:创建、fit操作、transform操作。

下面是用TfidfVectorizer对3个小文件学习词汇表和inverse document frequencies,然后编码其中一篇文件的例子:

先分词并建立词汇表,计算idf得分。

from sklearn.feature_extraction.text import TfidfVectorizer
# 文件列表
text = ["The quick brown fox jumped over the lazy dog.",
        "The dog.",
        "The fox"]
# 建立transform
vectorizer = TfidfVectorizer()
# 分词,建立词汇表
vectorizer.fit(text)
# 输出结果
print vectorizer.vocabulary_
print vectorizer.idf_

输出结果:

{u'brown': 0, u'lazy': 4, u'jumped': 3, u'over': 5, u'fox': 2, u'dog': 1, u'quick': 6, u'the': 7}
[ 1.69314718  1.28768207  1.28768207  1.69314718  1.69314718  1.69314718
  1.69314718  1.        ]

编码其中一个文件:

# 编码文件
vector = vectorizer.transform([text[0]])
# 输出编码结果
print vector.shape
print vector.toarray()

输出结果:

(1, 8)
[[ 0.36388646  0.27674503  0.27674503  0.36388646  0.36388646  0.36388646
   0.36388646  0.42983441]]

这些得分向量被规范化到0-1之间,可以直接作为机器学习任务的输入。

用HashingVectorizer进行Hashing操作

词数和词频一般很有用,但这些方法有个限制——词汇表可能很大。

如果词汇表很大,那么就需要大的向量来编码文件,对存储造成压力,进而拖慢算法。

一个聪明的解决方案是对单词进行单向哈希操作,将它们转换成整数。聪明的地方在于不需要词汇表,你可以选择一个指定任意长度的向量。该方法的缺点是哈希是一个单向函数,所以不能将编码好的词变回原来的词(在大多数监督学习任务中没啥影响)。

HashingVectorizer 类步骤是先对词进行hash操作,然后对指定文件进行分词和编码。

下面的例子是使用HashVectorizer对单个文件进行操作。选择一个任意定长为20的向量,这对应了哈希函数的范围,选择的哈希长度太小(比如20)可能导致哈希冲突,这需要我们根据估计的词汇长度计算冲突的可能性,并选择合适的哈希长度。

注意这种向量化方法不需要在训练文件数据上调用fit函数,在实例化之后,它可以直接被用来编码文件。

from sklearn.feature_extraction.text import HashingVectorizer
# 文件列表
text = ["The quick brown fox jumped over the lazy dog."]
# 创建transform
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为机器学习任务准备文本数据(文件预处理),只讲了简单的实现方式,有待深挖。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本demo实现的是基于bow原理对图片进行分类,并实现对选取得测试集进行查找 BoW(Bag of Words)词袋模型最初被用在文本分类中,将文档表示成特征矢量。它的基本思想是假定对于一个文本,忽略其词序和语法、句法,仅仅将其看做是一些词汇的集合,而文本中的每个词汇都是独立的。简单说就是讲每篇文档都看成一个袋子(因为里面装的都是词汇,所以称为词袋,Bag of words即因此而来),然后看这个袋子里装的都是些什么词汇,将其分类。如果文档中猪、马、牛、羊、山谷、土地、拖拉机这样的词汇多些,而银行、大厦、汽车、公园这样的词汇少些,我们就倾向于判断它是一篇描绘乡村的文档,而不是描述城镇的。 serachFeatures.py中,前面主要是一些通过parse使得可以在敲命令行的时候可以向里面传递参数,后面就是提取SIFT特征,然后聚类,计算TF和IDF,得到单词直方图后再做一下L2归一化。一般在一幅图像中提取的到SIFT特征点是非常多的,而如果图像库很大的话,SIFT特征点会非常非常的多,直接聚类是非常困难的(内存不够,计算速度非常慢),所以,为了解决这个问题,可以以牺牲检索精度为代价,在聚类的时候先对SIFT做降采样处理。最后对一些在在线查询时会用到的变量保存下来。对于某个图像库,我们可以在命令行里通过下面命令生成BoF。 query.py只能每次查找一张图片,并返回与之匹配度(递减)最接近的6张图片
### 回答1: scikit-learn是一个用于机器学习的Python库。它提供了丰富的机器学习算法和工具,使得我们能够更加方便地进行数据挖掘和预测分析。 scikit-learn库内置了许多经典的监督学习和无监督学习算法,如线性回归、逻辑回归、决策树、支持向量机、聚类算法等。我们可以使用这些算法进行分类、回归和聚类等任务。此外,scikit-learn还提供了模型选择、特征选择和模型评估等功能,使得我们能够更好地进行模型优化和性能评估。 scikit-learn的优点之一是其简单易用的接口和一致的编程风格。我们只需使用相同的方法和参数即可应用不同的算法。这使得我们能够快速上手并且能够更好地理解和比较不同的算法。 此外,scikit-learn还具有丰富的文档和示例代码,使得我们能够更好地学习使用和掌握相关知识。我们可以利用这些文档和示例代码来了解算法的原理和使用方法,以及如何解决实际问题。 总之,scikit-learn是一个功能强大且易于使用的机器学习库。它提供了丰富的机器学习算法和工具,使得我们能够更加便捷地进行数据挖掘和预测分析,同时也提供了方便的模型选择和模型评估功能。无论是对于初学者还是有经验的机器学习工程师来说,scikit-learn都是一个不可或缺的工具。 ### 回答2: scikit-learn是一个用于机器学习的Python库。它是一个开源的工具包,提供了许多用于机器学习的算法和工具,方便用户在数据处理、特征提取、模型训练和评估等方面进行工作。 scikit-learn内置了许多经典的机器学习算法,包括回归算法、分类算法、聚类算法、降维算法等。这些算法都有统一的接口,使用起来非常方便。此外,scikit-learn还提供了用于数据预处理、特征选择、模型评估和性能提升等功能的工具和函数,使机器学习的整个流程更加简单和高效。 scikit-learn拥有广泛的应用领域,可以用于解决各种机器学习的问题。比如,可以使用scikit-learn进行文本分类、图像识别、情感分析、推荐系统等任务scikit-learn还支持多种数据类型,可以处理结构化数据、时间序列数据和图像数据等。 使用scikit-learn进行机器学习的过程一般可以分为几个步骤。首先,需要准备并加载数据集,然后进行数据预处理,包括缺失值处理、数据标准化和特征工程等。接下来,可以选择合适的模型进行训练,并使用交叉验证的方法来评估模型的性能。最后,可以使用训练好的模型来进行预测。 总之,scikit-learn为用户提供了一个强大且易于使用的机器学习工具,可以帮助用户快速构建和训练机器学习模型,从而解决实际问题。无论是对于初学者还是专业人士来说,scikit-learn都是一种强大的工具,可以极大地提高机器学习的效率和准确性。 ### 回答3: scikit-learn是一个用于数据挖掘和数据分析的Python库,也被广泛应用于机器学习领域。它提供了丰富的工具和算法,方便用户进行数据预处理、特征选择、模型训练与评估等各个环节。 首先,scikit-learn提供了大量的数据预处理工具,包括标准化、归一化、缺失值处理等。通过这些工具,我们能够快速地对原始数据进行处理,使其适合机器学习算法的使用。 其次,scikit-learn还提供了丰富的特征选择方法,帮助我们筛选出对目标变量相关性较高的特征。这些方法包括方差阈值、单变量特征选择、递归特征消除等。通过特征选择,我们能够减少特征的维度,提高模型训练的效率和准确性。 针对各种机器学习任务scikit-learn提供了丰富的算法,如线性回归、逻辑回归、决策树、支持向量机、随机森林、K近邻等。这些算法具有良好的可解释性和表达能力,能够解决各种不同的问题。 此外,scikit-learn提供了丰富的模型评估指标和交叉验证方法,帮助我们评估模型的性能和泛化能力。通过这些评估指标,我们能够选择最优的模型,并进行模型的调参。 总之,scikit-learn是一个功能强大、易于使用且免费的机器学习库。它提供了丰富的工具和算法,帮助用户进行数据处理、特征选择、模型训练与评估等各个流程,并帮助用户构建高性能的机器学习模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值