一、思想概述

        贝叶斯分类算法是一大类分类算法的总称;贝叶斯分类算法以样本可能属于某类的概率来作为分类依据;朴素贝叶斯分类算法是贝叶斯分类算法中最简单的一种。

朴素贝叶斯分类器是一种用于分类任务的概率机器学习模型。分类器的关键是基于贝叶斯定理。

使用贝叶斯定理,假设B已经发生,我们可以找到A发生的概率。这里,B是证据,A是假设。这里的假设是预测变量/特征是独立的。也就是说,一个特定特征的存在不会影响另一个。因此,它被称为朴素。

朴素的意思是条件概率独立性。朴素贝叶斯方法是一组监督学习算法,基于贝叶斯定理,并在给定类变量值的情况下,每对特征之间的条件独立性的“朴素”假设。尽管它们的假设显然过分简化,但朴素的贝叶斯分类器在许多实际情况下(在著名的文档分类和垃圾邮件过滤中)都表现良好。他们需要少量的训练数据来估计必要的参数。另一方面也是由于过于朴素,所以对于输入数据的准备方式较为敏感。

贝叶斯发展出来很多分类

Gaussian Naive Bayes(高斯朴素贝叶斯算法)

Multinomial Naive Bayes(多项式朴素贝叶斯)

Complement Naive Bayes(补充朴素贝叶斯)

Bernoulli Naive Bayes(伯努利·朴素贝叶斯)

Categorical Naive Bayes(分类朴素贝叶斯)

Out-of-core naive Bayes model fitting(超核贝叶斯模型拟合)

二、OpenCV函数实现

大多数的函数都继承自StatModel。

创建贝叶斯实例

Ptr<NormalBayesClassifier> create()

加载贝叶斯实例,通过使用文件的路径调用此函数,再次从此文件加载 NormalBayesClassifier。(可选)为包含分类器的文件指定节点

Ptr<NormalBayesClassifier> load(const String& filepath , const String& nodeName = String())

该方法估计输入向量的最可能的类别。 输入向量(一个或多个)存储为矩阵输入的行。 在多个输入向量的情况下,应该有一个输出向量输出。 单个输入向量的预测类由该方法返回。向量 outputProbs 包含与结果的每个元素对应的输出概率。

virtual float predictProb( InputArray inputs, OutputArray outputs,
                               OutputArray outputProbs, int flags=0 )

三、 例1:进行敏感词分类

1、python实现

from numpy import *# 词表到向量的转换函数
def loadDataSet():postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],['stop', 'posting', 'stupid', 'worthless', 'garbage'],['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]classVec = [0,1,0,1,0,1]    #1 is abusive, 0 notreturn postingList,classVec# 创建一个包含在所有文档中出现的不重复词的列表,
def createVocabList(dataSet):# 创建一个空集合vocabSet = set([])  #create empty set# 创建并集for document in dataSet:vocabSet = vocabSet | set(document) #union of the two setsreturn list(vocabSet)# 该函数的输入参数为词汇表及某个文
档,输出的是文档向量,向量的每一元素为1或0,分别表示词汇表中的单词在输入文档中是否出
现。
def setOfWords2Vec(vocabList, inputSet):returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] = 1else: print "the word: %s is not in my Vocabulary!" % wordreturn returnVec#朴素贝叶斯分类器训练函数
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)numWords = len(trainMatrix[0])pAbusive = sum(trainCategory)/float(numTrainDocs)# 初始化概率p0Num = ones(numWords); p1Num = ones(numWords)      #change to ones() p0Denom = 2.0; p1Denom = 2.0                        #change to 2.0for i in range(numTrainDocs):if trainCategory[i] == 1:p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = log(p1Num/p1Denom)          #change to log()p0Vect = log(p0Num/p0Denom)          #change to log()return p0Vect,p1Vect,pAbusive# 朴素贝叶斯分类函数
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1)    #element-wise multp0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0def bagOfWords2VecMN(vocabList, inputSet):returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] += 1return returnVecdef testingNB():listOPosts,listClasses = loadDataSet()myVocabList = createVocabList(listOPosts)trainMat=[]for postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))testEntry = ['love', 'my', 'dalmation']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)testEntry = ['stupid', 'garbage']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)def textParse(bigString):    #input is big string, #output is word listimport relistOfTokens = re.split(r'\W*', bigString)return [tok.lower() for tok in listOfTokens if len(tok) > 2] def spamTest():docList=[]; classList = []; fullText =[]for i in range(1,26):wordList = textParse(open('email/spam/%d.txt' % i).read())docList.append(wordList)fullText.extend(wordList)classList.append(1)wordList = textParse(open('email/ham/%d.txt' % i).read())docList.append(wordList)fullText.extend(wordList)classList.append(0)vocabList = createVocabList(docList)#create vocabularytrainingSet = range(50); testSet=[]           #create test setfor i in range(10):randIndex = int(random.uniform(0,len(trainingSet)))testSet.append(trainingSet[randIndex])del(trainingSet[randIndex])  trainMat=[]; trainClasses = []for docIndex in trainingSet:#train the classifier (get probs) trainNB0trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))trainClasses.append(classList[docIndex])p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))errorCount = 0for docIndex in testSet:        #classify the remaining itemswordVector = bagOfWords2VecMN(vocabList, docList[docIndex])if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:errorCount += 1print "classification error",docList[docIndex]print 'the error rate is: ',float(errorCount)/len(testSet)#return vocabList,fullTextdef calcMostFreq(vocabList,fullText):import operatorfreqDict = {}for token in vocabList:freqDict[token]=fullText.count(token)sortedFreq = sorted(freqDict.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedFreq[:30]       def localWords(feed1,feed0):import feedparserdocList=[]; classList = []; fullText =[]minLen = min(len(feed1['entries']),len(feed0['entries']))for i in range(minLen):wordList = textParse(feed1['entries'][i]['summary'])docList.append(wordList)fullText.extend(wordList)classList.append(1) #NY is class 1wordList = textParse(feed0['entries'][i]['summary'])docList.append(wordList)fullText.extend(wordList)classList.append(0)vocabList = createVocabList(docList)#create vocabularytop30Words = calcMostFreq(vocabList,fullText)   #remove top 30 wordsfor pairW in top30Words:if pairW[0] in vocabList: vocabList.remove(pairW[0])trainingSet = range(2*minLen); testSet=[]           #create test setfor i in range(20):randIndex = int(random.uniform(0,len(trainingSet)))testSet.append(trainingSet[randIndex])del(trainingSet[randIndex])  trainMat=[]; trainClasses = []for docIndex in trainingSet:#train the classifier (get probs) trainNB0trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))trainClasses.append(classList[docIndex])p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))errorCount = 0for docIndex in testSet:        #classify the remaining itemswordVector = bagOfWords2VecMN(vocabList, docList[docIndex])if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:errorCount += 1print 'the error rate is: ',float(errorCount)/len(testSet)return vocabList,p0V,p1Vdef getTopWords(ny,sf):import operatorvocabList,p0V,p1V=localWords(ny,sf)topNY=[]; topSF=[]for i in range(len(p0V)):if p0V[i] > -6.0 : topSF.append((vocabList[i],p0V[i]))if p1V[i] > -6.0 : topNY.append((vocabList[i],p1V[i]))sortedSF = sorted(topSF, key=lambda pair: pair[1], reverse=True)print "SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**"for item in sortedSF:print item[0]sortedNY = sorted(topNY, key=lambda pair: pair[1], reverse=True)print "NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**"for item in sortedNY:print item[0]

2、c++代码参考

//naiveBayes.h
#ifndef NAIVEBAYES_H_
#define NAIVEBAYES_H_
#include<vector>
#include<string>
#include<set>
#include<opencv2/opencv.hpp>using cv::Mat;
using std::vector;
using std::string;
using std::set;//创建所有文档中出现的不重复词的集合
void createVocabList(const vector<vector<string>>& postingList, set<string>& vocabSet);
//将词向量转变成文本特征矩阵
Mat vec2Mat(const set<string>& vocabSet, vector<string>&vec);
//词集模型,判断文档中的单词那些在输入向量中出现,出现为1,否则为0
void setOfWords2Vec(const set<string>& vocabSet, const vector<string>&inputSet, vector<int>&output);
//词袋模型,判断文档中的单词那些在输入向量中出现,出现则+1,未出现为0
void bagOfWords2Vec(const set<string>& vocabSet, const vector<string>&inputSet, vector<int>&output);
//朴素贝叶斯分类器训练函数
void trainNB0(const Mat& trainMatrix, const vector<int>& classVec, vector<float>& pb, vector<Mat>& pVect);
//测试函数
int classifyNB(const Mat& test, vector<float>& pb, vector<Mat> pVect);
#endif
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<algorithm>
#include<opencv2/opencv.hpp>using cv::Mat;
using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::set;void createVocabList(const vector<vector<string>>& postingList, set<string>& vocabSet)
{/*函数功能:创建所有文档中出现的不重复词的集合postingList:各个文档中的词vocabSet:不重复词的集合*/for (int i = 0; i < postingList.size(); i++){vector<string>temp = postingList[i];for (int j = 0; j < temp.size(); j++){vocabSet.insert(temp[j]);}}}void setOfWords2Vec(const set<string>& vocabSet, const vector<string>&inputSet, vector<int>&output)
{/*函数功能:判断文档中的单词那些在输入向量中出现,出现为1,否则为0vocabSet:数据集中不重复词的集合inputSet:输入向量output:输出向量*/output.resize(vocabSet.size(), 0);for (auto it : inputSet){auto i = vocabSet.find(it);if (i != vocabSet.end()){int index = std::distance(vocabSet.begin(), i);output[index] = 1;}}
}
void bagOfWords2Vec(const set<string>& vocabSet, const vector<string>&inputSet, vector<int>&output)
{/*函数功能:词袋模型,判断文档中的单词那些在输入向量中出现,出现则+1,未出现为0vocabSet:数据集中不重复词的集合inputSet:输入向量output:输出向量*/output.resize(vocabSet.size(), 0);for (auto it : inputSet){auto i = vocabSet.find(it);if (i != vocabSet.end()){int index = std::distance(vocabSet.begin(), i);output[index] += 1;}}
}
Mat vec2Mat(const set<string>& vocabSet, vector<string>&vec)
{/*函数功能:将词向量转变成文本特征矩阵vocabSet:训练数据集中不重复词的集合vec:词向量*/vector<int>output;setOfWords2Vec(vocabSet, vec, output);Mat temp = Mat(output);cv::transpose(temp, temp);temp.convertTo(temp, CV_32F);return temp;
}
void trainNB0(const Mat& trainMatrix, const vector<int>& classVec, vector<float>& pb, vector<Mat>& pVect)
{/*函数功能:朴素贝叶斯分类器训练函数,由于的是文本分类,所以把文档中的所有样本的每个单词归为一个特征,而不是把每个单词是否出现当成一个特征trainMatrix:文档矩阵classVec:各文档类别pb:各类别概率,索引即类号,从 0 开始pVect:各类别条件概率*/int numTrainDocs = trainMatrix.rows;int numWords = trainMatrix.cols;//计算各类别概率auto it = std::max_element(classVec.begin(), classVec.end());//类别数auto classes = *it;pb.resize(classes + 1, 0);for (int i = 0; i < classVec.size(); i++){pb[classVec[i]]++;}for (int i = 0; i <= classes; i++){pb[i] = pb[i] / classVec.size();}vector<int>Num(classes + 1, 2);//各类别特征总数,由于可能出现单词未出现的情况,其条件概率将为0,故初始化分母为2,分子为1//计算条件概率for (int i = 0; i <= classes; i++){//创建每个类别的条件概率矩阵,由于可能出现单词未出现的情况,其条件概率将为0,故初始化分母为2,分子为1Mat temp = Mat::ones(1, trainMatrix.cols, CV_32F);pVect.push_back(temp);}for (int i = 0; i < numTrainDocs; i++){int cls = classVec[i];Mat temp = trainMatrix.row(i).clone();pVect[cls] = pVect[cls] + temp;Num[cls] += cv::sum(trainMatrix.row(i))[0];}//计算各类概率分布for (int i = 0; i <= classes; i++){cout << pVect[i] << endl;Mat& temp = pVect[i];temp = temp / Num[i];cv::log(temp, temp);cout << i << " = " << temp << endl;}}
int classifyNB(const Mat& test, vector<float>& pb, vector<Mat> pVect)
{/*函数功能:测试函数test:测试样本pb:各类别概率,索引即类号,从 0 开始pVect:各类别条件概率*/vector<float>p(pb.size());cout << test.type() << endl;cout << pVect[0].type() << endl;for (int i = 0; i < pb.size(); i++){Mat temp = test.mul(pVect[i]);p[i] = cv::sum(temp)[0] + log(pb[i]);}auto i = std::max_element(p.begin(), p.end());int index = std::distance(p.begin(), i);return index;
}

四、例2:汽车分类

数据集下载

链接:https://pan.baidu.com/s/1e3WDHdKMOxaLGKDKTYcX4w 
提取码:v0qn

buying    maint       doors      persons  lug_boot    safety      class
0    vhigh      vhigh      2              2     small       low          unacc
1    vhigh      vhigh      2              2     small       med         unacc
2    vhigh      vhigh      2              2     small       high        unacc
3    vhigh      vhigh      2              2     med         low          unacc
4    vhigh      vhigh      2              2     med         med         unacc

读取数据集

import os
import numpy as np
import pandas as pd
import numpy as np, pandas as pd
import matplotlib.pyplot as plt
from sklearn import metrics , model_selection
## Import the Classifier.
from sklearn.naive_bayes import GaussianNBdata = pd.read_csv('data/car_quality/car.data',names=['buying','maint','doors','persons','lug_boot','safety','class'])
data.head()data['class'],class_names = pd.factorize(data['class'])
print(class_names)print(data['class'].unique())X = data.iloc[:,:-1]
y = data.iloc[:,-1]# split data randomly into 70% training and 30% testX_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.3, random_state=123)model = GaussianNB()## Fit the model on the training data.model.fit(X_train, y_train)# use the model to make predictions with the test datay_pred = model.predict(X_test)# how did our model perform?count_misclassified = (y_test != y_pred).sum()print('Misclassified samples: {}'.format(count_misclassified))accuracy = metrics.accuracy_score(y_test, y_pred)print('Accuracy: {:.2f}'.format(accuracy))

预测结果

Misclassified samples: 150

Accuracy: 0.71

五、其它参考文章

朴素贝叶斯分类器的应用

朴素贝叶斯常见面试题 - 简书

机器学习笔记 - 学习朴素贝叶斯概念及应用相关推荐

  1. 机器学习笔记:朴素贝叶斯方法(Naive Bayes)原理和实现

    本文主要描述了朴素贝叶斯分类方法,包括模型导出和学习描述.实例部分总结了<machine learning in action>一书中展示的一个该方法用于句子感情色彩分类的程序.1 方法概 ...

  2. 【机器学习笔记】朴素贝叶斯

    本文学习自 https://zhuanlan.zhihu.com/ml-jack 朴素贝叶斯 朴素贝叶斯算法是有监督的学习算法,解决的是分类问题. 1.贝叶斯决策理论 贝叶斯决策理论的核心思想:选择具 ...

  3. 机器学习实战之朴素贝叶斯

    机器学习实战之朴素贝叶斯 一.朴素贝叶斯算法概述 1.贝叶斯决策理论 2.条件概率 3.全概率公式 4.贝叶斯推断 5.朴素贝叶斯推断 二.实战 三.总结 1.朴素贝叶斯推断的一些优点: 2.朴素贝叶 ...

  4. 机器学习面试题——朴素贝叶斯

    机器学习面试题--朴素贝叶斯 提示:这些知识点也是大厂笔试经常考的题目,我记得阿里和京东就考!!!想必在互联网大厂就会用这些知识解决实际问题 朴素贝叶斯介绍一下 朴素贝叶斯优缺点 贝叶斯公式 朴素贝叶 ...

  5. 《机器学习实战》朴素贝叶斯

    机器学习实战的朴素贝叶斯一章中的源文件老是提示 IndexError: range object index out of range 看源码里怎么都不会溢出啊,除非minLen为0:所以看了下测试集 ...

  6. 机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测

    机器学习:基于朴素贝叶斯对花瓣花萼的宽度和长度分类预测 作者:i阿极 作者简介:Python领域新星作者.多项比赛获奖者:博主个人首页

  7. sklearn学习-朴素贝叶斯(二)

    文章目录 一.概率类模型的评估指标 1.布里尔分数Brier Score 对数似然函数Log Loss 二. calibration_curve: 校准可靠性曲线 三.多项式朴素贝叶斯以及其变化 四. ...

  8. 机器学习实验:朴素贝叶斯算法

    机器学习实验:朴素贝叶斯算法 问题如下: 根据给出的算法naivebayes.py,实现: 1.将数据集文件naivebayes_data.csv中的数据替换成14天打球与天气数据: 2.预测样本{O ...

  9. 机器学习实战读书笔记(3)朴素贝叶斯

    贝叶斯定理 要理解贝叶斯推断,必须先理解贝叶斯定理.后者实际上就是计算"条件概率"的公式. 所谓"条件概率"(Conditional probability), ...

最新文章

  1. 做科研没人带,发不了文章怎么办?
  2. Sorry, user *** is not allowed to execute ‘xxxx‘ as root on ****.
  3. iis php 假死 nginx,网站假死 重启NGINX无效 必须重启PHP 原因分析
  4. Git:Rebase和Merge之间的区别,看完这篇文章你就懂了!
  5. MongoDB-数据库-mongoose-图形化操作
  6. 如何学计算机课程,一张图告诉你大学如何学好计算机专业课程
  7. 如何删除尾随换行符?
  8. python 新闻分类_python实现简单的新闻文章归类
  9. 小知识点日记 2013-1-17 至 2013-6-13
  10. matlab 三角函数 积化和差,三角函数之积化和差、和差化积及推导过程
  11. Android 圆形 ImageView
  12. php微信生成签名_微信APP支付服务端PHP生成签名
  13. R语言使用报错及处理总结(不断更新)
  14. 读书是一种修养 ——《大河奔流的精神》(俞敏洪著)读后感
  15. tomcat设置https端口时,8443和443区别:
  16. SAP 供应商合作伙伴功能设置
  17. 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结
  18. Windows-Python实时获取小米手环4心率,最简单代码
  19. 开分矿——青龙多容器的安装与使用
  20. ubuntu20.04安装中文输入法

热门文章

  1. ellipse()用法
  2. UI设计师有哪些就业方向选择?
  3. arm linux运行安卓app,Android x86 下运行纯ARM版APP
  4. 大数据才是未来,Oracle、SQL Server成昨日黄花?
  5. Linux中TCP listen()的参数
  6. IT外企那点儿事(15): 好员工和坏员工只有一步之遥
  7. mysql sql stuff函数_SQL常用函数之一 Stuff()
  8. 如何使用Flask和Heroku在Facebook Messenger上创建ChatBot
  9. 基于 Apache Kylin 的微博舆情实时分析(内含 Demo)
  10. 一路走来的飞控设计研发之路