【R的机器学习】模型性能提升探索:朴素贝叶斯

本文介绍如何使用朴素贝叶斯算法对Iris数据集进行分类。通过将连续数值转换为离散因子,并利用拉普拉斯平滑处理,模型表现出极高的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章强行带入朴素贝叶斯的算法进行分类。

为什么说是强行,因为NB(朴素贝叶斯)算法其实不算是一个好的对于数值型分类的方法,一般应用的部分的特征值通常是因子型;举个例子,对于我们的iris数据集:

head(iris_train)
    Sepal.Length Sepal.Width Petal.Length Petal.Width
75           6.4         2.9          4.3         1.3
16           5.7         4.4          1.5         0.4
120          6.0         2.2          5.0         1.5
91           5.5         2.6          4.4         1.2
93           5.8         2.6          4.0         1.2
127          6.2         2.8          4.8         1.8
       Species
75  versicolor
16      setosa
120  virginica
91  versicolor
93  versicolor
127  virginica

我们看到,除了结果分类的Species以外,其他的四个分类都是连续的数值型,因为朴素贝叶斯的主要思想是求一件事情发生的条件概率,而没有分类的连续数值型是无法求出条件概率的。举个例子,下雨天路上车少的概率是80%,这个很容易表达成条件概率:

P(车少|下雨天)=0.8

扩展下,某一个区域下雨的概率是50%,车少的概率是10%:

P(下雨天)=0.5
P(车少)=0.1

如果有一天我们大侦探福尔摩斯听到这一天车很少,脑海中迅速会回想起这一天的天气以及作案手段,他的计算方式是这样的:

P(车少|下雨天)*P(下雨天)=P(车少)*P(下雨天|车少)

左右两边相等,是因为求得结果都是下雨天且车少的概率,说到这了,求出:

P(下雨天|车少)=40%

但是,如果我们这里不是车少,比如我们看到下雨天车辆<100辆,然后我们看到120辆车,问这个概率的话,我们是没有先验条件的,也就是我们不知道120辆车的时候,下不下雨,所以从这个意义上说,NB算法针对于那些给定发生的、因子型的特征值处理的要更好,否则如果我们在做处理的时候(后面会具体模拟下),会损失掉一些数据,比如我们把数据分段,100辆以下的是少,120辆以上的是多,100-120是中,等等。所以NB也很适合文本分类,因为文本是一类典型的已知的因子。

再回到我们的iris数据集,看看每个参数的分布情况:

summary(iris)
Sepal.Length    Sepal.Width     Petal.Length  
 Min.   :4.300   Min.   :2.000   Min.   :1.000  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600  
 Median :5.800   Median :3.000   Median :4.350  
 Mean   :5.843   Mean   :3.057   Mean   :3.758  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100  
 Max.   :7.900   Max.   :4.400   Max.   :6.900  
  Petal.Width          Species  
 Min.   :0.100   setosa    :50  
 1st Qu.:0.300   versicolor:50  
 Median :1.300   virginica :50  
 Mean   :1.199                  
 3rd Qu.:1.800                  
 Max.   :2.500

我们按照最简单的方式,按照三个分位数(25,50,75)把每列数据分成四类,在这里需要新建个数据集,并且用循环的方式,具体的代码如下:

iris1<-iris
for (j in 1:4){
  for (i in 1:nrow(iris1)){
    if (iris1[i,j]<=quantile(iris[,j])[2]){
      iris1[i,j]<-'L'
    }else if(iris1[i,j]<=quantile(iris[,j])[3]){
      iris1[i,j]<-'M'
    }else if(iris1[i,j]<=quantile(iris[,j])[4]){
      iris1[i,j]<-'H'
    }else {
      iris1[i,j]<-'G'
    }
  }
}

我们把数据最小的设定为Low,然后是Medium,High,Great四个分类;

看下数据集:

str(iris1)
'data.frame':   150 obs. of  5 variables:
 $ Sepal.Length: chr  "L" "L" "L" "L" ...
 $ Sepal.Width : chr  "G" "M" "H" "H" ...
 $ Petal.Length: chr  "L" "L" "L" "L" ...
 $ Petal.Width : chr  "L" "L" "L" "L" ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

好,貌似我们的数据准备已经完成,那么我们开始进行模型拟合:

library(e1071)
m_nb<-naiveBayes(iris1_train,iris1_train$Species,laplace=0.01)

这里的贝叶斯模型采用e1071的包,顺便说一下其中的laplace,也就是拉普拉斯估计;考虑之前下雨天的概率,这个概率是计算出来的,我们说

P(车少)=0.1

其实是我们在训练集中看了10次,只有一辆车通过,那么在极端点,可能会没有车,但是没有车(是我们的估计概率)不一定是真实的;

再举个例子,比如计算抛硬币是正面且有声音,我们只抛了10次,一次都没有正面,但是如果我们说这个概率为0,那么有声音概率再大,这个概率也是0;拉普拉斯估计就是避免这种情况,在每一个为0的概率上加上一点点数据,让这个数不为0。这里加上0.01。

然后看下我们的模型:

m_nb

Naive Bayes Classifier for Discrete Predictors

Call:
naiveBayes.default(x = iris1_train, y = iris1_train$Species, 
    laplace = 0.01)

A-priori probabilities:
iris1_train$Species
    setosa versicolor  virginica 
 0.3523810  0.3238095  0.3238095 

Conditional probabilities:
                   Sepal.Length
iris1_train$Species            G            H            L
         setosa     0.0002702703 0.0002702703 0.7029729730
         versicolor 0.2061764706 0.3532352941 0.0885294118
         virginica  0.5002941176 0.3238235294 0.0297058824
                   Sepal.Length
iris1_train$Species            M
         setosa     0.2975675676
         versicolor 0.3532352941
         virginica  0.1473529412

                   Sepal.Width
iris1_train$Species          G          H          L
         setosa     0.62189189 0.21648649 0.02729730
         versicolor 0.02970588 0.14735294 0.50029412
         virginica  0.08852941 0.26500000 0.41205882
                   Sepal.Width
iris1_train$Species          M
         setosa     0.13540541
         versicolor 0.32382353
         virginica  0.23558824

                   Petal.Length
iris1_train$Species            G            H            L
         setosa     0.0002702703 0.0002702703 0.8921621622
         versicolor 0.0002941176 0.5297058824 0.0002941176
         virginica  0.6179411765 0.3826470588 0.0002941176
                   Petal.Length
iris1_train$Species            M
         setosa     0.1083783784
         versicolor 0.4708823529
         virginica  0.0002941176

                   Petal.Width
iris1_train$Species            G            H            L
         setosa     0.0002702703 0.0002702703 0.7570270270
         versicolor 0.0002941176 0.4414705882 0.0002941176
         virginica  0.7355882353 0.2650000000 0.0002941176
                   Petal.Width
iris1_train$Species            M
         setosa     0.2435135135
         versicolor 0.5591176471
         virginica  0.0002941176

                   Species
iris1_train$Species       setosa   versicolor    virginica
         setosa     0.9994598974 0.0002700513 0.0002700513
         versicolor 0.0002938584 0.9994122833 0.0002938584
         virginica  0.0002938584 0.0002938584 0.9994122833

先看开始的:

iris1_train$Species
    setosa versicolor  virginica 
 0.3523810  0.3238095  0.3238095 

说明三个类别整体概率还是挺均匀的,基本都是1/3;下面的每个参数变量结果都是差不多的,取第一个解释下

Conditional probabilities:
Sepal.Length
iris1_train$Species            G            H            L
         setosa     0.0002702703 0.0002702703 0.7029729730
         versicolor 0.2061764706 0.3532352941 0.0885294118
         virginica  0.5002941176 0.3238235294 0.0297058824
                   Sepal.Length
iris1_train$Species            M
         setosa     0.2975675676
         versicolor 0.3532352941
         virginica  0.1473529412

条件概率(Conditional probabilities)的含义是出现结果(列)中行的概率,比如出现setosa的时候,Sepal.Length=G的概率是0.0002702703,也就是

P(G|setosa)=0.0002702703
P(G|versicolor)=0.2061764706
P(G|virginica)=0.5002941176

单纯看这个,也就是当virginica条件下,G的概率将近50%,那么按照贝叶斯定理:

P(virginica)*P(G|virginica)=P(G)*P(virginica|G)

最后求解test中的virginica概率需要知道:

P(virginica|G)
P(G)
P(G|virginica)

而这三个在训练集中都是已知的;

最后预测下结果:

m_nbp<-predict(m_nb,iris1_test)

[1] versicolor versicolor virginica  virginica  versicolor
 [6] versicolor setosa     setosa     virginica  versicolor
[11] versicolor versicolor versicolor setosa     setosa    
[16] versicolor virginica  virginica  virginica  versicolor
[21] virginica  setosa     setosa     virginica  versicolor
[26] setosa     versicolor versicolor virginica  setosa    
[31] virginica  versicolor setosa     virginica  setosa    
[36] setosa     setosa     versicolor versicolor virginica 
[41] virginica  virginica  setosa     virginica  virginica 
Levels: setosa versicolor virginica

让我们吃惊的是,这个模型拟合的非常好,几乎是100%准确

table(iris1_test$Species,m_nbp)
m_nbp
             setosa versicolor virginica
  setosa         13          0         0
  versicolor      0         16         0
  virginica       0          0        16

看下概率

m_nbp_p<-predict(m_nb,iris1_test,type='raw')
m_nbp_p
 setosa  versicolor   virginica
 [1,] 0.002917515 0.994167039 0.002915446
 [2,] 0.002917515 0.994167039 0.002915446
 [3,] 0.002917515 0.002915446 0.994167039
 [4,] 0.002917515 0.002915446 0.994167039
 [5,] 0.002917515 0.994167039 0.002915446
 [6,] 0.002917515 0.994167039 0.002915446
 [7,] 0.994641852 0.002679074 0.002679074
 [8,] 0.994641852 0.002679074 0.002679074
 [9,] 0.002917515 0.002915446 0.994167039
[10,] 0.002917515 0.994167039 0.002915446
[11,] 0.002917515 0.994167039 0.002915446
[12,] 0.002917515 0.994167039 0.002915446
[13,] 0.002917515 0.994167039 0.002915446
[14,] 0.994641852 0.002679074 0.002679074
[15,] 0.994641852 0.002679074 0.002679074
[16,] 0.002917515 0.994167039 0.002915446
[17,] 0.002917515 0.002915446 0.994167039
[18,] 0.002917515 0.002915446 0.994167039
[19,] 0.002917515 0.002915446 0.994167039
[20,] 0.002917515 0.994167039 0.002915446
[21,] 0.002917515 0.002915446 0.994167039
[22,] 0.994641852 0.002679074 0.002679074
[23,] 0.994641852 0.002679074 0.002679074
[24,] 0.002917515 0.002915446 0.994167039
[25,] 0.002917515 0.994167039 0.002915446
[26,] 0.994641852 0.002679074 0.002679074
[27,] 0.002917515 0.994167039 0.002915446
[28,] 0.002917515 0.994167039 0.002915446
[29,] 0.002917515 0.002915446 0.994167039
[30,] 0.994641852 0.002679074 0.002679074
[31,] 0.002917515 0.002915446 0.994167039
[32,] 0.002917515 0.994167039 0.002915446
[33,] 0.994641852 0.002679074 0.002679074
[34,] 0.002917515 0.002915446 0.994167039
[35,] 0.994641852 0.002679074 0.002679074
[36,] 0.994641852 0.002679074 0.002679074
[37,] 0.994641852 0.002679074 0.002679074
[38,] 0.002917515 0.994167039 0.002915446
[39,] 0.002917515 0.994167039 0.002915446
[40,] 0.002917515 0.002915446 0.994167039
[41,] 0.002917515 0.002915446 0.994167039
[42,] 0.002917515 0.002915446 0.994167039
[43,] 0.994641852 0.002679074 0.002679074
[44,] 0.002917515 0.002915446 0.994167039
[45,] 0.002917515 0.002915446 0.994167039

一般来说,NB丢失了数据的数值,会让准确度下降;同时NB的前提假设是特征值之间是相互独立的;这对于很多现实情况来说,是不成立的;比如偿还贷款的案例中,特征值是房、车、收入,但是这三者本身就是比较相关的,所以不太适用于贝叶斯,而本文的例子来看,iris中这几个变量应该是相互独立,而且变量数量比较少,所以NB有如此高的准确率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值