2017-03-05 75 views
1

我编写了一些代码,使用iris数据集手工制作朴素贝叶斯分类器。我做了以下:R中的朴素贝叶斯分类 - 从头开始​​

  • 将数据分成3类
  • 计算均值和方差为每一类

使用dnorm

  • 乘以现有每个类
  • 计算概率对于每个结果我都会得到低概率。我想知道后函数的部分是否正确?这里是我的代码:

    set.seed(1) #reproducibility 
    training_rows <- sort(c(sample(1:50, 40), sample(51:100, 40), sample(101:150, 40))) 
    training_x <- as.data.frame(iris[training_rows, 1:4]) 
    training_y <- iris[training_rows, 5] 
    
    iris_nb <- function(x, trainx, trainy){ 
        train <- cbind(trainx, trainy) 
    
        class_virginica <- train[which(train$trainy == 'virginica'),] 
        class_setosa <- train[which(train$trainy == 'setosa'),] 
        class_versicolor <- train[which(train$trainy == 'versicolor'),] 
    
        posterior <- function(x, classtype){ 
    
        p_Sepal.Length <- dnorm(x, mean(classtype[,1]), sd(classtype[,1])) 
        p_Sepal.Width <- dnorm(x, mean(classtype[,2]), sd(classtype[,2])) 
        p_Petal.Length <- dnorm(x, mean(classtype[,3]), sd(classtype[,3])) 
        p_Petal.Width <- dnorm(x, mean(classtype[,4]), sd(classtype[,4])) 
    
        vec <- 0.33* p_Sepal.Length * p_Sepal.Width * p_Petal.Length * p_Petal.Width #for each species 
        return(vec) 
    } 
    
        return(list(virginica = sum(posterior(x, class_virginica)), 
         setosa = sum(posterior(x, class_setosa)), 
         versicolor = sum(posterior(x, class_versicolor)))) 
    } 
    

    这里是输出:

    test_case_1 <- as.matrix(iris[1, 1:4]) 
    iris_nb(test_case_1, training_x, training_y) 
    
    ## $virginica 
    ## [1] 1.167108e-16 
    
    ## $setosa 
    ## [1] 2.136291e-54 
    
    ## $versicolor 
    ## [1] 1.636154e-32 
    

    我感谢帮助!

  • 回答

    0

    两点意见:

    1)你计算的后部是基于这样的事实,这是成正比的prior * likelihood。这一切都很好,但请记住贝叶斯定理说posterior = prior * likelihood/marginal。边际非常小,因此将其从计算中删除将会使后验概率非常小(因为您没有按它分割)。

    一般来说,我们不关心这些概率本身,我们关心他们的相对大小。因此,这个测试案例的virginica似乎比其他物种多出许多倍。所以朴素贝叶斯会输出virginicaargmax。 2)通常在处理概率乘积(这就是你的共同可能性)的时候,我们使用对数概率来代替它们,因为它们是可加性的,并且不会引起数值问题(这通常发生在乘以许多小数一起)。