词袋模型
词袋模型(英语:Bag-of-words model)是个在自然语言处理和信息检索(IR)下被简化的表达模型。此模型下,一段文本(比如一个句子或是一个文档)可以用一个装着这些词的袋子来表示,这种表示方式不考虑文法以及词的顺序。词袋模型本质是一种用机器学习算法对文本进行建模时表示文本数据的方法,也是 ngram 中的 unigram。
词袋模型的三部曲
- 分词(tokenizing)
- 统计修订词特征值(counting)
- 标准化(normalizing)
中文文本需要进行分词处理,这里用英文语料,极大地简化分词步骤。调用 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 类怎样进行词频统计和向量化
- vectorizer.fit_transform(corpus)
Learn the vocabulary dictionary and return term-document matrix.
学习词典并且返回文档中的词对应的词向量矩阵
- vectorizer.fit_transform(corpus).toarray()
所有词组成一个向量,每个位置的数字表示这个位置对应的单词在这句话中出现的次数
- vectorizer.get_feature_names()
从索引值到特征名(每个单词)的映射
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。也就是说词向量是稀疏的。在实际应用中一般使用稀疏矩阵来存储。
sklearn CountVectorizer 详解
CountVectorizer 是属于常见的特征数值计算类,是一个文本特征提取方法。对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的频率。
CountVectorizer 会将文本中的词语转换为词频矩阵,它通过 fit_transform 函数计算各个词语出现的次数。
CountVectorizer 可以接收的参数如上图所示,主要说明几个需要设置的重要参数
参数表 | 作用 |
---|---|
ngram_range | 词组切分的长度范围 |
max_df | 可以设置为范围在[0.0 1.0]的float,也可以设置为没有范围限制的int,默认为1.0。 |
min_df | 类似于max_df,不同之处在于如果某个词的document frequence小于min_df,则这个词不会被当作关键词 |
stop_words | 设置停用词,设为english将使用内置的英语停用词,设为一个list可自定义停用词,设为None不使用停用词,设为None且max_df∈[0.7, 1.0)将自动根据当前的语料库建立停用词表 |
- ngram_range
ngram_range(m,n) 中保证 m 小于 n。m 和 n 的值表示切分的长度
# 2-gram
vectorizer = CountVectorizer(ngram_range=(1,2))
vectorizer.fit_transform(["an apple a day keeps the doctor away"])
print(vectorizer.get_feature_names())
# ['an', 'an apple', 'apple', 'apple day', 'away', 'day', 'day keeps', 'doctor', 'doctor away', 'keeps', 'keeps the', 'the', 'the doctor']
# 3-gram
vectorizer = CountVectorizer(ngram_range=(1,3))
vectorizer.fit_transform(["an apple a day keeps the doctor away"])
print(vectorizer.get_feature_names())
# ['an', 'an apple', 'an apple day', 'apple', 'apple day', 'apple day keeps', 'away', 'day', 'day keeps', 'day keeps the', 'doctor', 'doctor away', 'keeps', 'keeps the', 'keeps the doctor', 'the', 'the doctor', 'the doctor away']
- max_df
int 类型时如果一个词在文档中出现的次数大于设定值则忽视这个词(过多可能表明这个词没有价值),float 类型时表示词出现的次数(一个文档中最多计一次)与语料库文档数的百分比
参考链接