在使用文本数据构建预测模型之前,需要进行特殊准备。首先解析文本以提取单词,这个过程称为词形还原。然后需要将单词编码为整数或浮点值,作为机器学习算法的输入,称为特征提取(或量化)。scikit-learn提供了简单的工具来帮助我们对您的文本数据执行词形还原和特征提取。在本文中,您将学习如何在Python中使用scikit-learn为机器学习准备文本数据。阅读本文后,您将了解:如何使用CountVectorizer将文本转换为词频向量。如何使用TfidfVectorizer提取文本的词权重向量。如何使用HashingVectorizer将文本映射到特征索引。开始吧。当“Bag-of-words”模型使用机器学习算法时,我们不能直接使用文本来进行计算。相反,我们需要将文本转换为数字。当我们想要对文档进行分类时,每个文档都充当“输入”,文档的类标签是我们预测算法的“输出”。该算法只能接受数值向量作为输入,因此需要将文档转换为固定长度的数值向量。在机器学习领域,有一种简单有效的文本文档模型,称为词袋模型,简称BOW。该模型的简单之处在于它丢弃了所有单词中的顺序信息,而主要关注单词在文档中的频率。这可以通过为每个单词分配一个唯一的数字来实现。这样,我们看到的任何文档都可以编码为一个固定长度的向量,即已知单词词汇表的长度。该向量中每个位置的值是编码文档中每个单词出现的次数或频率。这就是“词袋”模型。我们只关心编码方法,文档中出现了哪些词,或者它们在编码后的文档中出现的频率,而不考虑任何关于顺序的信息。这种简单的方法有很多扩展,既可以更好地解释“单词”的含义,也可以定义每个单词在向量中的编码方式。scikit-learn提供了3种不同的方法供我们使用,我们将简要介绍每种方法。CountVectorizer-量化字数CountVectorizer提供了一种简单的方法,不仅可以将文本文档的数据集转换为标记并构建已知单词的词汇表,还可以使用该词汇表对新文本进行编码。使用方法如下:创建一个CountVectorizer类的实例。调用fit()函数从一个或多个文档中学习词汇。将transform()函数应用于一个或多个文档,将每个文档编码为一个向量。编码向量返回整个词汇表的长度,以及每个词在文档中出现的次数。由于这些向量包含许多零值,我们称它们为稀疏向量。Python在scipy.sparse库中提供了一种处理此类稀疏向量的有效方法。调用transform()返回的向量是稀疏向量。您可以将它们转换为numpy数组,这样看起来更直观易懂。这一步可以通过调用toarray()函数来完成。下面是一个使用CountVectorizer来标记化、构建词汇表和编码文档的示例。fromsklearn.feature_extraction.textimportCountVectorizer#文本文档列表text=["Thequickbrownfoxjumpedoverthelazydog."]#构造转换函数vectorizer=CountVectorizer()#词汇表的术语化和建立vectorizer.fit(text)#summaryprint(vectorizer.vocabulary_)#Encodingdocumentvector=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)[[11111112]]重要的是,这种量化方法可用于包含未出现在词汇表中的单词的文档。这些词将被忽略,并且在结果向量中不会给出出现次数。下面是一个使用上述分词器用一个词汇表内的词和一个词汇表外的词对文档进行编码的示例。#Encodeotherdocumentstext2=["thepuppy"]vector=vectorizer.transform(text2)print(vector.toarray())运行例子,展示了编码后的稀疏向量的矩阵形式,可以看出词汇表出现1次,不在词汇表中的词被完全忽略。[[00000001]]编码的向量可以直接用于机器学习算法。TfidfVectorizer-计算单词权重和计算单词出现次数是一个很好的切入点,但它也是一个非常基本的功能。简单计数的一个问题是某些单词(例如“the”)出现的次数太多,以至于它们的计数对于编码向量意义不大。另一种方法是统计词重,目前最好的方法是TF-IDF。这是一个缩写词,代表“TermFrequency–InverseDocumentFrequency”(词频–逆文档频率),代表了一个词对一篇文档的重要性。词频:指给定词在文档中出现的次数。InverseDocumentFrequency:一个词在文档中出现的频率越高,IDF值越低。撇开数学不谈,TF-IDF给出了词的权重,它会标记出更有趣的词,比如只在某个文档中出现频率很高但在所有文档中都不出现的词。TfidfVectorizer可以标记文档、学习词汇和反向文档频率权重,并且可以对新文档进行编码。或者,如果您已经使用CountVectorizer学习了向量,则可以对其使用Tfidftransformer函数,计算逆向文档频率并开始对文档进行编码。同样,对create、fit和transform函数的调用与CountVectorizer相同。下面是使用TfidfVectorizer学习3个小文档的词汇和逆文档频率,并对其中一个文档进行编码的示例。fromsklearn.feature_extraction.textimportTfidfVectorizer#文本文档列表text=["Thequickbrownfoxjumpedoverthelazydog.","Thedog.","Thefox"]#创建转换函数vectorizer=TfidfVectorizer()#Termize并创建词汇vectorizer.fit(text)#Summaryprint(vectorizer.vocabulary_)print(vectorizer.idf_)#编码文档vector=vectorizer.transform([text[0]])#摘要编码文档print(vector.shape)print(vector.toarray())在上面的例子中,我们从文档中学习8个单词的词汇表,每个单词在输出向量中分配一个唯一的整数索引。我们计算了词汇表中每个单词的逆文档频率,将最佳分数1.0分配给最常观察到的单词“the”(索引7)。最后,第一个文档被编码为一个8元素的稀疏矩阵,我们可以查看每个单词的最终权重得分。我们可以看到“the”、“fox”、“dog”的值对应词汇表中的值,其他词有不同的值。{'fox':2,'lazy':4,'dog':1,'quick':6,'the':7,'over':5,'brown':0,'jumped':3}[1.693147181.287682071.287682071.693147181.693147181.693147181.693147181.](1,8)[[0.363886460.276745030.276745030.363886460.363886460.363886460.363886460.42983441]]这些分数被归一化为0到1之间的值,编码的文档向量可以直接用于大多数机器学习算法。HashingVectorizer-哈希量化文本词频和权重是有用的,但是当词汇量变得非常大时,以上两种方法都有局限性。反过来,这将需要巨大的向量来对文档进行编码,需要大量内存并降低算法速度。一种好的方法是使用单向哈希方法将单词转换为整数。优点是这种方法不需要词汇表,可以选择任意长的定长向量。缺点是哈希量化是单向的,因此无法将编码转换回单词(对于许多监督学习任务来说可能并不重要)。HashingVectorizer类实现了此方法,因此它可用于连续散列量化单词,然后根据需要对文档进行分词和编码。下面是在单个文档上使用HashingVectorizer进行编码的示例。我们选择了一个固定长度20的任意向量。这个值对应哈希函数的取值范围,小的值(比如20)可能会造成哈希冲突。在之前的计算机科学课程中,我们介绍了一些启发式算法,根据估计的词汇量大小来选择哈希长度和碰撞概率。请注意,这种量化方法不需要调用函数来拟合训练数据文件。相反,在实例化之后,它可以直接用于对文档进行编码。fromsklearn.feature_extraction.textimportHashingVectorizer#文本文档列表text=["Thequickbrownfoxjumpedoverthelazydog."]#创建转换函数vectorizer=HashingVectorizer(n_features=20)#编码文档vector=vectorizer.transform(text)#摘要编码文档打印(vector.shape)print(vector.toarray())运行示例代码以将示例文档编码为具有20个元素的稀疏矩阵。编码文档的值对应于规范化的字数。默认值介于-1和1之间,但可以修改默认值并将其设置为整数计数值。(1,20)[[0.0.0.0.0.0.333333330.-0.333333330.333333330.0.0.333333330.0.0.-0.333333330.0.-0.666666670.]]深入阅读本节我们为您提供有关本文的一些信息阅读深入的材料。自然语言处理维基百科的“词袋”(Bag-of-words)模型介绍。维基百科“标记化”简介。维基百科“TF-IDF”。scikit-learnscikit-learn手册第4.2节,特征提取。sckit-learn特征提取API。scikit-learn教程:文本数据处理。类APICountVectorizerscikit-learnAPITfidfVectorizerscikit-learnAPITfidfTransformerscikit-learnAPIHashingVectorizerscikit-learnAPI总结在本教程中,您将学习如何使用scikit-learn为机器学习准备文本数据。在这些示例中,我们只触及了表面,我想强调的是,这些类有许多影响文档词形还原结果的设置细节,值得进一步探索。