Sklearn中CountVectorizer,TfidfVectorizer详解

本特征提取:将文本数据转化成特征向量的过程,比较常用的文本特征表示法为词袋法
词袋法:不考虑词语出现的顺序,每个出现过的词汇单独作为一列特征,这些不重复的特征词汇集合为词表,每一个文本都可以在很长的词表上统计出一个很多列的特征向量, 如果每个文本都出现的词汇,一般被标记为 停用词 不计入特征向量。
    
主要有两个api来实现 CountVectorizer 和 TfidfVectorizer
CountVectorizer:只考虑词汇在文本中出现的频率,属于词袋模型特征
TfidfVectorizer: 除了考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量。能够削减高频没有意义的词汇出现带来的影响, 挖掘更有意义的特征。属于Tfidf特征。

相比之下,文本条目越多,Tfid的效果会越显著

CountVectorize:

CountVectorizer是属于常见的特征数值计算类,是一个文本特征提取方法。对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的频率。

CountVectorizer会将文本中的词语转换为词频矩阵,它通过fit_transform函数计算各个词语出现的次数。


CountVectorizer参数详解

CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',
        tokenizer=None, vocabulary=None)

CountVectorizer类的参数很多,分为三个处理步骤:preprocessing、tokenizing、n-grams generation.

一般要设置的参数是:ngram_range,max_df,min_df,max_features,analyzer,stop_words,token_pattern等,具体情况具体分析

ngram_range:例如ngram_range(min,max),是指将text分成min,min+1,min+2,.........max 个不同的词组。比如 '我 爱 中国' 中ngram_range(1,3)之后可得到'我'  '爱'  '中国'  '我 爱'  '爱 中国' 和'我 爱 中国',如果是ngram_range (1,1) 则只能得到单个单词'我'  '爱'和'中国'。

max_df:可以设置为范围在[0.0 1.0]的float,也可以设置为没有范围限制的int,默认为1.0。这个参数的作用是作为一个阈值,当构造语料库的关键词集的时候,如果某个词的document frequence大于max_df,这个词不会被当作关键词。如果这个参数是float,则表示词出现的次数与语料库文档数的百分比,如果是int,则表示词出现的次数。如果参数中已经给定了vocabulary,则这个参数无效。
min_df:类似于max_df,不同之处在于如果某个词的document frequence小于min_df,则这个词不会被当作关键词。

max_features:默认为None,可设为int,对所有关键词的term frequency进行降序排序,只取前max_features个作为关键词集。

analyzer:一般使用默认,可设置为string类型,如’word’, ‘char’, ‘char_wb’,还可设置为callable类型,比如函数是一个callable类型。

stop_words:设置停用词,设为english将使用内置的英语停用词,设为一个list可自定义停用词,设为None不使用停用词,设为None且max_df∈[0.7, 1.0)将自动根据当前的语料库建立停用词表。

token_pattern:过滤规则,表示token的正则表达式,需要设置analyzer == ‘word’,默认的正则表达式选择2个及以上的字母或数字作为token,标点符号默认当作token分隔符,而不会被当作token。

decode_error:默认为strict,遇到不能解码的字符将报UnicodeDecodeError错误,设为ignore将会忽略解码错误,还可以设为replace,作用尚不明确。

binary:默认为False,一个关键词在一篇文档中可能出现n次,如果binary=True,非零的n将全部置为1,这对需要布尔值输入的离散概率模型的有用的。

其他参数详细参考:https://blog.csdn.net/weixin_38278334/article/details/82320307

相关属性:

Sklearn中CountVectorizer,TfidfVectorizer详解_第1张图片

简单实例入门:

# -*- coding: utf-8 -*-
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['我 爱 中国 中国','爸爸 妈妈 爱 我','爸爸 妈妈 爱 中国']
# corpus = ['我爱中国','爸爸妈妈爱我','爸爸妈妈爱中国']
vectorizer = CountVectorizer(min_df=1, ngram_range=(1, 1)) ##创建词袋数据结构,里面相应参数设置
features = vectorizer.fit_transform(corpus)  #拟合模型,并返回文本矩阵

print("CountVectorizer:")
print(vectorizer.get_feature_names())   #显示所有文本的词汇,列表类型
print(vectorizer.vocabulary_)    #词汇表,字典类型
print(features)   #文本矩阵
print(features.toarray())   #.toarray() 是将结果转化为稀疏矩阵
print(features.toarray().sum(axis=0)) #统计每个词在所有文档中的词频

CountVectorizer 结果依次为:

#词表
['中国', '妈妈', '爸爸']  

#key:词,value:对应编号
{'中国': 0, '爸爸': 2, '妈妈': 1}  

#第一行 (0, 0)	2 表示为:第0个列表元素,**词典中索引为0的元素**, 词频为2
  (0, 0)	2       
  (1, 1)	1
  (1, 2)	1
  (2, 1)	1
  (2, 2)	1
  (2, 0)	1

#将结果转化为稀疏矩阵
[[2 0 0]
 [0 1 1]
 [1 1 1]]

#文本中的词频
[3 2 2]

 

TfidfVectorizer:

什么是TF-IDF

TF-IDF(term frequency-inverse document frequency)词频-逆向文件频率。在处理文本时,如何将文字转化为模型可以处理的向量呢?TF-IDF就是这个问题的解决方案之一。字词的重要性与其在文本中出现的频率成正比(TF),与其在语料库中出现的频率成反比(IDF)。

TF为某个词在文章中出现的总次数。为了消除不同文章大小之间的差异,便于不同文章之间的比较,我们在此标准化词频:TF = 某个词在文章中出现的总次数/文章的总词数。

IDF为逆文档频率。逆文档频率(IDF) = log(词料库的文档总数/包含该词的文档数+1)。

为了避免分母为0,所以在分母上加1。

TF-IDF值 = TF * IDF。

相关参数:

TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), norm='l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents=None, sublinear_tf=False,
        token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
        vocabulary=None)

具体参数详解可以参考上面的CountVectorizer参数,大多数是一样的。具体详细参数详解参考:https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html

简单入门实例,可以和CountVectorizer结果对比一下:

# -*- coding: utf-8 -*-
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['我 爱 中国 中国','爸爸 妈妈 爱 我','爸爸 妈妈 爱 中国']
# corpus = ['我爱中国','爸爸妈妈爱我','爸爸妈妈爱中国']

print("TfidfVectorizer:")
vectorizer = TfidfVectorizer(min_df=1,
                                 norm='l2',
                                 smooth_idf=True,
                                 use_idf=True,
                                 ngram_range=(1, 1))
features = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())   #显示所有文本的词汇,列表类型
print(vectorizer.vocabulary_)    #词汇表,字典类型
print(features)   #文本矩阵,得到tf-idf矩阵,稀疏矩阵表示法
print(features.shape)  #(3, 3)
print(features.toarray())   #.toarray() 是将结果转化为稀疏矩阵
print(features.toarray().sum(axis=0)) #统计每个词在所有文档中的词频

TfidfVectorizer  结果依次为:

TfidfVectorizer:
['中国', '妈妈', '爸爸']

{'中国': 0, '爸爸': 2, '妈妈': 1}

  (0, 0)	1.0                #得到tf-idf矩阵,稀疏矩阵表示法
  (1, 2)	0.7071067811865476
  (1, 1)	0.7071067811865476
  (2, 0)	0.5773502691896257
  (2, 2)	0.5773502691896257
  (2, 1)	0.5773502691896257

(3, 3)

[[1.         0.         0.        ]
 [0.         0.70710678 0.70710678]
 [0.57735027 0.57735027 0.57735027]]

[1.57735027 1.28445705 1.28445705]

可以看到:"我" “爱”这两个单字是没有的,主要是参数token_pattern默认正则匹配字数是大于2的,如果想保留需重新设置一下,参考链接中第三步:https://blog.csdn.net/blmoistawinde/article/details/80816179

 

参考链接:https://blog.csdn.net/weixin_38278334/article/details/82320307

                    https://www.jianshu.com/p/c39feaf0d62f

                    https://www.cnblogs.com/Lin-Yi/p/8974108.html

你可能感兴趣的:(机器学习)