当前位置:   article > 正文

python_sklearn机器学习算法系列之sklearn.naive_bayes朴树贝叶斯算法_应用sklean中自带数据集(可选其中之一)用python实现朴素贝叶斯算法

应用sklean中自带数据集(可选其中之一)用python实现朴素贝叶斯算法

       本文主要目的是通过一段及其简单的小程序来快速学习python 中sklearn的naive_bayes这一模块的基本操作和使用,注意不是用python纯粹从头到尾自己构建贝叶斯算法,既然sklearn提供了现成的我们直接拿来用就可以了,当然其原理十分重要,这里做一下简单介绍:

P(A|B)=P(A)×P(B|A)/P(B)
用文字表述:后验概率=先验概率×相似度/标准化常量
朴素贝叶斯算法要解决的问题就是如何求出相似度即:P(B|A)的值[属性/特征]

所谓朴素就是假设属性之间相互独立即P(B|A)=P(B1|A)P(B2|A)P(B3|A)P(B4|A)

scikit-learn根据不同场景提供了三种常用的朴素贝叶斯算法:
如果样本特征的分布大部分是连续值,使用GaussianNB会比较好。
如果样本特征的分大部分是多元离散值,使用MultinomialNB比较合适。例如文本分类单词统计,以出现的次数作为特征值,https://www.jianshu.com/p/845b16559431
如果样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。

三种算法的详细讲解见https://www.cnblogs.com/pinard/p/6074222.html

好了直接看代码(其中都有详细的注释)

GaussianNB:

  1. #GaussianNB(高斯)类
  2. from sklearn import datasets
  3. from sklearn.naive_bayes import GaussianNB
  4. import numpy as np
  5. iris=datasets.load_iris()
  6. #核心代码:其实fit后面还有一个参数即fit(X, y, sample_weight=None),sample_weight表各样本权重数组,假如一共训练8个样本
  7. #则可以写为clf.fit(iris.data[:8], iris.target[:8],sample_weight=np.array([0.05,0.05,0.1,0.1,0.1,0.2,0.2,0.2]))
  8. clf=GaussianNB()
  9. clf.fit(iris.data,iris.target)
  10. '''
  11. #GaussianNB一个重要的功能是有 partial_fit方法,这个方法的一般用在如果训练集数据量非常大,一次不能全部载入
  12. #内存的时候。这时我们可以把训练集分成若干等分,重复调用partial_fit来一步步的学习训练集,非常方便
  13. #在第一次调用partial_fit函数时,必须制定classes参数,在随后的调用可以忽略
  14. clf.partial_fit(iris.data, iris.target,classes=[0,1,2])
  15. '''
  16. #学习后模型中的一些参数
  17. clf.set_params(priors=[0.333, 0.333, 0.333])#这里要设一下各个类标记对应的先验概率,如果不设置直接clf.priors返回的是None(不知道为什么?)
  18. print(clf.priors) #获取各个类标记对应的先验概率
  19. print(clf.class_prior_ ) #同priors一样,都是获取各个类标记对应的先验概率,区别在于priors属性返回列表,class_prior_返回的是数组
  20. print(clf.get_params(deep=True)) #返回priors与其参数值组成字典
  21. print(clf.class_count_) #获取各类标记对应的训练样本数
  22. print(clf.theta_) #获取各个类标记在各个特征上的均值
  23. print(clf.sigma_) #获取各个类标记在各个特征上的方差
  24. #测试数据
  25. data_test=np.array([6,4,6,2])
  26. data=data_test.reshape(1,-1)
  27. Result_predict=clf.predict(data)
  28. Score=clf.score([[6,8,5,3],[5,3,4,2],[4,6,7,2]],[2,0,1],sample_weight=[0.3,0.5,0.2])
  29. Result_predict_proba=clf.predict_proba(data)
  30. Result_predict_log_proba=clf.predict_log_proba(data)
  31. print(Result_predict) #预测所属类别
  32. print(Result_predict_proba) #输出测试样本在各个类标记上预测概率值
  33. print(Result_predict_log_proba) #输出测试样本在各个类标记上预测概率值对应对数值
  34. print(Score) #返回测试样本映射到指定类标记上的得分(准确率)

运行结果:


MultinomialNB:

  1. #详细地址请见:https://www.jianshu.com/p/845b16559431
  2. import warnings
  3. import numpy as np
  4. from sklearn import metrics
  5. from scipy.stats import sem
  6. from sklearn.pipeline import Pipeline
  7. from sklearn.datasets import fetch_20newsgroups
  8. from sklearn.naive_bayes import MultinomialNB
  9. from sklearn.model_selection import train_test_split
  10. from sklearn.feature_extraction.text import TfidfVectorizer, HashingVectorizer, CountVectorizer
  11. #忽略一些版本不兼容等警告
  12. warnings.filterwarnings("ignore")
  13. from sklearn.cross_validation import cross_val_score, KFold
  14. news = fetch_20newsgroups(subset='all')
  15. '''
  16. #测试news,来了解数据集的构成
  17. print (news.keys())
  18. print (type(news.data), type(news.target), type(news.target_names))
  19. print (news.target_names)
  20. print(news.data[0])
  21. print(news.target_names[news.target[0]])
  22. print (len(news.data))
  23. print (len(news.target))
  24. '''
  25. #原样本有18846个,为了运行快这里只抽取了样本中的188个样本进行实验,即用x_Reduced_sample1,y_Reduced_sample1进行实验
  26. x_Reduced_sample1, x_Reduced_sample2 , y_Reduced_sample1, y_Reduced_sample2 = train_test_split(news.data, news.target, test_size = 0.99)
  27. #划分训练集和测试集(76个)
  28. x_train, x_test, y_train, y_test = train_test_split(x_Reduced_sample1, y_Reduced_sample1, test_size = 0.4)
  29. #pipeline来将多个学习器组成流水线,通常流水线的形式为:
  30. #将数据标准化的学习器---特征提取的学习器---执行预测的学习器
  31. #除了最后一个学习器之外,前面的所有学习器必须提供transform方法,该方法用于数据转化(例如:归一化,正则化,以及特征提取)
  32. # CountVectorizer,HashingVectorizer,TfidfVectorizer是三种构建特征向量的工具
  33. nbc_1 = Pipeline([
  34. ('vect', CountVectorizer()),
  35. ('clf', MultinomialNB()),
  36. ])
  37. warnings.filterwarnings("ignore")
  38. nbc_2 = Pipeline([
  39. ('vect', HashingVectorizer(non_negative=True)),
  40. ('clf', MultinomialNB()),
  41. ])
  42. nbc_3 = Pipeline([
  43. ('vect', TfidfVectorizer()),
  44. ('clf', MultinomialNB()),
  45. ])
  46. nbcs=[nbc_1, nbc_2, nbc_3]
  47. #分类评价机制:k-折叠交叉验证
  48. def evaluate_cross_validation(clf, X, y, K):
  49. # 最基础的CV算法,也是默认采用的CV策略,地址见http://blog.sina.com.cn/s/blog_7103b28a0102w70h.html
  50. cv = KFold(len(y), n_folds=K, shuffle=True, random_state=0)
  51. # k-折叠交叉验证地址见https://blog.csdn.net/evillist/article/details/61912827
  52. scores = cross_val_score(clf, X, y, cv=cv)
  53. #换分K组后每组的准确率(是一个数组)
  54. print(scores)
  55. #数组中准确率的平均值(越高越好)
  56. print(np.mean(scores))
  57. #数组中准确率平的均值标准误差。
  58. print(sem(scores))
  59. #测试CountVectorizer,HashingVectorizer,TfidfVectorizer是三种构建特征向量的工具的性能
  60. for nbc in nbcs:
  61. evaluate_cross_validation(nbc, x_train, y_train, 5)
  62. '''
  63. #优化特征提取提高分类的效果系列
  64. #1:TfidfVectorizer的一个参数token_pattern用于指定提取单词的规则
  65. # 默认的正则表达式是ur"\b\w\w+\b",这个正则表达式只匹配单词边界并考虑到了下划线,也可能考虑到了横杠和点。
  66. # 新的正则表达式是ur"\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b"
  67. #2:TfidfVectorizer的一个参数stop_words这个参数指定的词将被省略不计入到标记词的列表中,
  68. # 比如一些出现频率很高的词(英文中的a或者and等),但是这些词对于特定的主题不能提供任何的先验支持。
  69. #3:MultinomialNB有一个alpha参数,该参数是一个平滑参数,默认是1.0,我们将其设为0.01
  70. #!!!!!!!!!!但是1和2方案运行不通过不知道什么原因,去掉就可以
  71. def get_stop_words():
  72. result = set()
  73. for line in open('stopwords_en.txt', 'r').readlines():
  74. result.add(line.strip())
  75. return result
  76. stop_words= get_stop_words()
  77. print(stop_words)
  78. nbc_4 = Pipeline([
  79. ('vect', TfidfVectorizer(
  80. stop_words=stop_words, #运行时去掉才行(不知道为什么?)
  81. token_pattern='ur\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b',#运行时去掉才行(不知道为什么?)
  82. )),
  83. ('clf', MultinomialNB(alpha=0.01)),
  84. ])
  85. evaluate_cross_validation(nbc_4,x_train, y_train, 5)
  86. '''
  87. #fit_prior:布尔型,可选项,默认True,表示是否学习先验概率,参数为False表示所有类标记具有相同的先验概率
  88. #class_prior:类似数组,数组大小为(n_classes,),默认None,是先验概率的值
  89. #具体见https://blog.csdn.net/kancy110/article/details/72763276
  90. nbc_5 = Pipeline([
  91. ('vect', TfidfVectorizer()),
  92. ('clf', MultinomialNB(alpha=0.01, class_prior=None, fit_prior=True)),
  93. ])
  94. #核心代码
  95. nbc_5.fit(x_train,y_train)
  96. y_predict = nbc_5.predict(x_test)
  97. print(nbc_5.score(x_test, y_test)) #预测准确率
  98. print(metrics.classification_report(y_test,y_predict)) #包含准确率,召回率等信息表
  99. print(metrics.confusion_matrix(y_test,y_predict)) #混淆矩阵
  100. '''
  101. 正如https://blog.csdn.net/kancy110/article/details/72763276介绍的那样如果有的场景直接用
  102. MultinomialNB()时就可以完成任务,而不是先通过构建特征向量的工具时,学习后的模型还有很多参数可以看
  103. 包括:
  104. class_log_prior_:各类标记的平滑先验概率对数值,其取值会受fit_prior和class_prior参数的影响
  105. intercept_:将多项式朴素贝叶斯解释的class_log_prior_映射为线性模型,其值和class_log_propr相同
  106. feature_log_prob_:指定类的各特征概率(条件概率)对数值,返回形状为(n_classes, n_features)数组
  107. 等等
  108. '''

运行结果为:



BernoulliNB:

  1. #伯努利朴素贝叶斯算法:类似于多项式朴素贝叶斯,也主要用户离散特征分类,
  2. #和MultinomialNB的区别是:MultinomialNB以出现的次数为特征值,而BernoulliNB的特征值为二进制或布尔型特性
  3. import numpy as np
  4. from sklearn.naive_bayes import BernoulliNB
  5. x=np.array([[1,2,3,4],[1,3,4,4],[2,4,5,5],[5,6,9,8]])
  6. y=np.array([1,1,2,3])
  7. #核心代码
  8. clf=BernoulliNB(alpha=2.0,binarize = 3.0,fit_prior=True)
  9. clf.fit(x,y)
  10. '''
  11. #训练后学习模型中的参数
  12. print(np.log(2/4))
  13. print(np.log(1/4))
  14. print(np.log(1/4))
  15. print(clf.class_log_prior_) #对比上面,这是先验概率对数值,类先验概率等于各类的个数/类的总个数
  16. print(clf.feature_log_prob_ ) #指定类的各特征概率(条件概率)对数值
  17. print(clf.class_count_) #按类别顺序输出其对应的个数
  18. print(clf.feature_count_) #各类别各特征值之和,按类的顺序输出,返回形状为[n_classes, n_features] 的数组(不懂?)
  19. '''
  20. #测试数据
  21. x_test=[[1,2,2,5],[7,6,10,9]] #数据不能是分数
  22. y_test_predict=clf.predict(x_test)
  23. y_predict_proba=clf.predict_proba(x_test)
  24. y_test_predict_log_proba=clf.predict_log_proba(x_test)
  25. print(y_test_predict) #在测试集x_test上预测,输出x_test对应目标值
  26. print(y_predict_proba) #输出测试样本划分到各个类别的概率值
  27. print(y_test_predict_log_proba) #输出测试样本划分到各个类别的概率值的对数
  28. print(clf.score([[3,4,5,4],[1,3,5,6]],[1,3])) #输出对测试样本的预测准确率的平均值,当然可以加权值这个参数score(X, y, sample_weight=None)

运行结果:


更多算法可以参看博主其他文章,或者github:https://github.com/Mryangkaitong/python-Machine-learning

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号