机器学习之朴素贝叶斯原理及python实现
朴素贝叶斯
朴素贝叶斯法是基于贝叶斯定理于特征独立假设的一类生成算法
1. 朴素贝叶斯原理
1.1 以一个垃圾邮件分类的例子开始有样本如下:
邮件一:x(1)=(明天,早上,参加,早会)x^{(1)} = (明天, 早上, 参加, 早会)x(1)=(明天,早上,参加,早会) 分类:y(1)=正常邮件y^{(1)}=正常邮件y(1)=正常邮件
邮件二:x(2)=(希望,明天,听到,好消息)x^{(2)} = (希望, 明天, 听到, 好消息)x(2)=(希望,明天,听到,好消息) 分类:y(2)=正常邮件y^{(2)} = 正常邮件y(2)=正常邮件
邮件三:x(3)=(欢迎,明天,订阅,购买)x^{(3)} = (欢迎, 明天, 订阅, 购买)x(3)=(欢迎,明天,订阅,购买) 分类:y(3)=垃圾邮件y^{(3)} = 垃圾邮件y(3)=垃圾邮件
邮件四 : x(4)=(听到,我们的,产品)x^{(4)} = (听到, 我们的, 产品)x(4)=(听到,我们的,产品) 分类:y(4)=垃圾邮件y^{(4)} = 垃圾邮件y(4)=垃圾邮件
如上面例子所示:
训练样本的输入数据可以表示为:X=(x(1),x(2),...,x(N))X = (x^{(1)}, x^{(2)}, ...,x^{(N)})X=(x(1),x(2),...,x(N))
训练样本的输出数据可以表示为:Y=(y(1),y(2),...,y(N))Y = (y^{(1)}, y^{(2)},..., y^{(N)})Y=(y(1),y(2),...,y(N))
其中:
x(1)=(x1(1),x2(1),...,xM1(1))x^{(1)} = (x_1^{(1)}, x_2^{(1)},...,x_{M_1}^{(1)})x(1)=(x1(1),x2(1),...,xM1(1))
x(2)=(x1(2),x2(2,...,xM2(2))x^{(2)} = (x_1^{(2)}, x_2^{(2},...,x_{M_2}^{(2)})x(2)=(x1(2),x2(2,...,xM2(2))
x(N)=(x1(N),x2(N),...,xMN(N))x^{(N)} = (x_1^{(N)}, x_2^{(N)},...,x_{M_N}^{(N)})x(N)=(x1(N),x2(N),...,xMN(N))
其中x(n)x^{(n)}x(n)代表第nnn个样本的输入数据,xmn(n)x_{m_n}^{(n)}xmn(n)代表第nnn个样本的第mmm个元素。
设有KKK个输出类别:C={c1,c2,...,cK}C = \{c_1,c_2,...,c_K\}C={c1,c2,...,cK}
实例中:C={正常邮件,垃圾邮件}C=\{正常邮件,垃圾邮件 \}C={正常邮件,垃圾邮件}
样本空间可以描述为:
T={(x(1),y(1)),(x(2),y(2)),...,(x(N),y(N))}(1)T = \{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(N)},y^{(N)})\} \tag{1}T={(x(1),y(1)),(x(2),y(2)),...,(x(N),y(N))}(1)
目标是求所有文档的最大似然概率:
p(T)=∏n=1Np(x(n),y(n))=∏n=1Np(x(n)∣y(n))p(y(n))=∏n=1Np(x1(n),x2(n),...,xMn(n)∣y(n))p(y(n))(2)p(T) = \prod_{n=1}^N p(x^{(n)}, y^{(n)}) = \prod_{n=1}^N p(x^{(n)}| y^{(n)}) p(y^{(n)}) = \prod_{n=1}^N p(x_1^{(n)}, x_2^{(n)},...,x_{M_n}^{(n)}| y^{(n)}) p(y^{(n)}) \tag{2}p(T)=n=1∏Np(x(n),y(n))=n=1∏Np(x(n)∣y(n))p(y(n))=n=1∏Np(x1(n),x2(n),...,xMn(n)∣y(n))p(y(n))(2)
1.2 求解目标函数的参数由朴素贝叶斯的条件独立假设得到:
p(T)=∏n=1N(x1(n)∣y(n))p(x2(n)∣y(n)),...,p(xMn(n)∣y(n))p(y(n))=∏n=1N∏m=1Mnp(xm(n)∣y(n))p(y(n))(3)p(T) = \prod_{n=1}^N (x_1^{(n)} |y^{(n)}) p( x_2^{(n)}|y^{(n)}),...,p(x_{M_n}^{(n)}| y^{(n)}) p(y^{(n)}) = \prod_{n=1}^N \prod_{m=1}^{Mn} p(x_m^{(n)}| y^{(n)}) p(y^{(n)}) \tag{3}p(T)=n=1∏N(x1(n)∣y(n))p(x2(n)∣y(n)),...,p(xMn(n)∣y(n))p(y(n))=n=1∏Nm=1∏Mnp(xm(n)∣y(n))p(y(n))(3)
其中p(xm(n)∣y(n))p(x_m^{(n)}| y^{(n)})p(xm(n)∣y(n))表示的含义是对于第nnn个样本而言,在已知输出标签的情况下,输入数据的第mmm个元素出现的概率。为了后面继续化简,可以做以下假设:
设:输入数据XXX中所有元素的集合为V=v1,v2,...,vWV={v_1,v_2,...,v_W}V=v1,v2,...,vW,即共有WWW个不同的元素;αw(n)\alpha_w^{(n)}αw(n)表示VVV中第www个元素在第nnn个样本中出现的次数。
则(3)式就可以表示为:
p(T)=∏n=1N∏w=1Wp(vw(n)∣y(n))αw(n)p(y(n))(4)p(T) = \prod_{n=1}^N \prod_{w=1}^{W} p(v_w^{(n)}| y^{(n)})^{\alpha_w^{(n)}} p(y^{(n)}) \tag{4}p(T)=n=1∏Nw=1∏Wp(vw(n)∣y(n))αw(n)p(y(n))(4)
又有输出类别集合C={c1,c2,...,cK}C = \{c_1,c_2,...,c_K\}C={c1,c2,...,cK},设βk(n)\beta_k^{(n)}βk(n)表示第nnn个样本是否属于第ckc_kck类,如果是则为1,否则为0.
所以(4)式又可以表示为:
p(T)=∏n=1N∏w=1W∏c=1Kp(vw(n)∣y(n)=ck)αw(n)∗βk(n)p(y(n)=ck)βk(n)(5)p(T) = \prod_{n=1}^N \prod_{w=1}^{W} \prod_{c=1}^K p(v_w^{(n)}| y^{(n)}=c_k)^{\alpha_w^{(n)} * \beta_k^{(n)}} p(y^{(n)} = c_k)^{\beta_k^{(n)}} \tag{5}p(T)=n=1∏Nw=1∏Wc=1∏Kp(vw(n)∣y(n)=ck)αw(n)∗βk(n)p(y(n)=ck)βk(n)(5)
对上式求对数:
logp(T)=∑n=1N∑w=1W∑c=1K[(αw(n)∗βk(n))logp(vw(n)∣y(n)=ck)+βk(n)logp(y(n)=ck)](6)\log p(T) = \sum_{n=1}^N \sum_{w=1}^{W} \sum_{c=1}^K [(\alpha_w^{(n)} * \beta_k^{(n)}) \log p(v_w^{(n)}| y^{(n)}=c_k) + \beta_k^{(n)} \log p(y^{(n)} = c_k)] \tag{6}logp(T)=n=1∑Nw=1∑Wc=1∑K[(αw(n)∗βk(n))logp(vw(n)∣y(n)=ck)+βk(n)logp(y(n)=ck)](6)
到这一步就得到了我们想要求解的目标函数,目标就是:
maxlogp(T)\max \log p(T)maxlogp(T)
需要求解的参数分别就是∑n=1Np(vw(n)∣y(n)=ck)\sum_{n=1}^N p(v_w^{(n)}| y^{(n)}=c_k)∑n=1Np(vw(n)∣y(n)=ck)和∑n=1Np(y(n)=ck)\sum_{n=1}^N p(y^{(n)} = c_k)∑n=1Np(y(n)=ck), 为了方便表示,设:
γwk=∑n=1Np(vw(n)∣y(n)=ck)(7)\gamma_{wk} = \sum_{n=1}^N p(v_w^{(n)}| y^{(n)}=c_k) \tag{7}γwk=n=1∑Np(vw(n)∣y(n)=ck)(7)
ξk=∑n=1Np(y(n)=ck)(8)\xi_k = \sum_{n=1}^N p(y^{(n)} = c_k) \tag{8}ξk=n=1∑Np(y(n)=ck)(8)
则求:
maxγwk,ξk∑n=1N∑w=1W∑c=1K[(αw(n)∗βk(n))logγwk(n)+βk(n)logξk(n)](9)\max_{\gamma_{wk},\xi_k} \sum_{n=1}^N \sum_{w=1}^{W} \sum_{c=1}^K [(\alpha_w^{(n)} * \beta_k^{(n)}) \log \gamma_{wk}^{(n)}+ \beta_k^{(n)} \log \xi_k^{(n)}] \tag{9}γwk,ξkmaxn=1∑Nw=1∑Wc=1∑K[(αw(n)∗βk(n))logγwk(n)+βk(n)logξk(n)](9)
1.求解ξk\xi_kξk:
有(9)式可以得到:
∑n=1N∑c=1Kβk(n)logξk(n) \sum_{n=1}^N \sum_{c=1}^K \beta_k^{(n)} \log \xi_k^{(n)}n=1∑Nc=1∑Kβk(n)logξk(n)
注意到约束条件∑c=1Kξk=1\sum_{c=1}^K \xi_k = 1∑c=1Kξk=1,利用拉格朗日乘子法,写出拉格朗日函数:
∑n=1N∑c=1Kβk(n)logξk(n)+λ(∑c=1Kξk−1) \sum_{n=1}^N \sum_{c=1}^K \beta_k^{(n)} \log \xi_k^{(n)} + \lambda(\sum_{c=1}^K \xi_k - 1)n=1∑Nc=1∑Kβk(n)logξk(n)+λ(c=1∑Kξk−1)
求其偏导数等于0得:
∂∂ξk[∑n=1N∑c=1Kβk(n)logξk(n)+λ(∑c=1Kξk−1)]=0\frac {\partial}{\partial \xi_k}[ \sum_{n=1}^N \sum_{c=1}^K \beta_k^{(n)} \log \xi_k^{(n)} + \lambda(\sum_{c=1}^K \xi_k - 1) ]= 0∂ξk∂[n=1∑Nc=1∑Kβk(n)logξk(n)+λ(c=1∑Kξk−1)]=0
得到:
∑n=1Nβk(n)∑n=1Nξk(n)+λ=0\frac {\sum_{n=1}^N \beta_k^{(n)}} {\sum_{n=1}^N \xi_k^{(n)}} + \lambda = 0∑n=1Nξk(n)∑n=1Nβk(n)+λ=0
则:
ξk=∑n=1Nβk(n)−λ\xi_k = \frac {\sum_{n=1}^N \beta_k^{(n)}} {- \lambda} ξk=−λ∑n=1Nβk(n)
将上式带入∑c=1Kξk=1\sum_{c=1}^K \xi_k = 1∑c=1Kξk=1:
−λ=∑c=1K∑n=1Nβk(n)=N- \lambda = \sum_{c=1}^K \sum_{n=1}^N \beta_k^{(n)} = N−λ=c=1∑Kn=1∑Nβk(n)=N
最后得到:
ξk=∑n=1Nβk(n)N(10)\xi_k = \frac {\sum_{n=1}^N \beta_k^{(n)}} {N} \tag{10}ξk=N∑n=1Nβk(n)(10)
上式的物理意义:
左边:ξk\xi_kξk表示kkk类的概率,这个属于先验概率
右边:所有标签中属于kkk类的数目除以总的样本数目。
实例中ξk=垃圾邮件=1/2\xi_{k=垃圾邮件} = 1/2ξk=垃圾邮件=1/2
2.求解γwk\gamma_{wk}γwk:
由(9)式可以得到:
∑n=1N∑w=1W∑c=1Kαw(n)∗βk(n)logγwk(n) \sum_{n=1}^N \sum_{w=1}^{W} \sum_{c=1}^K \alpha_w^{(n)} * \beta_k^{(n)} \log \gamma_{wk}^{(n)}n=1∑Nw=1∑Wc=1∑Kαw(n)∗βk(n)logγwk(n)
注意到约束条件∑w=1Wγwk=1\sum_{w=1}^W \gamma_{wk} = 1∑w=1Wγwk=1,利用拉格朗日乘子法,写出拉格朗日函数:
∑n=1N∑w=1W∑c=1Kαw(n)∗βk(n)logγwk(n)+λ(∑w=1Wγwk−1) \sum_{n=1}^N \sum_{w=1}^{W} \sum_{c=1}^K \alpha_w^{(n)} * \beta_k^{(n)} \log \gamma_{wk}^{(n)} + \lambda (\sum_{w=1}^W \gamma_{wk} - 1) n=1∑Nw=1∑Wc=1∑Kαw(n)∗βk(n)logγwk(n)+λ(w=1∑Wγwk−1)
求其偏导等于0得:
∂∂γwk[∑n=1N∑w=1W∑c=1Kαw(n)∗βk(n)logγwk(n)+λ(∑w=1Wγwk−1)]=0\frac {\partial} {\partial \gamma_{wk}} [ \sum_{n=1}^N \sum_{w=1}^{W} \sum_{c=1}^K \alpha_w^{(n)} * \beta_k^{(n)} \log \gamma_{wk}^{(n)} + \lambda (\sum_{w=1}^W \gamma_{wk} - 1)] = 0∂γwk∂[n=1∑Nw=1∑Wc=1∑Kαw(n)∗βk(n)logγwk(n)+λ(w=1∑Wγwk−1)]=0
得到:
∑n=1Nαw(n)∗βk(n)∑n=1Nγwk(n)+λ=0\frac { \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)} }{ \sum_{n=1}^N \gamma_{wk}^{(n)}} + \lambda = 0∑n=1Nγwk(n)∑n=1Nαw(n)∗βk(n)+λ=0
则:
γwk=∑n=1Nαw(n)∗βk(n)−λ\gamma_{wk} = \frac { \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)} }{- \lambda} γwk=−λ∑n=1Nαw(n)∗βk(n)
将上式带入∑w=1Wγwk=1\sum_{w=1}^W \gamma_{wk} = 1∑w=1Wγwk=1得到:
−λ=∑w=1W∑n=1Nαw(n)∗βk(n)- \lambda = \sum_{w=1}^W \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)}−λ=w=1∑Wn=1∑Nαw(n)∗βk(n)
最后求得:
γwk=∑n=1Nαw(n)∗βk(n)∑w=1W∑n=1Nαw(n)∗βk(n)(11)\gamma_{wk} = \frac { \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)} }{\sum_{w=1}^W \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)}} \tag{11}γwk=∑w=1W∑n=1Nαw(n)∗βk(n)∑n=1Nαw(n)∗βk(n)(11)
1.3 拉普拉斯平滑处理上式表示的运算是:第kkk类中第www个单词的个数除以第kkk个类中的所有单词个数
用极大似然估计会出现概率为0的情况,可以使用拉普拉斯平滑处理。
(10)式可以表示为:
ξk=∑n=1Nβk(n)+λN+Kλ(12)\xi_k = \frac {\sum_{n=1}^N \beta_k^{(n)} + \lambda} {N + K\lambda} \tag{12}ξk=N+Kλ∑n=1Nβk(n)+λ(12)
(11)式可以表示为:
γwk=∑n=1Nαw(n)∗βk(n)+λ∑w=1W∑n=1Nαw(n)∗βk(n)+Wλ(13)\gamma_{wk} = \frac { \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)} + \lambda} {\sum_{w=1}^W \sum_{n=1}^N \alpha_w^{(n)} * \beta_k^{(n)} + W \lambda} \tag{13}γwk=∑w=1W∑n=1Nαw(n)∗βk(n)+Wλ∑n=1Nαw(n)∗βk(n)+λ(13)
得到(12)(13)式仍然分别满足∑c=1Kξk=1\sum_{c=1}^K \xi_k = 1∑c=1Kξk=1和∑w=1Wγwk=1\sum_{w=1}^W \gamma_{wk} = 1∑w=1Wγwk=1。
2. 朴素贝叶斯python实现
2.1 模型实现import numpy as np class MyNaiveBayes(object): def __init__(self, laplace=1): """ 朴素贝叶斯 :param laplace: 拉普拉斯平滑项,默认值为1 :param N: 输入样本的个数 :param W: 输入样本的元素集合数目 :param K: 输入标签类的数目 :param V: 输入样本的元素集合 :param C: 输入标签的类的集合 模型参数 :param xi: 参数,先验概率,表示每一类别概率,维度(K,) :param gamma: 参数,条件概率,表示单词在一个类别中的概率,维度(K, W) """ self.laplace = laplace self.params = { 'xi': None, 'gamma': None } self.N = None self.V = None self.C = None self.W = None self.K = None self.is_adding_lambda = True # 是否应用拉普拉斯平滑 def _init_params(self): """ 初始化模型参数 :return: None """ xi = np.zeros(self.K) gamma = np.zeros((self.K, self.W)) self.params['xi'] = xi self.params['gamma'] = gamma def fit(self, X, y, V, C): """ 输入样本,训练模型 :param X: 训练输入输入(N, M_N) :param y: 训练输入标签(N) :param V: 输入样本的元素集合 :param C: 输入标签的类的集合 :return: None """ X = np.array(X) y = np.array(y) self.N = len(X) self.V = V self.C = C self.W = len(V) self.K = len(C) self._init_params() for c in C: if self.is_adding_lambda: self.params['xi'][c] = ((y == c).sum() + self.laplace) / (self.N + self.K * self.laplace) else: self.params['xi'][c] = (y == c).sum() / self.N split_x = [[] for _ in range(self.K)] for x_s, y_s in zip(X, y): for c in C: if y_s == c: split_x[c].extend(x_s) split_x = np.array([np.array(x) for x in split_x]) for c in C: for v in V: if self.is_adding_lambda: self.params['gamma'][c][v] = ((np.array(split_x[c]) == v).sum() + self.laplace) / (split_x[c].sum() + self.W * self.laplace) else: self.params['gamma'][c][v] = (np.array(split_x[c]) == v).sum() / split_x[c].sum() def predict(self, X): """ 求取对数似然最大的一个标签 :param X: 输出数据 :return: 最大概率的标签 """ result_list = np.zeros(self.K) for c in self.C: result_list[c] = np.log(self.params['xi'][c]) # 先加入先验概率的对数 for x_s in X: # 后加入每个单词的条件概率 result_list[c] += np.log(self.params['gamma'][c][x_s]) return np.argmax(result_list)2.1 模型测试
def generate_data(): O = [['明天', '早上', '参加', '早会'], ['希望', '明天', '听到', '好消息'], ['欢迎', '明天', '订阅', '购买'], ['听到', '我们的', '产品']] word2index = {} index2word = {} for sentence in O: for word in sentence: if word not in word2index.keys(): word2index[word] = len(word2index) index2word[len(index2word)] = word print(word2index) print(index2word) O_input = [] for sentence in O: O_input.append([word2index[word] for word in sentence]) print(O_input) C = ['正常邮件', '垃圾邮件'] C_input = [0, 1] V = [i for i in range(len(word2index))] y = [0, 0, 1, 1] return O_input, y, V, C_input def run_my_model(): X, y, V, C = generate_data() my = MyNaiveBayes() my.fit(X, y, V, C) X_test = [4, 1, 2] y_test = my.predict(X_test) print(y_test)
输出结果为:
0
- scikit-learn机器学习(六)--朴素贝叶斯分类原理及python实现
- [(机器学习)概率统计]极大似然估计MLE原理+python实现
- <基础原理进阶>机器学习算法python实现【3】--文本分析之朴素贝叶斯分类器
- 机器学习(4):BP神经网络原理及其python实现
- 机器学习—— 基于朴素贝叶斯分类算法构建文本分类器的Python实现
- 机器学习:K-近邻算法原理与Python代码实现
- 机器学习之朴素贝叶斯算法原理与代码实现
- 机器学习:IDE3决策树(原理+python实现)
- 机器学习笔记(一)朴素贝叶斯的Python代码实现
- 机器学习经典算法详解及Python实现---朴素贝叶斯分类及其在文本分类、垃圾邮件检测中的应用
- 机器学习-朴素贝叶斯(python3代码实现)
- 机器学习笔记:朴素贝叶斯方法(Naive Bayes)原理和实现
- 朴素贝叶斯分类算法原理与Python实现与使用方法案例
- 机器学习实战笔记(五):基于概率论的分类方法: 朴素贝叶斯(Python3 实现)
- 机器学习决策树的Python实现详细流程及原理解读_1
- 机器学习之朴素贝叶斯(NB)分类算法与Python实现
- 分类算法-----朴素贝叶斯原理和python实现
- Python实现基于朴素贝叶斯的垃圾邮件分类 标签: python朴素贝叶斯垃圾邮件分类 2016-04-20 15:09 2750人阅读 评论(1) 收藏 举报 分类: 机器学习(19) 听说
- 机器学习决策树的Python实现详细流程及原理解读_2
- 【机器学习之统计学习】 朴素贝叶斯法及sklearn库python实现