机器学习-朴素贝叶斯学习-原理分析与C语言代码实现

合集下载

利用c++实现贝叶斯公式

利用c++实现贝叶斯公式

利用c++实现贝叶斯公式摘要:1.贝叶斯公式的介绍2.C++实现贝叶斯公式的步骤3.代码展示及解析4.结论正文:贝叶斯公式是概率论中一个非常重要的公式,它描述了在已知某条件概率的情况下,求解相关联的逆条件概率。

具体公式如下:P(A|B) = P(B|A) * P(A) / P(B)其中,P(A|B) 表示在已知事件B 发生的情况下,事件A 发生的概率;P(B|A) 表示在已知事件A 发生的情况下,事件B 发生的概率;P(A) 和P(B) 分别表示事件A 和事件B 的概率。

接下来,我们将介绍如何利用C++ 实现贝叶斯公式。

首先,我们需要定义一个结构体,用于存储事件的名称和发生的概率:```cppstruct Event {string name;double probability;};```接着,我们需要实现一个计算贝叶斯公式的函数:```cppdouble calculateBayes(const vector<Event>& events, string condition, string hypothesis) {// 计算P(B)double P_B = 0.0;for (const auto& event : events) {if ( == condition) {P_B += event.probability;}}// 计算P(A|B)double P_A_B = 0.0;for (const auto& event : events) {if ( == condition) {for (const auto& otherEvent : events) {if ( == hypothesis && != condition) {P_A_B += event.probability * otherEvent.probability;}}}}// 计算P(A)double P_A = 0.0;for (const auto& event : events) {if ( == hypothesis) {P_A += event.probability;}}// 返回贝叶斯公式结果return P_A_B / P_A;}```最后,我们可以通过以下方式使用这个函数:```cppvector<Event> events = {{"A", 0.2},{"B", 0.3},{"C", 0.5},{"D", 0.4},{"E", 0.1},};double result = calculateBayes(events, "B", "A");cout << "P(A|B) = " << result << endl;```以上代码首先定义了一个结构体Event,用于存储事件的名称和发生的概率。

朴素贝叶斯算法及其代码实现

朴素贝叶斯算法及其代码实现

朴素贝叶斯算法及其代码实现朴素贝叶斯朴素贝叶斯是经典的机器学习算法之⼀,也是为数不多的基于概率论的分类算法。

在机器学习分类算法中,朴素贝叶斯和其他绝多⼤的分类算法都不同,⽐如决策树,KNN,逻辑回归,⽀持向量机等,他们都是判别⽅法,也就是直接学习出特征输出Y和特征X之间的关系,要么是决策函数,要么是条件分布。

但是朴素贝叶斯却是⽣成⽅法,这种算法简单,也易于实现。

1.基本概念朴素贝叶斯:贝叶斯分类是⼀类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。

⽽朴素贝叶斯分类时贝叶斯分类中最简单,也是最常见的⼀种分类⽅法。

贝叶斯公式:先验概率P(X):先验概率是指根据以往经验和分析得到的概率。

后验概率P(Y|X):事情已经发⽣,要求这件事情发⽣的原因是由某个因素引起的可能性的⼤⼩,后验分布P(Y|X)表⽰事件X已经发⽣的前提下,事件Y发⽣的概率,叫做事件X发⽣下事件Y的条件概率。

后验概率P(X|Y):在已知Y发⽣后X的条件概率,也由于知道Y的取值⽽被称为X的后验概率。

朴素:朴素贝叶斯算法是假设各个特征之间相互独⽴,也是朴素这词的意思,那么贝叶斯公式中的P(X|Y)可写成:朴素贝叶斯公式:2,贝叶斯算法简介 贝叶斯⽅法源域它⽣前为解决⼀个“逆概”问题写的⼀篇⽂章。

其要解决的问题: 正向概率:假设袋⼦⾥⾯有N个⽩球,M个⿊球,你伸⼿进去摸⼀把,摸出⿊球的概率是多⼤ 逆向概率:如果我们事先不知道袋⼦⾥⾯⿊⽩球的⽐例,⽽是闭着眼睛摸出⼀个(或者好⼏个)球,观察这些取出来的球的颜⾊之后,那么我们可以就此对袋⼦⾥⾯的⿊⽩球的⽐例做出什么样的推测。

那么什么是贝叶斯呢?1,现实世界本⾝就是不确定的,⼈类的观察能⼒是有局限性的2,我们⽇常观察到的只是事物表明上的结果,因此我们需要提供⼀个猜测 NaiveBayes算法,⼜称朴素贝叶斯算法。

朴素:特征条件独⽴;贝叶斯:基于贝叶斯定理。

属于监督学习的⽣成模型,实现监督,没有迭代,并有坚实的数学理论(即贝叶斯定理)作为⽀撑。

机器学习:贝叶斯分类器(二)——高斯朴素贝叶斯分类器代码实现

机器学习:贝叶斯分类器(二)——高斯朴素贝叶斯分类器代码实现

机器学习:贝叶斯分类器(⼆)——⾼斯朴素贝叶斯分类器代码实现⼀⾼斯朴素贝叶斯分类器代码实现⽹上搜索不调⽤sklearn实现的朴素贝叶斯分类器基本很少,即使有也是结合⽂本分类的多项式或伯努利类型,因此⾃⼰写了⼀遍能直接封装的⾼斯类型NB分类器,当然与真正的源码相⽐少了很多属性和⽅法,有兴趣的可以⾃⼰添加。

代码如下(有详细注释):class NaiveBayes():'''⾼斯朴素贝叶斯分类器'''def __init__(self):self._X_train = Noneself._y_train = Noneself._classes = Noneself._priorlist = Noneself._meanmat = Noneself._varmat = Nonedef fit(self, X_train, y_train):self._X_train = X_trainself._y_train = y_trainself._classes = np.unique(self._y_train) # 得到各个类别priorlist = []meanmat0 = np.array([[0, 0, 0, 0]])varmat0 = np.array([[0, 0, 0, 0]])for i, c in enumerate(self._classes):# 计算每个种类的平均值,⽅差,先验概率X_Index_c = self._X_train[np.where(self._y_train == c)] # 属于某个类别的样本组成的“矩阵”priorlist.append(X_Index_c.shape[0] / self._X_train.shape[0]) # 计算类别的先验概率X_index_c_mean = np.mean(X_Index_c, axis=0, keepdims=True) # 计算该类别下每个特征的均值,结果保持⼆维状态[[3 4 6 2 1]]X_index_c_var = np.var(X_Index_c, axis=0, keepdims=True) # ⽅差meanmat0 = np.append(meanmat0, X_index_c_mean, axis=0) # 各个类别下的特征均值矩阵罗成新的矩阵,每⾏代表⼀个类别。

朴素贝叶斯原理、实例与Python实现

朴素贝叶斯原理、实例与Python实现

朴素贝叶斯原理、实例与Python实现初步理解⼀下:对于⼀组输⼊,根据这个输⼊,输出有多种可能性,需要计算每⼀种输出的可能性,以可能性最⼤的那个输出作为这个输⼊对应的输出。

那么,如何来解决这个问题呢?贝叶斯给出了另⼀个思路。

根据历史记录来进⾏判断。

思路是这样的:1、根据贝叶斯公式:P(输出|输⼊)=P(输⼊|输出)*P(输出)/P(输⼊)2、P(输⼊)=历史数据中,某个输⼊占所有样本的⽐例;3、P(输出)=历史数据中,某个输出占所有样本的⽐例;4、P(输⼊|输出)=历史数据中,某个输⼊,在某个输出的数量占所有样本的⽐例,例如:30岁,男性,中午吃⾯条,其中【30岁,男性就是输⼊】,【中午吃⾯条】就是输出。

⼀、条件概率的定义与贝叶斯公式⼆、朴素贝叶斯分类算法朴素贝叶斯是⼀种有监督的分类算法,可以进⾏⼆分类,或者多分类。

⼀个数据集实例如下图所⽰:现在有⼀个新的样本, X = (年龄:<=30, 收⼊:中,是否学⽣:是,信誉:中),⽬标是利⽤朴素贝叶斯分类来进⾏分类。

假设类别为C(c1=是或 c2=否),那么我们的⽬标是求出P(c1|X)和P(c2|X),⽐较谁更⼤,那么就将X分为某个类。

下⾯,公式化朴素贝叶斯的分类过程。

三、实例下⾯,将下⾯这个数据集作为训练集,对新的样本X = (年龄:<=30, 收⼊:中,是否学⽣:是,信誉:中) 作为测试样本,进⾏分类。

我们可以将这个实例中的描述属性和类别属性,与公式对应起来,然后计算。

参考python实现代码#coding:utf-8# 极⼤似然估计朴素贝叶斯算法import pandas as pdimport numpy as npclass NaiveBayes(object):def getTrainSet(self):dataSet = pd.read_csv('F://aaa.csv')dataSetNP = np.array(dataSet) #将数据由dataframe类型转换为数组类型trainData = dataSetNP[:,0:dataSetNP.shape[1]-1] #训练数据x1,x2labels = dataSetNP[:,dataSetNP.shape[1]-1] #训练数据所对应的所属类型Yreturn trainData, labelsdef classify(self, trainData, labels, features):#求labels中每个label的先验概率labels = list(labels) #转换为list类型labelset = set(labels)P_y = {} #存⼊label的概率for label in labelset:P_y[label] = labels.count(label)/float(len(labels)) # p = count(y) / count(Y)print(label,P_y[label])#求label与feature同时发⽣的概率P_xy = {}for y in P_y.keys():y_index = [i for i, label in enumerate(labels) if label == y] # labels中出现y值的所有数值的下标索引for j in range(len(features)): # features[0] 在trainData[:,0]中出现的值的所有下标索引x_index = [i for i, feature in enumerate(trainData[:,j]) if feature == features[j]]xy_count = len(set(x_index) & set(y_index)) # set(x_index)&set(y_index)列出两个表相同的元素pkey = str(features[j]) + '*' + str(y)P_xy[pkey] = xy_count / float(len(labels))print(pkey,P_xy[pkey])#求条件概率P = {}for y in P_y.keys():for x in features:pkey = str(x) + '|' + str(y)P[pkey] = P_xy[str(x)+'*'+str(y)] / float(P_y[y]) #P[X1/Y] = P[X1Y]/P[Y]print(pkey,P[pkey])#求[2,'S']所属类别F = {} #[2,'S']属于各个类别的概率for y in P_y:F[y] = P_y[y]for x in features:F[y] = F[y]*P[str(x)+'|'+str(y)] #P[y/X] = P[X/y]*P[y]/P[X],分母相等,⽐较分⼦即可,所以有F=P[X/y]*P[y]=P[x1/Y]*P[x2/Y]*P[y] print(str(x),str(y),F[y])features_label = max(F, key=F.get) #概率最⼤值对应的类别return features_labelif__name__ == '__main__':nb = NaiveBayes()# 训练数据trainData, labels = nb.getTrainSet()# x1,x2features = [8]# 该特征应属于哪⼀类result = nb.classify(trainData, labels, features)print(features,'属于',result)#coding:utf-8#朴素贝叶斯算法贝叶斯估计,λ=1 K=2, S=3;λ=1 拉普拉斯平滑import pandas as pdimport numpy as npclass NavieBayesB(object):def__init__(self):self.A = 1 # 即λ=1self.K = 2self.S = 3def getTrainSet(self):trainSet = pd.read_csv('F://aaa.csv')trainSetNP = np.array(trainSet) #由dataframe类型转换为数组类型trainData = trainSetNP[:,0:trainSetNP.shape[1]-1] #训练数据x1,x2labels = trainSetNP[:,trainSetNP.shape[1]-1] #训练数据所对应的所属类型Yreturn trainData, labelsdef classify(self, trainData, labels, features):labels = list(labels) #转换为list类型#求先验概率P_y = {}for label in labels:P_y[label] = (labels.count(label) + self.A) / float(len(labels) + self.K*self.A)#求条件概率P = {}for y in P_y.keys():y_index = [i for i, label in enumerate(labels) if label == y] # y在labels中的所有下标y_count = labels.count(y) # y在labels中出现的次数for j in range(len(features)):pkey = str(features[j]) + '|' + str(y)x_index = [i for i, x in enumerate(trainData[:,j]) if x == features[j]] # x在trainData[:,j]中的所有下标 xy_count = len(set(x_index) & set(y_index)) #x y同时出现的次数P[pkey] = (xy_count + self.A) / float(y_count + self.S*self.A) #条件概率#features所属类F = {}for y in P_y.keys():F[y] = P_y[y]for x in features:F[y] = F[y] * P[str(x)+'|'+str(y)]features_y = max(F, key=F.get) #概率最⼤值对应的类别return features_yif__name__ == '__main__':nb = NavieBayesB()# 训练数据trainData, labels = nb.getTrainSet()# x1,x2features = [10]# 该特征应属于哪⼀类result = nb.classify(trainData, labels, features)print(features,'属于',result)参考链接:https:///ten_sory/article/details/81237169。

朴素贝叶斯文本分类代码(详解)

朴素贝叶斯文本分类代码(详解)

朴素贝叶斯⽂本分类代码(详解)1from numpy import zeros,array2from math import log34def loadDataSet():5#词条切分后的⽂档集合,列表每⼀⾏代表⼀个email6 postingList=[['your','mobile','number','is','award','bonus','prize'],7 ['new','car','and','house','for','my','parents'],8 ['my','dalmation','is','so','cute','I','love','him'],9 ['today','voda','number','prize', 'receive','award'],10 ['get','new','job','in','company','how','to','get','that'],11 ['free','prize','buy','winner','receive','cash']]12#由⼈⼯标注的每篇⽂档的类标签13 classVec=[1,0,0,1,0,1] #1-spam, 0-ham14return postingList,classVec15 postingList,classVec = loadDataSet()161718#统计所有⽂档中出现的词条列表19def createVocabList(dataSet):20 vocabSet=set([])21#遍历⽂档集合中的每⼀篇⽂档22for document in dataSet:23 vocabSet=vocabSet|set(document)24return list(vocabSet)25 vocabSet = createVocabList(postingList)262728#根据词条列表中的词条是否在⽂档中出现(出现1,未出现0),将⽂档转化为词条向量29def setOfWords2Vec(vocabSet,inputSet):30#新建⼀个长度为vocabSet的列表,并且各维度元素初始化为031 returnVec=[0]*len(vocabSet)32#遍历⽂档中的每⼀个词条33for word in inputSet:34#如果词条在词条列表中出现35if word in vocabSet:36#通过列表获取当前word的索引(下标)37#将词条向量中的对应下标的项由0改为138 returnVec[vocabSet.index(word)]=139else: print('the word: %s is not in my vocabulary! '%'word')40#返回inputet转化后的词条向量41return returnVec4243 trainMatrix = [setOfWords2Vec(vocabSet,inputSet) for inputSet in postingList]444546#训练算法,从词向量计算概率p(w0|ci)...及p(ci)47#@trainMatrix:由每篇⽂档的词条向量组成的⽂档矩阵48#@trainCategory:每篇⽂档的类标签组成的向量49def trainNB0(trainMatrix,trainCategory):50#获取⽂档矩阵中⽂档的数⽬51 numTrainDocs=len(trainMatrix)52#获取词条向量的长度53 numWords=len(trainMatrix[0])54#所有⽂档中属于类1所占的⽐例p(c=1)55 pAbusive=sum(trainCategory)/float(numTrainDocs)56#创建⼀个长度为词条向量等长的列表57 p0Num=zeros(numWords) #ham58 p1Num=zeros(numWords) #spam59 p0Denom=0.060 p1Denom=0.061#遍历每⼀篇⽂档的词条向量62for i in range(numTrainDocs):63#如果该词条向量对应的标签为164if trainCategory[i]==1:65#统计所有类别为1的词条向量中各个词条出现的次数66 p1Num+=trainMatrix[i]67#统计类别为1的词条向量中出现的所有词条的总数68#即统计类1所有⽂档中出现单词的数⽬69 p1Denom+=sum(trainMatrix[i])70else:71#统计所有类别为0的词条向量中各个词条出现的次数72 p0Num+=trainMatrix[i]73#统计类别为0的词条向量中出现的所有词条的总数74#即统计类0所有⽂档中出现单词的数⽬75 p0Denom+=sum(trainMatrix[i])76print(p1Num, p1Denom, p0Num,p0Denom )77#利⽤NumPy数组计算p(wi|c1)78 p1Vect=p1Num/p1Denom #为避免下溢出问题,需要改为log()79#利⽤NumPy数组计算p(wi|c0)80 p0Vect=p0Num/p0Denom #为避免下溢出问题,需要改为log()81return p0Vect,p1Vect,pAbusive8283 p0Vect,p1Vect,pAbusive= trainNB0(trainMatrix,classVec)848586#朴素贝叶斯分类函数87#@vec2Classify:待测试分类的词条向量88#@p0Vec:类别0所有⽂档中各个词条出现的频数p(wi|c0)89#@p0Vec:类别1所有⽂档中各个词条出现的频数p(wi|c1)90#@pClass1:类别为1的⽂档占⽂档总数⽐例91def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):92#根据朴素贝叶斯分类函数分别计算待分类⽂档属于类1和类0的概率93 p1=sum(vec2Classify*p1Vec)+log(pClass1)94 p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1)95if p1>p0:96return'spam'97else:98return'not spam'99100101102 testEntry=['love','my','job']103 thisDoc=array(setOfWords2Vec(vocabSet,testEntry))104print(testEntry,'classified as:',classifyNB(thisDoc,p0Vect,p1Vect,pAbusive))。

朴素贝叶斯算法,贝叶斯分类算法,贝叶斯定理原理

朴素贝叶斯算法,贝叶斯分类算法,贝叶斯定理原理

朴素贝叶斯算法,贝叶斯分类算法,贝叶斯定理原理朴素贝叶斯算法,贝叶斯分类算法,贝叶斯定理原理贝叶斯分类算法是统计学的⼀种分类⽅法,它是⼀类利⽤概率统计知识进⾏分类的算法。

在许多场合,朴素贝叶斯(Naïve Bayes,NB)分类算法可以与决策树和神经⽹络分类算法相媲美,该算法能运⽤到⼤型数据库中,⽽且⽅法简单、分类准确率⾼、速度快。

由于贝叶斯定理假设⼀个属性值对给定类的影响独⽴于其它属性的值,⽽此假设在实际情况中经常是不成⽴的,因此其分类准确率可能会下降。

为此,就衍⽣出许多降低独⽴性假设的贝叶斯分类算法,如TAN(tree augmented Bayes network)算法。

朴素贝叶斯算法的核⼼思想:选择具有最⾼后验概率作为确定类别的指标。

--------------------朴素贝叶斯算法设每个数据样本⽤⼀个n维特征向量来描述n个属性的值,即:X={x1,x2,…,xn},假定有m个类,分别⽤C1, C2,…,Cm表⽰。

给定⼀个未知的数据样本X(即没有类标号),若朴素贝叶斯分类法将未知的样本X分配给类Ci,则⼀定是P(Ci|X)>P(Cj|X) 1≤j≤m,j≠i根据贝叶斯定理由于P(X)对于所有类为常数,最⼤化后验概率P(Ci|X)可转化为最⼤化先验概率P(X|Ci)P(Ci)。

如果训练数据集有许多属性和元组,计算P(X|Ci)的开销可能⾮常⼤,为此,通常假设各属性的取值互相独⽴,这样先验概率P(x1|Ci),P(x2|Ci),…,P(xn|Ci)可以从训练数据集求得。

根据此⽅法,对⼀个未知类别的样本X,可以先分别计算出X属于每⼀个类别Ci的概率P(X|Ci)P(Ci),然后选择其中概率最⼤的类别作为其类别。

朴素贝叶斯算法成⽴的前提是各属性之间互相独⽴。

当数据集满⾜这种独⽴性假设时,分类的准确度较⾼,否则可能较低。

另外,该算法没有分类规则输出。

在所有的机器学习分类算法中,朴素贝叶斯和其他绝⼤多数的分类算法都不同。

机器学习课件 三,贝叶斯学习

机器学习课件 三,贝叶斯学习

贝叶斯理论例
• 后验概率:
P(cancer / ) 0.0078 0.21 0.0078 0.0298
P(cancer / ) 0.0298 0.79 0.0078 0.0298
P(+ ) Cancer
非Cancer
Brute-Force MAP学习器
蛮力
• 对H中每个h,计算:
学习任务的先验 知识,任意概率
em算法在许多实际的学习问题框架中相关实例特征中只有一部分可观察到比如如果某些变量有时能观察到有时不能那么可以用观察到该变量的实例去预测未观察到的实例中的变量的值em算法是存在隐含变量时广泛使用的一种学习方法可用于变量的值从来没有被直接观察到的情形只要这些变量所遵循的概率分布的一般形式已知用于马尔可夫模型的训练估计k个高斯分布的均值考虑d是一个实例集合它由k个不同正态分布的混合所得分布生成单个正态分布的选择基于均匀的概率进行且k个正态分布有相同的方差描述k个分布中每个分布的均值找到极大似然假设即使得pdh最大化的假设估计k个高斯分布的均值2然而现在的问题涉及k个不同正态分布而且不知道哪个实例是哪个分布产生的
|H |
Brute-Force MAP学习器
P(D) P(D | hi )P(hi ) hi H
1 1
0 1
hiVSH ,S
| H | hiVSH ,S
|H |
| VSH ,S | |H |
1
P(h
|
D)
| VSH ,S
|
, h与D一致
0,其他
Brute-Force MAP学习器
未加入训 练数据, 假设概率 相等
朴素贝叶斯分类器
• 决策树、神经网络、最近邻方法之外,最 实用的学习方法

贝叶斯分类器(3)朴素贝叶斯分类器

贝叶斯分类器(3)朴素贝叶斯分类器

贝叶斯分类器(3)朴素贝叶斯分类器根据,我们对贝叶斯分类器所要解决的问题、问题的求解⽅法做了概述,将贝叶斯分类问题转化成了求解P(x|c)的问题,在上⼀篇中,我们分析了第⼀个求解⽅法:极⼤似然估计。

在本篇中,我们来介绍⼀个更加简单的P(x|c)求解⽅法,并在此基础上讲讲常⽤的⼀个贝叶斯分类器的实现:朴素贝叶斯分类器(Naive Bayes classifier)。

1 朴素贝叶斯分类原理1.1 分类问题回顾我们的⽬标是通过对样本的学习来得到⼀个分类器,以此来对未知数据进⾏分类,即求后验概率P(c|x)。

在中,我们描述了贝叶斯分类器是以⽣成式模型的思路来处理这个问题的,如下⾯的公式所⽰,贝叶斯分类器通过求得联合概率P(x,c)来计算P(c|x),并将联合概率P(x,c)转化成了计算类先验概率P(c)、类条件概率P(x|c)、证据因⼦P(x)。

h∗(x)=\argmax c∈Y P(c|x)=\argmax c∈Y P(x,c)P(x)=\argmaxc∈YP(c)∗P(x|c)P(x)其中的难点是类条件概率P(x|c)的计算,因为样本x本⾝就是其所有属性的联合概率,各种属性随意组合,变幻莫测,要计算其中某⼀种组合出现的概率真的是太难了,⽽朴素贝叶斯的出现就是为了解决这个问题的。

要想计算联合概率P(a,b),我们肯定是希望事件a与事件b是相互独⽴的,可以简单粗暴的P(a,b)=P(a)P(b),多想对着流星许下⼼愿:让世界上复杂的联合概率都变成简单的连乘!1.2 朴素贝叶斯朴素贝叶斯实现了我们的梦想!朴素贝叶斯中的朴素就是对多属性的联合分布做了⼀个⼤胆的假设,即x的n个维度之间相互独⽴:P([x1,x2,...,x n]|c)=P(x1|c)P(x2|c)...P(x1|c)朴素贝叶斯通过这⼀假设⼤⼤简化了P(x|c)的计算,当然,使⽤这个假设是有代价的,⼀般情况下,⼤量样本的特征之间独⽴这个条件是弱成⽴的,毕竟哲学上说联系是普遍的,所以我们使⽤朴素贝叶斯会降低⼀些准确性;如果实际问题中的事件的各个属性⾮常不独⽴的话,甚⾄是⽆法使⽤朴素贝叶斯的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
现在我们根据贝叶斯法则重写上面的公式:
������������������������
=
������������������������������������ ������������ ∈{������������������,������������ }
������
������������
������������������������ℎ������������
现在我们需要做的就是计算式3中������ ������������������������ℎ������������ ������������ 和������(������������ )的值,计算������(������������ )的值比较容 易,只需要把训练样例中每个目标属性������������ 出现的概率即可;要计算������ ������������������������ℎ������������ ������������ 的值,需
……………………..1
������������������������
=
������������������������������������ ������ ������������ ∈{������������������,������������ }
������������������������ ℎ������������ ������������ ∗������(������������ )……………….....2
No
表 1:朴素贝叶斯学习起使用的训练样例
我们先计算 P(Vj)的值,Vj 有两个值,yes 和 no: P(yes)=9/14=0.643,P(no)=5/14=0.357。 然后分别计算在目标属性为 yes 和 no 时,测试样例的各个属性的条件概率。注意,我 们在计算各个属性的条件概率时,采用了 m-估计的方法计算。比如在计算 P(sunny|yes)(目 标属性为 yes,Outlook 的属性值为 Sunny 的概率)时,按普通的计算方法: P(sunny|yes)=nc/n=2/9,nc=2 是在训练样例中目标属性为 yes 的条件下 Outlook=sunny 的样例数,n=9 是训练样例中目标属性值为 yes 的样例数; 但是按 m_估计的方法,计算出的概率是: P(sunny|yes)=(nc+m*p)/(n+m)=(2+14*0.33)/(9+14),nc=2 和 n=9 代表的意思和上一样,
四, 朴素贝叶斯学习器代码
朴素贝叶斯学习器的代码很简单,先训练样例统计各个属性的概率,然后根据测试样例 的各个属性值取出对应的概率,并相乘即可,测试结果如下:
朴素贝叶斯学习器完整代码如下: //朴素贝叶斯学习器算法 C 语言代码实现 //Copyright:wxh5055
#include <stdio.h>
//天气类型 typedef enum _outlook {
sunny, overcast, rain }_outlook;
������������
∗ ������ ������������������������������������������������������������������ ������������
∗ ������ ������������������������������������������������ ������������
作者:wxh5055
机器学习-朴素贝叶斯学习
原理分析与 C 语言代码实现
一, 任务介绍
本文介绍朴素贝叶斯学习的基本原理以及其算法实现的 C 语言代码。 朴素贝叶斯学习也叫朴素贝叶斯分类器,它是根据贝叶斯法则进行学习的一种算法。贝 叶斯法则是条件概率相互计算的法则,即在已知 P(A|B)的情况下怎么计算 P(B|A)。P(A|B)是 条件概率,表示在条件 B 成立的条件下条件 A 发生的概率,贝叶斯法则的表达式如下:
有了条件概率的计算公式,我们就可计算出式6中的所有项的值: P(su nny |yes)= 0.290;P(cool |yes)=0.333;P(high |yes)=0.435;P(strong|ye s)=0.435; P(sunny|no)=0.403;P(cool|no)=0.298;P(high|no)=0.579;P(strong|no)=0.526; 所以根据式6: P(vj=yes)=P(yes)* P(sunny|yes)* P(cool|yes)* P(high|yes)* P(strong|yes)=0.0117; P(vj=no)=P(no)* P(sunny|no)* P(cool|no)* P(high|no)* P(strong|no)=0.0131。 所以,该测试样例的朴素贝叶斯分类结果为 PlayTennis=no,因条件概率 P(vj=no)大于条 件概率 P(vj=yes)。 如果把这两个概率进行归一化处理,则 P(vj=yes)=0.473,P(vj=no)=0.528。
}
������
������������������������������������������ , ������������������������������������������������������������������,������������������������������������������������, ������������������������
要作一些相应的假定,即给定目标值时,各属性值之间的相互条件独立。 我们把 weather 用{Outlook, Temperature , Humidity ,Wind}表示,把式3重写为:
������������������������
=
������������������������������������ ������������ ∈{���式4中就得到我们要求的朴素贝叶斯的表达式:
������������������
=
������������������������������������ ������������ ∈{������������������,������������}
������
������������������������������������������
������������������������������������ ������������������������ = ������������ ∈ ������ ������(������������ |������������������������ℎ������������) 称 vMAP 为在给定实例的属性值(weather 的各属性值)下,得到的最可能的目标值,也就 是条件概率最大的值。其中 V={yes,no},也就是说 vMAP 为目标属性集 V 中各取值(yes 或 no) 的概率最大的。朴素贝叶斯学习器即使根据上面的公式推导而来。
Strong
No
D3
Overcast
Hot
High
Weak
Yes
D4
Rain
Mild
High
Weak
Yes
D5
Rain
Cool
Normal
Weak
Yes
D6
Rain
Cool
Normal
Strong
No
D7
Overcast
Cool
Normal
Strong
Yes
D8
Sunny
Mild
High
Weak
No
������ (������������������������ ℎ������������ )
������������������������
=
������������������������������������ ������������ ∈{������������������,������������
weather={Outlook= su nny,Temperature=cool,Humidity=high,Wind s=strong};
Day
Outlook Temperature Humidity
Wind PlayTennis
Dl
Sunny
Hot
High
Weak
No
D2
Sunny
Hot
High
m=14 代表训练样例总数,p=0.33 代表在属性 Outlook 下共有3个属性值,所以这个先验概 率就等于 1/3。
选择 m-估计的原因是为了避免当训练样例数量较小时,训练样例中有可能没有测试样 例中列出的某些属性值,也就是上面的 nc=0,如果按照普通的方法,采用公式nnc ,计算出的 条件概率(比如 P(sunny|yes))就会等于0,这样,根据式6计算出的条件概率因为是相乘的 关系,其值也会为0,这样就会出现对训练样例过拟合的情况。而 m-估计采用公式nnc ++mm∗p的 形式,就可以避免出现过拟合的情况,m 取值一般为训练样例的总数,p 的值如果某个属性 有 k 个可能值,则 p=1/k,如上面 P(sunny|yes)中,因为 Outlook 有3个可能值,所以 p=1/3。
P A B ∗ P(B) P B A = P(A) 即在条件 A 成立的条件下条件 B 发生的概率,等于条件 B 成立的条件下条件 A 发生的 概率,乘以条件 B 发生的概率,再除以条件 A 发生的概率。 朴素贝叶斯学习器(分类器)就是需要计算在某个样例条件下,计算每个目标属性项发生 的概率,然后选出概率最大的目标属性 。举例说明,假设现 在我们在已知某一 天气候的情况 下(用 weather 表示),需要确定是否打网球(用 yes 和 no 表示)。朴素贝叶斯分类器就是要计 算在已知 weather 的条件下,打网球的概率 P(yes|weather)和 P(no|weather),如果前者大于 后者,就去打网球,否则就不去打网球。
相关文档
最新文档