在开始使用文本数据进行预测建模之前,需要进行大量的预备工作。必须解析文本标记化,删去不必要的单词接着,这些单词需要被编码为整数或浮点值,以用作机器学习算法的输入,这一过程为特征提取(或矢量化)。scikit-learn库提供很多简单易用的工具,可以帮您进行文本数据的标记化和特征提取。在本教程中,您将了解如何使用scikit-learnPython中为预测建模准备文本数据。完成本教程后,您将了解:

如何使用CountVectorizer将文本转换为字数统计向量。

如何使用TfidfVectorizer将文本转换为字频向量。

如何使用HashingVectorizer将文本转换为唯一的整数。

3.1 词袋模型

我们如果想要文档进行分类,要进行的工作是对每个输入的文档,经常预测算法处理后都能给出对应类别标签但是机器学习算法无法直接应用于文本的,因此需要将文本转换为数字算法将转换后数字向量作为输入才能正常的使用机器学习的算法,对文章类别进行预测,在转换过程中为了方便机器处理,可以考虑将文档转换为固定长度的数字向量。

在机器学习中处理文本文档的简单有效模型称为Bag-of-Words模型,即BoW。请注意,我们将在下一部分中详细介绍BoW模型,从第8章开始。模型很简单,它会抛弃单词中的所有顺序信息,并关注文档中单词的出现次数。这可以通过为每个单词分配唯一编号来完成。然后,我们看到的任何文档都可以编码为具有已知单词词汇长度的固定长度向量。矢量中每个位置的值可以用编码文档中每个单词的计数或频率填充。

这是词袋模型,我们只关注编码方案,这些编码方案表示存在的单词或它们在编码文档中存在的程度,而没有关于顺序的任何信息。有许多方法可以扩展这个简单的方法,既可以更好地阐明单词是什么,也可以定义对向量中每个单词进行编码的内容。scikit-learn库提供了我们可以使用的3种不同方法,我们将简要介绍每种方案。

3.2 Word计数与CountVectorizer

CountVectorizer提供了一种简单的方法,既可以标记文本文档的集合,也可以构建已知单词的词汇表,还可以使用该词汇表对新文档进行编码。您可以按如下方式使用它:

创建CountVectorizer类的实例。

调用fit()函数以便从一个或多个文档中学习词汇表。

根据需要在一个或多个文档上调用transform()函数,将每个文档编码为向量。

返回编码向量表示文档中每个单词出现的次数的整数计数,向量的长度整个词汇表的长度因为返回的文本向量将包含许多零,所以我们将它们称为稀疏。Pythonscipy.sparse包中提供了处理稀疏向量的有效方法。调用transform()返回的向量将是稀疏向量,可以通过调用NumPytoarray()方法将它们转换回数组,以通过调用函数来查看并更好地了解正在发生的事情。下面是使用CountVectorizer进行标记,构建词汇表,然后对文档进行编码的示例。

from sklearn.feature_extraction.text import CountVectorizer
# list of text documents
text = ["The quick brown fox jumped over the lazy dog."]
#  create the transform
vectorizer = CountVectorizer()
   # tokenize and build vocab
vectorizer.fit(text)
#summarize
print(vectorizer.vocabulary_)
# encode document
vector = vectorizer.transform(text)

   # summarize encoded vector
print(vector.shape)
print(type(vector))
print(vector.toarray())

代码3.1:训练CountVectorizer的示例

在上面,您可以看到我们访问词汇表以查看通过调用标记的确切内容:

print(vectorizer.vocabulary_)

代码3.2:词汇表

 

我们可以看到默认情况下所有单词都是小写的,并且忽略了标点符号。可以配置对应的参数来决定忽略什么使用什么,建议查看API文档中的所有选项。首先运行示例打印词汇表,然后打印文档向量的大小。词汇中有8个单词,因此编码的向量长度为8,接着们可以看到编码的向量是稀疏矩阵。最后,我们可以看到编码向量的数组版本,显示除了出现2的(indexid 7)之外的每个单词的1次出现次数。

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

(1, 8)

<class 'scipy.sparse.csr.csr_matrix'>

[[1 1 1 1 1 1 1 2]]

代码清单3.3:训练CountVectorizer的示例输出

重要的是,相同的矢量化器可以用于包含词汇表中未包含的单词的文档。忽略这些单词,并且在结果向量中不给出计数。例如,下面是使用上面的矢量化器来编码文档中的一个单词和一个单词不是的单词的示例。

# encodeanotherdocument
text2 = ["the puppy"]
vector = vectorizer.transform(text2)
print(vector.toarray())

代码清单3.4:使用CountVectorizer编码未出现词的示例

运行此示例打印编码稀疏向量的数组版本,显示词汇中一个单词出现一次,而词汇表中没有的另一个单词完全被忽略。

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

代码清单3.5:编码另一个文档的示例输出

然后,编码的矢量可以直接与机器学习算法一起使用。

3.3 使用TfidfVectorizer的单词频率

单词计数是一个很好的起点,但非常基本。简单计数的一个问题是某些像will这样的单词会出现很多次,它们在编码向量中意义不大。另一种方法是计算字频率,到目前为止,最流行的方法称为TF-IDF。这是一个缩写,代表术语Term Frequency - Inverse Document Frequency,它表示的是每个单词在文本中出现的分值。

  • Term Frequency::给定单词在文档中出现的频率。
  • Inverse Document Frequency:这缩小了文档中出现的很多单词。

不用去考虑数学的含义及计算方法,TF-IDF文档中单词频率分数,试图突出文本中更重要的单词,我们通常在文档中计算单词的频率是不跨文档,很难一下子确具体一篇文献中哪些词语是关键词,利用TF-IDF就可以快速的确定文本的关键词。TfidfVectorizer对库中文档分词学习词汇和反向每个词的文档频率权重,用学习的后的结果,来处理新加入的文本。如果您已经学习了CountVectorizer,则可以将其与TfidfTransformer一起使用,以计算逆文档频率并处理新文档。与CountVectorizer一样使用相同的创建,拟合和转换过程。下面是使用TfidfVectorizer学习3个小文档中的词汇和逆文档频率然后编码其中一个文档的示例。

from sklearn.feature_extraction.text import TfidfVectorizer
# list of text documents
text = ["The quick brown fox jumped over the lazy dog.", "The dog.",
        "The fox"]
# create the transform
vectorizer = TfidfVectorizer()
# tokenize and build vocab
vectorizer.fit(text)
#  summarize
print(vectorizer.vocabulary_)
print(vectorizer.idf_)
# encode document
vector = vectorizer.transform([text[0]])
# summarize encoded vector
print(vector.shape)
print(vector.toarray())

代码清单3.6:培训TfidfVectorizer的示例

从文档中学习8个单词的词汇表,并且在输出向量中为每个单词分配唯一的整数索引。计算词汇表中每个单词的逆文档频率,将最低分数1.0分配给最常观察的单词:at索引7.最后,将第一个文档编码为8个元素的稀疏数组,我们可以查看每个单词的最终评分,其中包含词汇表中其他单词的不同值,狐狸和狗。

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

[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]]

代码3.7:训练TfidfVectorizer的示例输出

将得分归一化为01之间的值,然后可以将编码的文档向量直接用于大多数机器学习算法。

3.4 使用HashingVectorizer处理文本

计数和频率可能非常有用,但这些方法的一个限制是词汇量会变得非常大。反过来,这将需要大的向量来编码文档,并对内存大量要求降低算法速度。一个聪明的解决方法是使用单向哈希值将它们转换为整数。聪明的部分是不需要词汇表,你可以选择任意长度的固定长度矢量。不利方面是哈希是一个单向函数,所以没有办法将编码转换回一个单词(这对许多监督学习任务可能无关紧要)。

HashingVectorizer类实现了这种方法,可用于一致地散列单词,然后根据需要对文档进行token和编码。下面的示例演示了HashingVectorizer处理单文档的过程选择矢量长度为20。这对应于散列函数的范围,其中小值(如20)可能导致哈希冲突。记得回到计算机科学课程,我相信有一些启发式方法可以用来根据估计的词汇量大小来选择哈希长度和碰撞概率(例如,加载因子为75%)。查看有关该主题的任何优秀教科书。请注意,此向量化程序不需要调用fit训练数据文档。相反,在实例化之后,它可以直接用于编码文档。

from sklearn.feature_extraction.text import HashingVectorizer
# list of text documents
text = ["The quick brown fox jumped over the lazy dog."]
# create the transform
vectorizer = HashingVectorizer(n_features=20)
# encode document
vector = vectorizer.transform(text)
# summarize encoded vector
print(vector.shape)
print(vector.toarray())

代码清单3.8:训练HashingVectorizer的示例

运行该示例将示例文档编码为20个元素的稀疏数组。编码文档的值默认对应于标准化字数,范围为-11,但可以通过更改默认配置使其成为简单整数计数。

(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.        ]]

代码3.9:训练HashingVectorizer的示例输出

3.5 进一步阅读

如果您要深入了解,本节将提供有关该主题的更多资源。

3.5.1 自然语言处理

维基百科上的词袋模型。 https://en.wikipedia.org/wiki/Bag-of-words_model

维基百科上的标记化。https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization

维基百科上的TF-IDFhttp/ /恩。维基百科。org /维基/ TF % % 80% 93idf E2

3.5.2 sciki-learn

4.2节。功能提取,scikit-learn用户指 http://scikit-learn.org/stable/modules/feature_extraction.html

sckit-learn特征提取APIhttp://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_ extraction

使用文本数据,scikit-learn Tutorial http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_datahtml


0 条 查看最新 评论

没有评论
暂时无法发表评论