2017-03-05 37 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)通常在處理概率乘積(這就是你的共同可能性)的時候,我們使用對數概率來代替它們,因爲它們是可加性的,並且不會引起數值問題(這通常發生在乘以許多小數一起)。