前言

本文以jieba给中文分词之后再用CountVectorizer提取特征不足之处为引例,用了一种更加合理的文本抽取方法tf-idf(TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency))

一、jieba分词中文后再用CountVectorizer提取特征有何不妥?

1先用jieba给一个中文str组成的list分词 #2将分好词之后的中文str组成的list用CountVectorizer提取特征

#1先用jieba给一个中文str组成的list分词
import jieba#先导包

#有3句话str在一个list里面
data=[  '燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候',
        '但是,聪明的,你告诉我,我们的日子为什么一去不复返呢?',
        '是有人偷了他 们罢:那是谁?又藏在何处呢?是他们自己逃走了罢——如今又到了哪里呢?'
    ]
#先遍历list里的str并用分好词
data_new=[]#先用一个空列表准备接收,待会儿把分好词的str放进来
for text in data:
    data_new.append(' '.join(list(jieba.cut(text))))
print(data_new)

#2将分好词之后的中文str组成的list用CountVectorizer提取特征
from sklearn.feature_extraction.text import CountVectorizer
#“将这个data_new分好词的str组成的list用CountVectorizer提取一下特征”
#实例化一个CountVectorizer 停用一下几个字
transfer=CountVectorizer(stop_words=['了','的','呢'])
#将data_new喂入实例化好的transfer的fit-transform()方法之中
cvt_data_new=transfer.fit_transform(data_new)#此时返回一个sparse稀疏矩阵
print('看一下cvt_data_new的值:\n{}'.format(cvt_data_new))
print('看一下cvt_data_new的类型:{}'.format(type(cvt_data_new)))
print("特征名字:{}".format(transfer.get_feature_names()))
print('看一下cvt_data_new的shape:{}'.format(cvt_data_new.shape))
#将sparse矩阵转换成数组,统计每一个样本出现的特征值的个数
print('cvt_data_new转换成数组:\n{}'.format(cvt_data_new.toarray()))

程序运行结果如下:
在这里插入图片描述
运行结果分析:一般认为数值更大的影响更大,比如上图中“时候”这个在稀疏矩阵中数值最大,出现了3次。如果按照这种分类的话,“时候”这个词语对分类产生的影响很大。这3句话来自朱自清《春》,显然3句话当中,“时候”的影响力不是最关键的。本文还用stop_words已经去掉’了’、’的‘、‘呢’,要是不去掉,这些词影响力会更大。所以,单单按照出现频次的方法来抽取文本特征的方法也是不尽善尽美的。
这样会造成一些常用的字词比如“我们”、“你们”、”所以“、”来“、”去“等占用的影响力很大,这对实际的文本分类来说,不太妥当。下文是另一种更合适文本分类的特征抽取方法:TF-IDF(term frequency–inverse document frequency)

二、TfidfVectorizer

1.TFIDF原理

TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。数学公式如下图:
在这里插入图片描述
举个栗子,如下图:
在这里插入图片描述
再举个栗子,如下图:
在这里插入图片描述

2.TfidfVectorizer()使用

sklearn官网API:
https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer
截张图如下:
在这里插入图片描述
用红框标记了我觉得比较常用的两个参数。

使用举例

#1先用jieba给一个中文str组成的list分词 #2将分好词之后的中文str组成的list用TfidfVectorizer提取特征

#1先用jieba给一个中文str组成的list分词
import jieba#先导包

#有3句话str在一个list里面
data=[  '燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候',
        '但是,聪明的,你告诉我,我们的日子为什么一去不复返呢?',
        '是有人偷了他 们罢:那是谁?又藏在何处呢?是他们自己逃走了罢——如今又到了哪里呢?'
    ]
#先遍历list里的str并用分好词
data_new=[]#先用一个空列表准备接收,待会儿把分好词的str放进来
for text in data:
    data_new.append(' '.join(list(jieba.cut(text))))
print(data_new)

[‘燕子 去 了 , 有 再 来 的 时候 ; 杨柳 枯 了 , 有 再 青 的 时候 ; 桃花 谢 了 , 有 再 开 的 时候’, ‘但是 , 聪明 的 , 你 告诉 我 , 我们 的 日子 为什么 一去不复返 呢 ?’, ‘是 有人 偷 了 他 们 罢 : 那 是 谁 ? 又 藏 在 何处 呢 ? 是 他们 自己 逃走 了 罢 — — 如今 又 到 了 哪里 呢 ?’]

#2将分好词之后的中文str组成的list用TfidfVectorizer提取特征
from sklearn.feature_extraction.text import TfidfVectorizer
#“将这个data_new分好词的str组成的list用TfidfVectorizer提取一下特征”
#实例化一个TfidfVectorizer 停用一下几个字
transfer=TfidfVectorizer(stop_words=['了','的','呢'])
#将data_new喂入实例化好的transfer的fit-transform()方法之中
cvt_data_new=transfer.fit_transform(data_new)#此时返回一个sparse稀疏矩阵
print('看一下cvt_data_new的值:\n{}'.format(cvt_data_new))
print('看一下cvt_data_new的类型:{}'.format(type(cvt_data_new)))
print("特征名字:{}".format(transfer.get_feature_names()))
print('看一下cvt_data_new的shape:{}'.format(cvt_data_new.shape))
#将sparse矩阵转换成数组,统计每一个样本出现的特征值的个数
print('cvt_data_new转换成数组:\n{}'.format(cvt_data_new.toarray()))

在这里插入图片描述

#将sparse矩阵转换成数组,统计每一个样本出现的特征值的个数
print('cvt_data_new转换成数组:\n{}'.format(cvt_data_new.toarray()))

在这里插入图片描述

总结

本文讲了一下TF-IDF原理及怎么使用。(如果您发现我写的有错误,欢迎在评论区批评指正)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐