1.准备安装
安装python
目前我安装的是3.7.4版本。安装必要的依赖库:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple SciPy
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple NumPy
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple joblib安装机器学习库scikit-learn
pip install -U scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple安装过程比较慢的办法解决:
在windows下可以在C:\User\xxxx下新建pip目录,新建文件名为pip.ini
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
linux下~/.pip/pip.conf内容为:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
二 sublime 配置python环境
配置参考:https://www.cnblogs.com/zhaof/p/8126306.html
三 贝叶斯回顾
本来自己已经理解了,再找一题,突然又点模糊了,题目如下:
有一种病x,假设在人群中得病的概率为0.01%即万分之一,有一种检测方法,检测的准确率为99.9%,误报率为0.1%,那么如果有人检测的时候,检测出来是患有x这个病,那么这个人的的病概率是多少?
思考计算过程:
用B+表示得病,用B-表示未的病,用T标识检测出来有病,用F标识未检测出来有病。
条件
得病的概率:P(B+) = 0.01%
未得病的概率:P(B-) = 99.99%
得病情况下,检测到的得病的概率:P(T|B+) = 99.9%
得病情况下,未检测到的得病的概率:P(F|B+) = 0.1%
未得病情况下,检测到的得病的概率:P(T|B-) = 0.1%
未得病情况下,未检测到的得病的概率: P(F|B-) = 99.9%
计算过程
直观计算法:
我们要求的是:P(B+|T) 即在检测得病情况下,真正得病的几率是多少。
我们可以直接思考下,P(B+|T) = 查出且得病人数/查出的总人数
假设总人数为X,那么P(B+|T)= X*0.01%*99.9%(有病且检测出来)/[X*0.01%*99.9%(有病且检测出来)+X*99.9%*0.1%(无病但是检测出有病) = 0.00999%/(0.00999%+0.0999%) 约等于9%。-
贝叶斯计算法:
P(B+|T) = P(T|B+)*P(B+)/P(T)
= 99.9%*0.01%/P(T)
我原来卡在这里面P(T)怎么求,T是标识检测出来得病的概率,这个怎么算。
其实可以这样想,P(T)概率有两部分组成,一是有病检测出来的概率+无病检测出来的概率
所以P(T) = 0.01%*99.9%+ 99.9%*0.1%
和上面一样了。
所以可以得到更普遍的贝叶斯公式:
贝叶斯公式
通用的贝叶斯公式
对照下图公式更好理解:
四 .朴素贝叶斯实战
在机器学习领域,一般都是获取数据集合,然后对数据进行可视化和基础的探测,接着选择特征向量,对数据进行预处理,然后训练模型,测试模型的准确率,最后使用模型来预测数据执行结果。
我们这次用Sklearn进行测试,这个是非常简单好用的机器学习库,对于朴素贝叶斯分类算法,分为三个,分别为高斯朴素贝叶斯,多项式朴素贝叶斯,伯努利朴素贝叶斯。
高斯朴素贝叶斯: 特征变量是连续变量,符合高斯分布,比如高考成绩,身高等。
多项式贝叶斯:特征变量是离散的,符合多项式分布,在文档中特征表现为单词的TF-IDF等。
伯努利朴素贝叶斯:特征变量为0或1,这种布尔变量。
伯努利朴素贝叶斯以文件为粒度,如果单词在文件中出现为1,不出现为0,多项式贝叶斯会计算单词在文件中出现的具体次数。高斯贝叶斯,适合特征变量为连续的,且是符合正态分布的数据。
实战准备
对于垃圾邮件来说,是个二分类的问题,我们判断每个单词在垃圾邮件中的概率,在正常邮件中的概率,然后再结合先验概率,求得特定一段邮件文本下的此邮件是垃圾邮件的可能性。
这时候可能会发现误判率应该还是比较高,原因是什么那?因为每个词其实在判断垃圾邮件的重要程度是不一样的,有的可能更重要,有的可能不重要;什么样的词更重要,更能够代表整个邮件的属性那,可以用以前的TF-IDF作为特征替代词的频率,这个在以前的文档相似度算法中有过基本的描述,文档相似度通过单词间的TF-IDF来经过复杂的公式来比对。
TF: 即Trem Frequency 即单词在一个文档中出现的次数;
IDF: Inverse Document Frequency 即逆向文档频率,标识的是在多少个文档中出现单词的倒数。
TF: 标识的是这个单词可以代表的文档的程度;IDF:标识的是这个单词本身的重要性,如果在越多文档中包含这个词,这个词的重要性也就越低。
TF-IDF = TF*IDF
IDF计算过程中+1防止出现次数为0,用log我像是为了让取值范围更小一些。
代码
# -*- coding: utf-8 -*-
import os
import jieba
import warnings
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
warnings.filterwarnings('ignore')
def cut_words(one_dir,label):
'''
:param one_dir 一类文件比如体育等
return 一类的所有词语
'''
tmp_words = ''
one_labels = []
one_words = []
for one_file in os.listdir(one_dir):
real_name = one_dir +'\\'+one_file
text = open(real_name, 'r', encoding='gb18030').read()
words = jieba.cut(text)
for one in words:
tmp_words += one + ' '
one_words.append(tmp_words)
one_labels.append(label)
tmp_words = ''
return one_words,one_labels
def get_data_label(file_path):
all_class_words = []
all_class_labels = []
for dir_name in os.listdir(file_path):
one_dir = file_path+'\\'+dir_name
words, labels = cut_words(one_dir,dir_name)
all_class_words.extend(words)
all_class_labels.extend(labels)
return all_class_words,all_class_labels
if __name__== "__main__":
org_path = 'E:\\python\\PythonCode\\text_classification-master\\text classification'
file_path = org_path+ '\\train'
#1.提取词语
all_train_words,all_train_label = get_data_label(file_path)
all_test_words,all_test_label = get_data_label(org_path+'\\test')
#print(len(all_train_words))
#print(all_train_label[0])
#2.根据词语生成tf-idf
stop_words = open(org_path+ '\\stop\\stopword.txt', 'r', encoding='utf-8').read()
stop_words = stop_words.encode('utf-8').decode('utf-8-sig') # 列表头部\ufeff处理
stop_words = stop_words.split('\n') # 根据分隔符分隔
# 计算单词权重 词在文档中出现频率大于60%就删除不计算
# td-idf 计算的时候是一串单词
tf = TfidfVectorizer(stop_words=stop_words, max_df=0.6)
train_features = tf.fit_transform(all_train_words)
# 上面fit过了,这里transform
test_features = tf.transform(all_test_words)
#3. 多项式贝叶斯分类器训练
from sklearn.naive_bayes import MultinomialNB
#alpha 做平滑处理,不是所有的词都出现,所以原来为0 的改下,改成非零,越小越精确计算越慢
clf = MultinomialNB(alpha=0.0001).fit(train_features, all_train_label)
#4.预测
predicted_labels=clf.predict(test_features)
#5. 计算准确率
print('准确率为:', metrics.accuracy_score(all_test_label, predicted_labels))
说明:
1)词的TF-IDF计算需要多篇文档,这样可以求出IDF,即类似词的权重的概念。
2)TfidfVectorizer计算的时候需要传入的是空格分割的多个单词。
3)TF-IDF实际上相当于一个词语的信息量。
参考:
垃圾邮件分类处理:https://blog.csdn.net/loveliuzz/article/details/78827741
朴素贝叶斯:https://blog.csdn.net/sinat_30353259/article/details/80932111
一些预处理函数说明:https://blog.csdn.net/anshuai_aw1/article/details/82498374
skearn预处理:https://blog.csdn.net/wang1127248268/article/details/53264041
均差方差理解:https://blog.csdn.net/u013066730/article/details/83029619