作文本分类等问题的时,须要从大量语料中提取特征,并将这些文本特征变换为数值特征。经常使用的有词袋模型和TF-IDF 模型html
词袋模型是最原始的一类特征集,忽略掉了文本的语法和语序,用一组无序的单词序列来表达一段文字或者一个文档。能够这样理解,把整个文档集的全部出现的词都丢进袋子里面,而后无序的排出来(去掉重复的)。对每个文档,按照词语出现的次数来表示文档。python
句子1:我/有/一个/苹果数组
句子2:我/明天/去/一个/地方this
把全部词丢进一个袋子:我,有,一个,苹果,明天,去,地方。spa
如今咱们创建一个无序列表:我,有,一个,苹果,明天,去,地方并根据每一个句子中词语出现的次数来表示每一个句子。3d
这样的一种特征表示,咱们就称之为词袋模型的特征。code
这种模型主要是用词汇的统计特征来做为特征集。TF-IDF 由两部分组成:TF(Term frequency,词频),IDF(Inverse document frequency,逆文档频率)两部分组成。IDF反映的是一个词能将当前文本与其它文本区分开的能力orm
TF:xml
其中分子 nij表示词 ii在文档 j 中出现的频次。分母则是全部词频次的总和,也就是全部词的个数。htm
举个例子:
句子1:上帝/是/一个/女孩
句子2:桌子/上/有/一个/苹果
每一个句子中词语的 TF :
IDF:
其中 |D|表明文档的总数,分母部分 |Di|则是表明文档集中含有 i 词的文档数。原始公式是分母没有 +1 的,这里 +1 是采用了拉普拉斯平滑,避免了有部分新的词没有在语料库中出现而致使分母为零的状况出现。
最后,把 TF 和 IDF 两个值相乘就能够获得 TF-IDF 的值。即:
把每一个句子中每一个词的 TF-IDF 值 添加到向量表示出来就是每一个句子的 TF-IDF 特征。
在 Python 当中,咱们能够经过 scikit-learn 来分别实现词袋模型以及 TF-IDF 模型。而且,使用 scikit-learn 库将会很是简单。这里要用到 CountVectorizer()
类以及 TfidfVectorizer()
类。
看一下两个类的参数:
#词袋 sklearn.featur_extraction.text.CountVectorizer(min_df=1, ngram_range=(1,1))
min_df
:忽略掉词频严格低于定阈值的词ngram_range
:将 text 分红 n1,n1+1,……,n2个不一样的词组。好比好比'Python is useful'中ngram_range(1,3)以后可获得 'Python' , 'is' , 'useful' , 'Python is' , 'is useful' , 'Python is useful'。若是是ngram_range (1,1) 则只能获得单个单词'Python' , 'is' , 'useful'。#Tf-idf sklearn.feature_extraction.text.TfidfVectorizer(min_df=1,norm='l2',smooth_idf=True,use_idf=True,ngram_range=(1,1))
min_df
: 忽略掉词频严格低于定阈值的词。norm
:标准化词条向量所用的规范。smooth_idf
:添加一个平滑 idf 权重,即 idf 的分母是否使用平滑,防止0权重的出现。use_idf
: 启用 idf 逆文档频率从新加权。ngram_range
:同词袋模型python代码实现:
词袋:
from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer(min_df=1, ngram_range=(1, 1)) #创建文本库 corpus = ['This is the first document.', 'This is the second second document.', 'And the third one.', 'Is this the first document?'] #训练数据 corpus 得到词袋特征 a = vectorizer.fit_transform(corpus) #查看词的排列形式 vectorizer.get_feature_names() a.toarray()
tf-idf
from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer( min_df=1, norm='l2', smooth_idf=True, use_idf=True, ngram_range=(1, 1)) #用 TF-IDF 类去训练上面同一个 corpus b = vectorizer.fit_transform(corpus)
须要注意的是 b
这个特征矩阵是以稀疏矩阵的形式存在的,使用 Compressed Row Storage 格式存储,也就是这个特征矩阵的信息是被压缩了。
为何要这么作呢?由于在实际运用是文本数据量是很是大的,若是完整的存储会消耗大量的内存,所以会将其压缩存储。可是仍然能够像 numpy 数组同样取特征矩阵中的数据。