本特征提取:将文本数据转化成特征向量的过程,比较常用的文本特征表示法为词袋法
词袋法:不考虑词语出现的顺序,每个出现过的词汇单独作为一列特征,这些不重复的特征词汇集合为词表,每一个文本都可以在很长的词表上统计出一个很多列的特征向量, 如果每个文本都出现的词汇,一般被标记为 停用词 不计入特征向量。
主要有两个api来实现 CountVectorizer 和 TfidfVectorizer
CountVectorizer:只考虑词汇在文本中出现的频率,属于词袋模型特征。
TfidfVectorizer: 除了考量某词汇在文本出现的频率,还关注包含这个词汇的所有文本的数量。能够削减高频没有意义的词汇出现带来的影响, 挖掘更有意义的特征。属于Tfidf特征。
相比之下,文本条目越多,Tfid的效果会越显著
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
相关属性:
简单实例入门:
# -*- 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]
什么是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