机器学习本科课程 实验5 贝叶斯分类

实验1.使用sklearn的GaussianNB、BernoulliNB、MultinomialNB完成肿瘤预测任务

实验内容:

  1. 使用GaussianNB、BernoulliNB、MultinomialNB完成肿瘤预测
  2. 计算各自十折交叉验证的精度、查准率、查全率、F1值
  3. 根据精度、查准率、查全率、F1值的实际意义以及四个值的对比阐述三个算法在肿瘤预测中的表现对比

1. 读取数据集

python 复制代码
import pandas as pd
import numpy as np
data = pd.read_csv('./breast-cancer.csv')
data = data.replace({'B': 1, 'M': -1})
data = data.values 
data_x = data[:,2:]
data_y = data[:,1:2].ravel()

2. 导入模型

python 复制代码
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import BernoulliNB
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score

3. 计算十折交叉验证下,GaussianNB、BernoulliNB、MultinomialNB的精度、查准率、查全率、F1值

python 复制代码
model = GaussianNB()
prediction = cross_val_predict(model, data_x, data_y, cv=10)

acc = accuracy_score(data_y, prediction)
precision = precision_score(data_y, prediction)
recall = recall_score(data_y, prediction)
f = f1_score(data_y, prediction)

print("GaussianNB在测试集上的四项指标")
print("精度:",acc)
print("查准率:",precision)
print("查全率:",recall)
print("f1值:",f)

model12 = BernoulliNB()
prediction12 = cross_val_predict(model12, data_x, data_y, cv=10)

acc12 = accuracy_score(data_y, prediction12)

precision12 = precision_score(data_y, prediction12)

recall12 = recall_score(data_y, prediction12)

f12 = f1_score(data_y, prediction12)
print("BernoulliNB在测试集上的四项指标")
print("精度:",acc12)
print("查准率:",precision12)
print("查全率:",recall12)
print("f1值:",f12)

model13 = MultinomialNB()
prediction13 = cross_val_predict(model13, data_x, data_y, cv=10)

acc13 = accuracy_score(data_y, prediction13)

precision13 = precision_score(data_y, prediction13)

recall13 = recall_score(data_y, prediction13)

f13 = f1_score(data_y, prediction13)
print("MultinomialNB在测试集上的四项指标")
print("精度:",acc13)
print("查准率:",precision13)
print("查全率:",recall13)
print("f1值:",f13)

实验2.实现一个高斯朴素贝叶斯分类器

实验内容:

  1. 实现高斯朴素贝叶斯分类器
  2. 计算模型的查准率,查全率,F1值

我们要实现一个可以处理连续特征的,服从高斯分布的朴素贝叶斯分类器

符号

给定训练集 T T T

T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋅ ⋅ ⋅ , ( x N , y N ) } T = \{(x_1, y_1), (x_2, y_2), ···, (x_N, y_N)\} T={(x1,y1),(x2,y2),⋅⋅⋅,(xN,yN)}

其中, x x x 为样本的特征, y y y 是该样本对应的标记,下标表示对应的是第几个样本,上标表示第几个特征。训练集 T T T 内一共 ∣ T ∣ = N \vert T \vert = N ∣T∣=N 个样本。

假设我们的任务是处理 K K K 类分类任务,记类标记分别为 c 1 , c 2 , . . . , c k c_1, c_2, ..., c_k c1,c2,...,ck 。

目标

我们的目标是对样本进行分类,这里我们用概率的方法,求 P ( Y = c k ∣ X = x ) , k = 1 , 2 , . . . , K P(Y = c_k \mid X = x), \ k = 1, 2, ..., K P(Y=ck∣X=x), k=1,2,...,K 中最大的那个概率对应的 k k k 是哪个,也就是,给定样本 x x x ,模型认为它是哪个类别的概率最大。

原理

由贝叶斯公式:

P ( Y = c k ∣ X = x ) = P ( Y = c k , X = x ) P ( X = x ) = P ( X = x ∣ Y = c k ) P ( Y = c k ) ∑ k P ( X = x ∣ Y = c k ) P ( Y = c k ) \begin{aligned} P(Y = c_k \mid X = x) &= \frac{P(Y = c_k, X = x)}{P(X = x)} \\ &= \frac{P(X = x \mid Y = c_k)P(Y = c_k)}{\sum_kP(X = x \mid Y = c_k)P(Y = c_k)} \\ \end{aligned} P(Y=ck∣X=x)=P(X=x)P(Y=ck,X=x)=∑kP(X=x∣Y=ck)P(Y=ck)P(X=x∣Y=ck)P(Y=ck)

这里,我们要求 K K K 个概率中最大的那个,而这 K K K 个概率的分母都相同,我们可以忽略分母部分,比较分子部分的大小,也就是比较 先验概率 P ( Y = c k ) P(Y = c_k) P(Y=ck) 和 似然 P ( X = x ∣ Y = c k ) P(X = x \mid Y = c_k) P(X=x∣Y=ck) 的乘积。

通过先验概率分布

P ( Y = c k ) , k = 1 , 2 , . . . , K P(Y = c_k), \ k = 1, 2, ..., K P(Y=ck), k=1,2,...,K

和条件概率分布

P ( X = x ∣ Y = c k ) = P ( X ( 1 ) = x ( 1 ) , ⋅ ⋅ ⋅ , X ( n ) = x ( n ) ∣ Y = c k ) , k = 1 , 2 , . . . , K P(X = x \mid Y = c_k) = P(X^{(1)} = x^{(1)}, ···, X^{(n)} = x^{(n)} \mid Y = c_k), \ k = 1, 2, ..., K P(X=x∣Y=ck)=P(X(1)=x(1),⋅⋅⋅,X(n)=x(n)∣Y=ck), k=1,2,...,K

我们就可以得到联合概率分布 P ( X = x , Y = c k ) P(X = x, Y = c_k) P(X=x,Y=ck) 。

1. 先验概率 P ( Y = c k ) P(Y = c_k) P(Y=ck) :

先验概率的求解很简单,只要统计训练集中类别 k k k 出现的概率即可。

P ( Y = c k ) = n u m b e r o f c k N P(Y = c_k) = \frac{\mathrm{number} \ \mathrm{of}\ c_k}{N} P(Y=ck)=Nnumber of ck

2. 似然 P ( X = x ∣ Y = c k ) P(X = x \mid Y = c_k) P(X=x∣Y=ck) :

求解这个条件概率比较复杂,这里我们要假设特征之间相互独立,可得

P ( X = x ∣ Y = c k ) = ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) P(X = x \mid Y = c_k) = \prod^n_{j=1}P(X^{(j)}=x^{(j)} \mid Y = c_k) P(X=x∣Y=ck)=j=1∏nP(X(j)=x(j)∣Y=ck)

其中, x ( j ) x^{(j)} x(j) 表示样本 x x x 的第 j j j 个特征。

这样,复杂的条件概率就转换为了多个特征条件概率的乘积。

3. 特征 j j j 的条件概率 P ( X ( j ) = x ( j ) ∣ Y = c k ) P(X^{(j)}=x^{(j)} \mid Y = c_k) P(X(j)=x(j)∣Y=ck) :

因为我们处理的特征都是连续型特征,一般我们假设这些特征服从正态分布。

当 Y = c k Y = c_k Y=ck 时, X ( j ) = a j l X^{(j)} = a_{jl} X(j)=ajl 的概率可由下面的公式计算得到:

P ( X ( j ) = a j l ∣ Y = c k ) = 1 2 π σ c k , j 2 exp ⁡ ( − ( a j l − μ c k , j ) 2 2 σ c k , j 2 ) P(X^{(j)} = a_{jl} \mid Y = c_k) = \frac{1}{\sqrt{2 \pi \sigma^2_{c_k,j}}} \exp{\bigg( - \frac{(a_{jl} - \mu_{c_k,j})^2}{2 \sigma^2_{c_k,j}} \bigg)} P(X(j)=ajl∣Y=ck)=2πσck,j2 1exp(−2σck,j2(ajl−μck,j)2)

这里 μ c k , j \mu_{c_k,j} μck,j 和 σ c k , j 2 \sigma^2_{c_k,j} σck,j2 分别表示当 Y = c k Y = c_k Y=ck 时,第 j j j 个特征的均值和方差,这个均值和方差都是通过训练集的样本计算出来的

因为正态分布只需要两个参数(均值和方差)就可以确定,对于特征 j j j 我们要估计 K K K 个类别的均值和方差,所以特征 j j j 的参数共有 2 K 2K 2K个。

综上

朴素贝叶斯分类器可以表示为:

y = arg ⁡ max ⁡ c k P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) ∣ Y = c k ) y = \mathop{\arg\max}_{c_k} P(Y = c_k) \prod_j P(X^{(j)} = x^{(j)} \mid Y = c_k) y=argmaxckP(Y=ck)j∏P(X(j)=x(j)∣Y=ck)

实现

实现的时候会遇到数值问题,在上面的条件概率连乘中,如果有几个概率值很小,它们的连乘就会导致下溢,解决方案就是将其改写为连加的形式。

首先,我们的目标是:

y = arg ⁡ max ⁡ c k P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) ∣ Y = c k ) y = \mathop{\arg\max}_{c_k} P(Y = c_k) \prod_j P(X^{(j)} = x^{(j)} \mid Y = c_k) y=argmaxckP(Y=ck)j∏P(X(j)=x(j)∣Y=ck)

比较这 K K K 个数值的大小,然后取最大的那个数对应的 k k k。

为了解决可能出现的下溢问题,我们对上面的式子取对数,因为是对 K K K 项都取对数,不会改变单调性,所以取对数是不影响它们之间的大小关系的。

那目标就变成了:

y = arg ⁡ max ⁡ c k [ log ⁡ P ( Y = c k ) ∏ j P ( X ( j ) = x ( j ) ∣ Y = c k ) ] = arg ⁡ max ⁡ c k [ log ⁡ P ( y = c k ) + ∑ j log ⁡ P ( X ( j ) = x ( j ) ∣ Y = c k ) ] \begin{aligned} y &= \mathop{\arg\max}{c_k} \big[ \log^{ \ P(Y = c_k) \prod_j P(X^{(j)} = x^{(j)} \mid Y = c_k)} \big] \\ &= \mathop{\arg\max}{c_k} \big[ \log^{ \ P(y = c_k)} + \sum_j \log^{ \ P(X^{(j)} = x^{(j)} \mid Y = c_k)} \big] \end{aligned} y=argmaxck[log P(Y=ck)∏jP(X(j)=x(j)∣Y=ck)]=argmaxck[log P(y=ck)+j∑log P(X(j)=x(j)∣Y=ck)]

在求条件概率的时候,也进行变换:

log ⁡ P ( X ( j ) = x ( j ) ∣ Y = c k ) = log ⁡ [ 1 2 π σ c k , j 2 exp ⁡ ( − ( a j l − μ c k , j ) 2 2 σ c k , j 2 ) ] = log ⁡ 1 2 π σ c k , j 2 + log ⁡ exp ⁡ ( − ( a j l − μ c k , j ) 2 2 σ c k , j 2 ) = − 1 2 log ⁡ 2 π σ c k , j 2 − 1 2 ( a j l − μ c k , j ) 2 σ c k , j 2 \begin{aligned} \log^{ \ P(X^{(j)} = x^{(j)} \mid Y = c_k)} &= \log^{ \ \bigg[\frac{1}{\sqrt{2 \pi \sigma^2_{c_k,j}}} \exp{\bigg(- \frac{(a_{jl} - \mu_{c_k,j})^2}{2 \sigma^2_{c_k,j}}\bigg)}\bigg]}\\ &= \log^{ \frac{1}{\sqrt{2 \pi \sigma^2_{c_k,j}}} } + \log^{ \exp{\bigg(- \frac{(a_{jl} - \mu_{c_k,j})^2}{2 \sigma^2_{c_k,j}}\bigg)} }\\ &= - \frac{1}{2} \log^{2 \pi \sigma^2_{c_k,j}} - \frac{1}{2} \frac{(a_{jl} - \mu_{c_k,j})^2}{\sigma^2_{c_k,j}} \end{aligned} log P(X(j)=x(j)∣Y=ck)=log [2πσck,j2 1exp(−2σck,j2(ajl−μck,j)2)]=log2πσck,j2 1+logexp(−2σck,j2(ajl−μck,j)2)=−21log2πσck,j2−21σck,j2(ajl−μck,j)2

所以,高斯朴素贝叶斯就可以变形为:

y = arg ⁡ max ⁡ c k [ log ⁡ P ( y = c k ) + ∑ j ( − 1 2 log ⁡ 2 π σ c k , j 2 − 1 2 ( a j l − μ c k , j ) 2 σ c k , j 2 ) ] y = \mathop{\arg\max}{c_k} \bigg[ \log^{ \ P(y = c_k)} + \sum_j \big( - \frac{1}{2} \log^{2 \pi \sigma^2{c_k,j}} - \frac{1}{2} \frac{(a_{jl} - \mu_{c_k,j})^2}{\sigma^2_{c_k,j}} \big) \bigg] y=argmaxck[log P(y=ck)+j∑(−21log2πσck,j2−21σck,j2(ajl−μck,j)2)]

上式就是我们需要求的,我们要求出 K K K 个值,然后求最大的那个对应的 k k k。

1. 导入数据集

python 复制代码
import pandas as pd
import numpy as np
data = pd.read_csv('./breast-cancer.csv')
data = data.replace({'B': 1, 'M': -1})
data = data.values 
data_x = data[:,2:]
data_y = data[:,1:2].ravel()

2. 划分数据集

python 复制代码
from sklearn.model_selection import train_test_split
trainX, testX, trainY, testY = train_test_split(data_x, data_y, test_size = 0.4, random_state = 32)

3. 实现高斯朴素贝叶斯

接下来我们开始实现高斯朴素贝叶斯,我们以类的形式实现这个高斯朴素贝叶斯。因为朴素贝叶斯是懒惰学习,所以这个模型只有在预测的时候,会进行大量的运算。

python 复制代码
class myGaussianNB:
    '''
    处理连续特征的高斯朴素贝叶斯
    '''
    def __init__(self):
        '''
        初始化四个字典
        self.label_mapping     类标记 与 下标(int)
        self.probability_of_y  类标记 与 先验概率(float)
        self.mean              类标记 与 均值(np.ndarray)
        self.var               类标记 与 方差(np.ndarray)
        '''
        self.label_mapping = dict()
        self.probability_of_y = dict()
        self.mean = dict()
        self.var = dict()
        
    def _clear(self):
        '''
        为了防止一个实例反复的调用fit方法,我们需要每次调用fit前,将之前学习到的参数删除掉
        '''
        self.label_mapping.clear()
        self.probability_of_y.clear()
        self.mean.clear()
        self.var.clear()
    
    def fit(self, trainX, trainY):
        '''
        这里,我们要根据trainY内的类标记,针对每类,计算这类的先验概率,以及这类训练样本每个特征的均值和方差

        Parameters
        ----------
            trainX: np.ndarray, 训练样本的特征, 维度:(样本数, 特征数)
        
            trainY: np.ndarray, 训练样本的标记, 维度:(样本数, )
        '''
        
        # 先调用_clear
        self._clear()
        
        # 获取类标记
        labels = np.unique(trainY)
        
        # 添加类标记与下标的映射关系
        self.label_mapping = {label: index for index, label in enumerate(labels)}
        
        # 遍历每个类
        for label in labels:
            
            # 取出为label这类的所有训练样本,存为 x
            x = trainX[trainY == label, :]
            
            # 计算先验概率,用 x 的样本个数除以训练样本总个数,存储到 self.probability_of_y 中,键为 label,值为先验概率
            self.probability_of_y[label] = len(x) / len(trainY)
            
            
            # 对 x 的每列求均值,使用 keepdims = True 保持维度,存储到 self.mean 中,键为 label,值为每列的均值组成的一个二维 np.ndarray
            self.mean[label] = np.mean(x, axis=0, keepdims=True)
            
            
            # 这句话是debug用的,如果不满足下面的条件,会直接跳出
            assert self.mean[label].shape == (1, trainX.shape[1])
            
            # 对 x 的每列求方差,使用 keepdims = True 保持维度,存储到 self.var 中,键为 label,值为每列的方差组成的一个二维 np.ndarray
            self.var[label] = np.var(x, axis=0, keepdims=True)
            
            
            # debug
            assert self.var[label].shape == (1, trainX.shape[1])
            
            # 平滑,因为方差在公式的分母部分,我们要加一个很小的数,防止除以0
            self.var[label] += 1e-9 * np.var(trainX, axis = 0).max()
        
    def predict(self, testX):
        '''
        给定测试样本,预测测试样本的类标记,这里我们要实现化简后的公式

        Parameters
        ----------
            testX: np.ndarray, 测试的特征, 维度:(测试样本数, 特征数)
    
        Returns
        ----------
            prediction: np.ndarray, 预测结果, 维度:(测试样本数, )
        '''
        
        # 初始化一个空矩阵 results,存储每个样本属于每个类的概率,维度是 (测试样本数,类别数),每行表示一个样本,每列表示一个特征
        results = np.empty((testX.shape[0], len(self.probability_of_y)))
        
        # 初始化一个列表 labels,按 self.label_mapping 的映射关系存储所有的标记,一会儿会在下面的循环内部完成存储
        labels = [0] * len(self.probability_of_y)
        
        # 遍历当前的类,label为类标记,index为下标,我们将每个样本预测出来的这个 label 的概率,存到 results 中的第 index 列
        for label, index in self.label_mapping.items():
            
            # 先验概率存为 py
            py = self.probability_of_y[label]
            
            # 使用变换后的公式,计算所有特征的条件概率之和,存为sum_of_conditional_probability
            sum_of_conditional_probability = -0.5 * np.sum(np.log(2 * np.pi * self.var[label])) \
                - 0.5 * np.sum(((testX - self.mean[label]) ** 2) / self.var[label], axis=1)
            
            # debug
            assert sum_of_conditional_probability.shape == (len(testX), )
            
            # 使用变换后的公式,将 条件概率 与 log先验概率 相加,存为result,维度应该是 (测试样本数, )
            result = sum_of_conditional_probability + np.log(py)
            
            
            # debug
            assert result.shape == (len(testX), )
            
            # 将所有测试样本属于当前这类的概率,存入到results中
            results[:, index] = result
            
            # 将当前的label,按index顺序放入到labels中
            labels[index] = label
        
        # 将labels转换为np.ndarray
        np_labels = np.array(labels)
        
        # 循环结束后,就计算出了给定测试样本,当前样本属于这类的概率的近似值,存放在了results中,每行对应一个样本,每列对应一个特征
        # 我们要求每行的最大值对应的下标,也就是求每个样本,概率值最大的那个下标是什么,结果存入max_prob_index中
        max_prob_index = np.argmax(results, axis=1)
        
        
        # debug
        assert max_prob_index.shape == (len(testX), )
        
        # 现在得到了每个样本最大概率对应的下标,我们需要把这个下标变成 np_labels 中的标记
        # 使用上面小技巧中的第五点求解
        prediction = np_labels[max_prob_index]
        
        
        # debug
        assert prediction.shape == (len(testX), )
        
        # 返回预测结果
        return prediction
python 复制代码
# 测试样例
from sklearn.metrics import accuracy_score
model2 = myGaussianNB()
model2.fit(trainX, trainY)
accuracy_score(testY, model2.predict(testX))  # 0.9254385964912281

4. 计算其他的指标

python 复制代码
# YOUR CODE HERE
prediction2 = model2.predict(testX)

precision2 = precision_score(testY, prediction2)

recall2 = recall_score(testY, prediction2)
f2 = f1_score(testY, prediction2)
print("查准率:",precision2)
print("查全率:",recall2)
print("f1值:",f2)

实验3.:实现带有拉普拉斯修正的朴素贝叶斯

实验内容:

  1. 叙述拉普拉斯修正的作用
  2. 使用给定的数据集
  3. 给出实现的代码,要有详细的注释
  4. 给出模型评价指标的结果

1. 叙述拉普拉斯修正的作用

回答:

在朴素贝叶斯分类器中,拉普拉斯修正主要用于解决概率估计中的零概率问题。当在训练数据中出现一个特征值而在测试数据中没有相应特征值时,朴素贝叶斯分类器的条件概率计算中可能会出现零概率,这会导致整个后验概率为零,影响分类器的性能。

拉普拉斯修正通过在概率估计的分子和分母中添加一个小的常数,解决了零概率的问题,确保每个特征值都有一个非零的概率。

2. 拉普拉斯修正的具体介绍

在训练集中总共的分类数,用 N 表示;di 属性可能的取值数用 Ni 表示,因此原来的先验概率 P© 的计算公式由:

P© = Dc / D

被拉普拉斯修正为

P© = (Dc + 1) / (D + N)

类的条件概率由P(xi|c) = Dc,xi / Dc

被拉普拉斯修正为

P(xi|c) = (Dc,xi + 1) / (Dc + Ni)

3. 数据集的介绍

Balance Scale Data Set

离散特征的三分类数据集

Attribute Information:

1. Class Name: 3 (L(左边重), B(天平平衡), R(右边重)) 
2. Left-Weight: 5 (1, 2, 3, 4, 5)
3. Left-Distance: 5 (1, 2, 3, 4, 5)
4. Right-Weight: 5 (1, 2, 3, 4, 5)
5. Right-Distance: 5 (1, 2, 3, 4, 5)

4. 导入数据集及处理

python 复制代码
import numpy as np
data = np.loadtxt("./balance-scale.data", str, unpack = True)
print(data)
#数据处理:分类结果数值化,B->0, L->-1, R->1
dicts = {'R': 1, 'L': -1, 'B': 0}
# print(dicts['R'])
results = [] 
for i in data:
    tmp = []
    for j in i:
        if j == ',':
            continue
        if j == 'B' or j == 'R' or j == 'L':
            tmp.append(dicts[j])
        else:
            tmp.append(int(j))
    results.append(tmp)
data = np.array(results) # 处理后的数据集
datax = data[ : , 1 : ]
datay = data[ : , 0]
print(datax.shape)
print(datay.shape)

5. 划分数据集

测试集30%,训练集70%

python 复制代码
from sklearn.model_selection import train_test_split
trainX, testX, trainY, testY = train_test_split(datax, datay, test_size = 0.3, random_state = 32)

6. 实现带拉普拉斯修正的朴素贝叶斯

python 复制代码
class myGaussianNB:
   
    def __init__(self):
        '''
        初始化四个字典
        self.label_mapping     类标记 与 下标(int)
        self.probability_of_y  类标记 与 先验概率(float)
        self.probability_of_attributes 类标记 与 每个属性的类条件概率
        '''
        # your code
        self.label_mapping = dict()
        self.probability_of_y = dict()
        self.probability_of_attributes = dict()
        self.mean_of_attributes = dict()
    def _clear(self):
        '''
        为了防止一个实例反复的调用fit方法,我们需要每次调用fit前,将之前学习到的参数删除掉
        '''
        # your code 
        self.label_mapping.clear()
        self.probability_of_y.clear()
        self.probability_of_attributes.clear()
        
    def fit(self, trainX, trainY):
        self._clear()
        # 获取类标
        unique_labels, counts = np.unique(trainY, return_counts=True)
        total_samples = len(trainY)
        
        # 遍历每个类
        for label, count in zip(unique_labels, counts):
            # 类标映射下标
            self.label_mapping[label] = len(self.label_mapping)
            # 先验概率
            self.probability_of_y[label] = count / total_samples
            
            label_indices = np.where(trainY == label)[0]
            label_data = trainX[label_indices, :]
            
            # 计算每个特征的频率
            feature_frequencies = []
            for feature_values in label_data.T:
                unique_values, value_counts = np.unique(feature_values, return_counts=True)
                feature_frequency = dict(zip(unique_values, value_counts / count))
                feature_frequencies.append(feature_frequency)
            
            self.mean_of_attributes[label] = feature_frequencies
        
    def predict(self, testX):
        predictions = []
        
        for sample in testX:
            max_probability = float('-inf')
            predicted_label = None
            # 遍历当前类, 预测概率
            for label, index in self.label_mapping.items():
                prior_prob = np.log(self.probability_of_y[label])
                likelihood = 0
                
                # 计算类条件概率
                for feature, value in enumerate(sample):
                    if value in self.mean_of_attributes[label][feature]:
                        likelihood += np.log(self.mean_of_attributes[label][feature][value])
                    else:
                        likelihood += float('-inf')
                # 条件概率加 log(先验概率)
                posterior_prob = prior_prob + likelihood
                
                if posterior_prob > max_probability:
                    max_probability = posterior_prob
                    predicted_label = label
            
            predictions.append(predicted_label)
        # lebels转换为np.ndarray
        return np.array(predictions)

7. 模型评价指标的计算

python 复制代码
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score

model = myGaussianNB()
model.fit(trainX, trainY)
prediction = model.predict(testX)

# 多分类任务 your code
acc3 = accuracy_score(testY, prediction)
precision3 = precision_score(testY, prediction, average='weighted')
recall3 = recall_score(testY, prediction, average='weighted')
f3 = f1_score(testY, prediction, average= 'weighted')
print("精度:", acc3)
print("查准率:",precision2)
print("查全率:",recall2)
print("f1值:",f2)
相关推荐
诚威_lol_中大努力中37 分钟前
关于pytorch3d的安装
人工智能·pytorch·python
GISer_Jing43 分钟前
神经网络、深度学习、卷积神经网络
python
onejason1 小时前
深度解析:利用Python爬虫获取亚马逊商品详情
前端·python
小王子10241 小时前
数据结构与算法Python版 二叉查找树
数据结构·python·算法·二叉查找树
编程阿布1 小时前
Python基础——多线程编程
java·数据库·python
又蓝1 小时前
使用 Python 操作 MySQL 数据库的实用工具类:MySQLHandler
数据库·python·mysql
dundunmm1 小时前
机器学习之pandas
人工智能·python·机器学习·数据挖掘·pandas
好学近乎知o1 小时前
常用的Django模板语言
python·django·sqlite
小火炉Q2 小时前
16 循环语句——for循环
人工智能·python·网络安全
segwyang2 小时前
Maven 项目模板
java·python·maven