<jupyter_start><jupyter_text>朴素贝叶斯 朴素贝叶斯法的学习与分类 基本方法训练数据集$T=\{(x_1,y_1),(x_1,y_1),\cdots ,(x_N,y_N)\}$由X和Y的联合概率分布*P*(X,Y)独立同分布产生。朴素贝叶斯对条件概率分布做了条件独立性假设，即$$P(X=x|Y=c_k)=P(X^{(1)}=x^{(1)},X^{(2)}=x^{(2)},\cdots,X^{(n)}=x^{(n)}|Y=c_k)\\=\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)$$朴素贝叶斯法实际上学习到生成数据的机制，所以属于生成模型。朴素贝叶斯进行分类时，对于给定输入x，通过学习到的模型计算后验概率分布$P(Y=c_k|X=x)$，将后验概率最大的类作为x的类输出。$$P(Y=c_k|X=x)=\frac{P(X=x|Y=c_k)P(Y=c_k)}{P(X=x)}\\=\frac{P(X=x|Y=c_k)P(Y=c_k)}{\sum_kP(X=x|Y=c_k)P(Y=c_k)}\\=\frac{P(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_kP(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)}$$于是，朴素贝叶斯分类器可以表示为$$y=f(x)=\operatorname{arg}\max_{c_k}\frac{P(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)}{\sum_kP(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)}$$注意到，上式中对所有$c_k$,分母都是相同的，所以可以得到$$y=f(x)=\operatorname{arg}\max_{c_k}P(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)$$ 后验概率最大化的含义假设选择0-1损失函数$$L(Y,f(X))=\begin{cases}1,Y\ne f(X)\\0,Y=f(X)\end{cases}$$其中f(X)是分类决策函数，这时，期望风险函数为$$R_{exp}(f)=E[L(Y,f(X))]$$取条件期望$$R_{exp}(f)=E_X\sum_{k=1}^K[L(c_k,f(X))]P(c_k|X)$$为了使期望风险最小化，只需对X=x逐个最小化，由此得到:$$f(x)=\operatorname{arg}\min_y\sum_{k=1}^K[L(c_k,y)]P(c_k|X=x)\\=\operatorname{arg}\min_y\sum_{k=1}^KP(c_k\ne y|X=x)\\=\operatorname{arg}\min_y\sum_{k=1}^K(1-P(c_k=y|X=x))\\=\operatorname{arg}\max_y\sum_{k=1}^KP(c_k=y|X=x)$$  朴素贝叶斯的参数估计 极大似然估计先验概率$P(Y=c_j)$的极大似然估计为$$P(Y=c_k)=\frac{\sum_{i=1}^NI(y_i=c_k)}{N},\quad k=1,2,\cdots,K$$设第j个特征$x^{(j)}$的可能取值集合为${a_{j1},a_{j2},\cdots,a_{js_j}}$,条件概率$P(X^{(j)=a_{}jl}|Y=c_k)$的极大似然估计为$$P(X^{(j)}|Y=c_k)=\frac{\sum_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)}{\sum_{i=1}^NI(y_i=c_k)}\\j=1,2,\cdots,n;l=1,2,\cdots,S_j;k=1,2,\cdots.K$$ 学习分类算法输入:训练数据$T={(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n)}$,其中$x_i=(x_i^{(1)},x_i^{(2)},\cdots,x_i^{(n)})^T$,$x_i^{(j)}$是第i个样本的第k个特征，$x_i^{(j)}\in\{a_{j1},a_{j2},\cdots,a_{jS_j}\}$;实例x输出:实例x的分类(1)计算先验概率以及条件概率$$P(Y=c_k)=\frac{\sum_{i=1}^NI(y_i=c_k)}{N},\quad k=1,2,\cdots,K\\P(X^{(j)}|Y=c_k)=\frac{\sum_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)}{\sum_{i=1}^NI(y_i=c_k)}\\j=1,2,\cdots,n;l=1,2,\cdots,S_j;k=1,2,\cdots.K$$(2)对于给定实例$x=(x^{(1)},x^{(2)},\cdots,x_i^{(n)})^T$计算$$P(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k), k=1,2,\cdots,K$$(3)确定实例x的类$$y=f(x)=\operatorname{arg}\max_{c_k}P(Y=c_k)\prod^n_{j=1}P(X^{(j)}=x^{(j)}|Y=c_k)$$ 贝叶斯估计极大似然法估计会出现概率为0的情况。这时会影响到后验概率的计算结果，会使分类发生偏差，解决这一问题是采用贝叶斯估计具体地，条件概率的贝叶斯估计是$$P_\lambda(X^{(j)}=a_{jl}|Y=c_k)==\frac{\sum_{i=1}^NI(x_i^{(j)}=a_{jl},y_i=c_k)+\lambda}{\sum_{i=1}^NI(y_i=c_k)+S_j\lambda}$$当$\lambda$=0时，为极大似然估计;当$\lambda$=0时,成为拉普拉斯平滑  高斯贝叶斯朴素贝叶斯的计算时默认特征变量是离散的(例如：性别，尺码，年龄)，但对于连续特征(例如：身高，体重)，我们通常使用高斯模型。该模型被称为高斯模型的原因是假定训练样本集T满足高斯分布，即$$T\sim N(\mu,\Sigma)$$ 基本方法高斯贝叶斯方法同样采用朴素贝叶斯方法的条件独立性假设对于Y子类$c_k$,$X^{(j)}\sim N(\mu_{jk},\sigma_{jk})$$$P(X|Y=c_k)=\prod_{j=1}^n\frac{1}{\sqrt{2\pi}\sigma_{jk}}exp\left(-\frac{(x^{(j)}-\mu_{jk})^2}{2\sigma_{jk}^2}\right)$$其中，$\mu_{jk}$为子类$c_k$下第j维特征的期望，$\sigma_{jk}$为子类$c_k$下第j维特征的标准差。在得到连续变量的条件概率计算方法后，进一步的算法与估计与朴素贝叶斯方法相同，就不在赘述。<jupyter_code>import math
class GaussianBeyes:
    def __init__(self):
        self.model=None
            
    def std(self, X):
        avg=sum(X)/float(len(X))
        stdev=(math.sqrt(sum([math.pow(x-avg,2) for x in X])/float(len(X))))
        return (avg, stdev)
    
    def  feature_cal(self, X):
        return [self.std(i) for i in zip(*X)]#也可以用numpy切片，但是上面没有用ndarray，这里也不默认X为ndarray类型
    
    def Gaussian(self, x, avg, dev):
        return (1/(math.sqrt(2*math.pi)*dev))*math.exp(-(math.pow(x-avg,2)/(2 * math.pow(dev,2))))
    
    
    def fit(self,X,y):
        labels=set(y)#标签集合
        data={label:[] for label in labels} #每个标签对应一个分类
        for x, label in zip(X, y):
            data[label].append(x)#X分组
        
        self.res={
            label:self.feature_cal(value) for label,value in data.items()
        }#存储每个label对应的特征的平均值与标准差
        self.Py={
            label:(float(len(data[label]))/float(len(X))) for label in labels
        }
    #给定一个样本计算概率   
    def prob_cal(self, data):
        probability={}
        for label,value in self.res.items():
            probability[label]=self.Py[label]
            for i in range(len(value)):
                mean,std=value[i]
                probability[label]*=self.Gaussian(data[i], mean, std)
        return  probability
    
    def predict(self, X):
        label=sorted(self.prob_cal(X).items(), key=lambda x:x[-1])[-1][0]#取概率最大对应的label
        return label
    
X=np.array([[60,60],[50,50],[40,40],[40,40],[40,40],[30,30],[60,60],[70,70],[50,50],[90,90],[90,90],[90,90],[170,170],[180,180],[160,160],[170,170]])
y=np.array([0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1])
bayes=GaussianBeyes()
bayes.fit(X,y)
bayes.predict(np.array([120,120]))
bayes.prob_cal(np.array([120,120]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.29847263470513363, 'fraction_numerical': 0.03924480271531608, 'mean_word_length': 6.793388429752066, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '391394', 'license': 'MIT', 'n_tokens_mistral': 2964, 'n_tokens_neox': 3054, 'n_words': 116, 'path': '3.naive Bayes.ipynb', 'repo_name': 'PINE4PPLE/-', 'size': '4714'}