200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 简洁高斯朴素贝叶斯分类原理及python实现

简洁高斯朴素贝叶斯分类原理及python实现

时间:2020-10-29 18:45:07

相关推荐

简洁高斯朴素贝叶斯分类原理及python实现

高斯朴素贝叶斯分类器是针对特征值连续的情况下给出的一种分类方法。

贝叶斯公式

所有的贝叶斯分类器的基石都是概率论中的贝叶斯公式,给定训练数据集 D = { x i , C i } , i = 1 , . . . , N , x i ∈ R D , C i ∈ 1 , . . . , K D=\{x_i,C_i\},i=1,...,N,x_i\in R^D,C_i\in {1,...,K} D={xi​,Ci​},i=1,...,N,xi​∈RD,Ci​∈1,...,K有贝叶斯公式如下: p ( C ∣ x ) = p ( C ) p ( x ∣ C ) p ( x ) , C ∈ { C 1 , C 2 , . . . , C k } p(C|x)=\frac {p(C)p(x|C)}{p(x)},C\in \{C_1,C_2,...,C_k\} p(C∣x)=p(x)p(C)p(x∣C)​,C∈{C1​,C2​,...,Ck​}

其中 p ( C ) p(C) p(C)为分类先验概率, p ( x ∣ C ) p(x|C) p(x∣C)为分类条件分布概率。我们的主要任务就是求得 p ( x ∣ C ) 和 p ( C ) p(x|C)和p(C) p(x∣C)和p(C)。

高斯分布式

在此时我们假设 p ( x ∣ C ) p(x|C) p(x∣C)是服从高斯分布的,对任意 x i ∈ ( x 1 , x 2 , . . . , x D ) T x_i\in(x_1,x_2,...,x_D)^T xi​∈(x1​,x2​,...,xD​)T是相互独立的并且均服从高斯分布:

p ( x ∣ C ) = 1 2 π σ c e x p [ − ( x − μ c ) 2 2 σ c 2 ] p(x|C)=\frac {1}{\sqrt {2\pi}\sigma_c}exp[- \frac{(x-\mu_c)^2}{2\sigma_c^2} ] p(x∣C)=2π ​σc​1​exp[−2σc2​(x−μc​)2​]

其中 μ c 和 σ c \mu_c和\sigma_c μc​和σc​分别为各特征的平均值和标准差。

最终分类条件概率可写成:

p ( x ∣ C ) = ∏ d = 1 D p ( x i ∣ C ) = ∏ d = 1 D 1 2 π σ c d e x p [ − ( x − μ c d ) 2 2 ( σ c d ) 2 ] p(x|C)=\prod_{d=1}^Dp(x_i|C)=\prod_{d=1}^D\frac {1}{\sqrt{2\pi}\sigma_c^d}exp[- \frac{(x-\mu_c^d)^2}{2(\sigma_c^{d})^2}] p(x∣C)=d=1∏D​p(xi​∣C)=d=1∏D​2π ​σcd​1​exp[−2(σcd​)2(x−μcd​)2​]

那么最终得到的预测分类结果就是:

C = arg max ⁡ c p ( C ∣ x ) C=\argmax_c{p(C|x)} C=cargmax​p(C∣x)

算法流程

明确了高斯朴素贝叶斯分类器的原理以及计算过程,那么我们很容易得到其算法流程如下:

准备数据集,分离出feature集以及label集,并根据label集计算先验概率p(C)训练模型,根据training dataset计算各特征向量的平均值及标准差预测分类,根据输入特征向量计算出所有特征对应的p(x|C)p(C)即k*p(x|C),这里由于分母均相同,所以直接忽略计算分母求argmax(k*p(x|C))=argmax(p(x|C))

python实现

花的分类问题:

数据集:数据集链接

import numpy as npimport collections#高斯朴素贝叶斯类class GuassianNB:def __init__(self):self.prior = None #先验概率self.avgs = None #均值self.vars = None #方差值self.nums = None # 特征值数量#计算先验概率def _get_prior(self, label: np.array)->dict:cnt = collections.Counter(label)a = {}for k,v in cnt.items():a[k]=v/len(label)return a#计算均值def _get_avgs(self,data:np.array,label:np.array)->np.array:return np.array([data[label == i].mean(axis=0) for i in self.nums])#计算方差def _get_vars(self,data:np.array,label:np.array)->np.array:return np.array([data[label == i].var(axis=0) for i in self.nums])#计算似然度def _get_likelihood(self,row:np.array)->np.array:return (1 / np.sqrt(2 * np.pi * self.vars) * np.exp(-(row - self.avgs) ** 2 / (2 * self.vars))).prod(axis=1)#训练数据集def fit(self, data: np.array, label: np.array):self.prior = self._get_prior(label)print(self.prior)a=[]for key in self.prior.keys():a.append(key)self.nums = aself.avgs = self._get_avgs(data, label)self.vars = self._get_vars(data, label)#预测labeldef predict_prob(self, data: np.array) -> np.array:likelihood = np.apply_along_axis(self._get_likelihood, axis=1, arr=data)print(likelihood)a = []for key in self.prior.keys():a.append(self.prior[key])probs = np.array(a) * likelihoodprint(probs)probs_sum = probs.sum(axis=1)return probs / probs_sum[:, None]#预测结果def predict(self, data: np.array) -> np.array:return self.predict_prob(data).argmax(axis=1)def main():origin_dataset = np.loadtxt('iris.txt',dtype=str,delimiter=',')np.random.shuffle(origin_dataset)feature_dataset = [] #特征集label_dataset = [] #标签集feature_dataset_test = [] #测试集label_dataset_test = [] #测试结果集for i in range(int(len(origin_dataset)*0.8)):feature_dataset.append(origin_dataset[i][0:4])label_dataset.append(origin_dataset[i][4])for i in range(int(len(origin_dataset)*0.8),len(origin_dataset)):feature_dataset_test.append(origin_dataset[i][0:4])label_dataset_test.append(origin_dataset[i][4])# print(feature_dataset)# print("--------------------------")# print(label_dataset)feature_dataset = np.array(feature_dataset,dtype=float)label_dataset = np.array(label_dataset,dtype=str)feature_dataset_test = np.array(feature_dataset_test,dtype=float)label_dataset_test = np.array(label_dataset_test,dtype=str)# print(feature_dataset)# print(label_dataset)nb = GuassianNB()nb.fit(feature_dataset,label_dataset) #训练模型# print(nb.avgs)# print(nb.nums)# print(nb.prior)# print(nb.vars)test_result = nb.predict(feature_dataset_test)print(test_result)acc = 0for i in range(len(test_result)):if nb.nums[test_result[i]] == label_dataset_test[i]:acc+=1print("精确度:"+str(acc/len(test_result)))if __name__ == '__main__':main()

预测结果:

精确度基本可达90%以上。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。