正文
本篇是贝叶斯算法的项目实战
如果你还不知道贝叶斯算法,你可以选择再次和韩梅梅同学
一起边吃火锅边学习贝叶斯
- 大话系列 | 贝叶斯(上)—下雨天吃什么?
今天的项目会利用贝叶斯算法实现新闻的分类,数据集和相关代码都在文末。
文本分类需要用到分词的思想,文中会略略提到,主要目的是熟悉算法的应用。
ok,直接开始
在sklearn 中提供的贝叶斯分类算法有三种,分别是:高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)
先来看一下这三种算法的区别:
高斯分布:
高斯分布又叫正态分布,我们把一个随机变量 X服从数学期望为μ,方差为σ^2 的数据分布称为正态分布,当μ=0,σ=1是称为标准 正态分布(对应红色的线)
伯努利分布:
又称零一分布,是多重伯努利实验的概率分布。
多项式分布:
是二项分布的推广,二项分布是随机结果只有两个取值,多项式分布式指随机结果有多个取值
多项式朴素贝叶斯和伯努利朴素贝叶斯常用在文本分类问题中,高斯朴素贝叶斯主要用于连续变量中,且假设连续变量是服从正态分布的。
有关文本分类
今天的实战项目是针对新闻数据进行分类,说更直白点,就是文本分类
在文本分类的过程中,有一个很重要的内容:如何将普通的文本转换为计算机可以识别的向量
这里用到一个叫做TF-IDF的方法,先解释一下这个内容
TF-IDF 是一个统计方法,用来评估某个词语对于一个文件集或文档库中的其中一份文件的重要程度。
TF-IDF 由Term Frequency(词频)和Inverse Document Frequency(逆向文档频率)组成。即TF-IDF=TF*IDF
词频TF:
计算一个单词在文档中出现的次数,单词的重要性和TF成正比
逆向文档概率IDF:
指一个单词在文档中的区分度。如果一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。即IDF越大单词的区分度越大
分母 1是因为有些单词不会存在在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1
所以,TF和IDF越高的单词越适合分类,也就是在一个文档中出现次数较多,同时又很少出现在其他文档中的单词,适合进行分类
开始实战
先来说说这次实战项目的相关背景
目前我们有部分新浪新闻数据,其中包括财经、IT、健康等等新闻类别,每个类别有若干篇新闻报道
我们的任务是预测新闻的类别
为了方便进行分词,我们还有一个停用词表
什么是停用词呢?
停用词是指在分类中没有用的词,这类词一般出现的频率TF很高,但是并不能很好的区分不同的文章(IDF低),例如“你、我、他”、一些介词、连接词等
读取数据
读取数据,将每一个新闻文本和其对应的新闻类别进行对应
为了方便下一步进行分词,这里直接将数据存储在字典中
最终结构化的数据是这样的
数据分词
针对每个新闻,我们这里直接使用结巴进行分词
使用结巴分词,需要提前安装jieba 这个包,win下直接pip install 即可
分词后的数据集是这样的
一共88条新闻,好像看的不是很清楚,我们拎出来第一条新闻仔细看下是如何分词的
计算每个单词的权重
在sklearn 中直接使用 TfidfVectorizer类可以用来计算词的TF-IDF值
在这里面,我们可以传入停用词表,并且设置参数max_df
max_df代表单词在所有文档中出现的概率,如果这个概率很大,就说明这个词的区分度很小,一般不会用来作分词统计
代码语言:javascript复制"""使用停用词"""
list_stop_words = df_stop_words['stop_words'].to_list()
tfidf_vec = TfidfVectorizer(stop_words=list_stop_words, max_df=0.5)
因为我们前面是对整个数据集进行操作,所在在这一步需要将数据集进行拆分,然后再计算词的TF-IDF值
代码语言:javascript复制# 切分数据集
X_train, X_test, y_train, y_test = train_test_split(data['cut_content'], data['label'], test_size=0.2)
# 计算权重
X_train_features = tfidf_vec.fit_transform(X_train)
X_test_features = tfidf_vec.transform(X_test)
建立模型
在文章的开始说到了三种朴素贝叶斯的分类算法,针对新闻数据集,很明显是一个多分类问题,所有我们选用多项式朴素贝叶斯
多项式朴素贝叶斯假设特征的先验概率为多项式分布,即:
即第k 个类别的第j 维特征的第l 个取值条件概率。mk是训练集中输出为第k 类的样本个数。
λ为一个大于0的常数,当训练样本很大的时候,加1的概率变化可以忽略,也同时避免了零概率的问题
对了,三种算法,各自有其不同的参数
多项式朴素贝叶斯有一个参数需要特别注意:alpha
- 当 alpha=1 时,使用的是 Laplace 平滑
- 当 0<alpha<1 时,使用的是 Lidstone 平滑
对于 Lidstone 平滑来说,alpha 越小,迭代次数越多,精度越高
ok,那我们直接进行建模
代码语言:javascript复制"""建立模型并进行训练"""
# 使用多项式朴素贝叶斯进行预测
clf = MultinomialNB(alpha=0.001).fit(X_train_features, y_train)
predict_label = clf.predict(X_test_features)
# 计算准确率
print('准确率为:', accuracy_score(y_test, predict_label))
贝叶斯模型的方法和其他模型是一样的
最终的计算结果是这样的
好了,今天的项目就到这了