使用Scikit-learn的CountVectorizer()函数初始化词袋模型时,设置不同的特征个数生成邮件的特征表示向量,比较训练分类模型所耗费的时间,以及分类模型分类的准确性。特征个数越多是否意味分类性能越好?
数据集为mailcorpus.txt
词袋模型(英语:Bag-of-words model)是个在自然语言处理和信息检索(IR)下被简化的表达模型。此模型下,一段文本(比如一个句子或是一个文档)可以用一个装着这些词的袋子来表示,这种表示方式不考虑文法以及词的顺序。词袋模型本质是一种用机器学习算法对文本进行建模时表示文本数据的方法,也是 ngram 中的 unigram。
词袋模型的三部曲
中文文本需要进行分词处理,这里用英文语料,极大地简化分词步骤。调用 scikit-learn 的 CountVectorizer 类来进行文本的词频统计与向量化。
from sklearn.feature_extraction.text import CountVectorizer
vectorizer=CountVectorizer()
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
调用相关函数查看 CountVectorizer 类怎样进行词频统计和向量化
Learn the vocabulary dictionary and return term-document matrix.
学习词典并且返回文档中的词对应的词向量矩阵
所有词组成一个向量,每个位置的数字表示这个位置对应的单词在这句话中出现的次数
从索引值到特征名(每个单词)的映射
print(vectorizer.fit_transform(corpus))
# 部分结果
# (0, 4) 1 # 0表示第一个文档,4表示come的索引,1表示出现的次数(I为停用词)
# (0, 15) 2 # 0表示第一个文档,15表示to的索引,2表示出现的次数(I为停用词)
# (0, 3) 1
# (0, 16) 1
print(vectorizer.fit_transform(corpus).toarray())
[[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0] # 从下面可以看出 come 对应索引位置为4上的'1'
[0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
[1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]
print(vectorizer.get_feature_names())
['and', 'apple', 'car', 'china', 'come', 'in', 'is', 'love', 'papers', 'polupar', 'science', 'some', 'tea', 'the', 'this', 'to', 'travel', 'work', 'write']
可以看到我们一共有19个词,所以4个文本都是19维的特征向量。而每一维的向量依次对应了下面的19个词。另外由于词"I"在英文中是停用词,不参加词频的统计。
由于大部分的文本都只会使用词汇表中的很少一部分的词,因此我们的词向量中会有大量的0。也就是说词向量是稀疏的。在实际应用中一般使用稀疏矩阵来存储。