2016-03-09 38 views
2

下面是我用於R中樸素貝葉斯實現(使用e1071包)的訓練數據集,其中:X,Y,Z是不同的類別,V1,V2,V3, V4,V5是屬性: -關於包e1071中的樸素貝葉斯算法的查詢R

Class V1 V2 V3 V4 V5 
X  Yes Yes No Yes Yes 
X  Yes Yes No No Yes 
X  Yes Yes No No Yes 
X  Yes Yes No No Yes 
X  No Yes No No Yes 
X  No Yes No No Yes 
X  No Yes No No Yes 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
X  No No No No No 
Y  Yes Yes Yes No Yes 
Y  No No No No Yes 
Y  No No No No Yes 
Y  No No No No No 
Y  No No No No No 
Y  No No No No No 
Y  No No No No No 
Z  No Yes Yes No Yes 
Z  No No No No Yes 
Z  No No No No Yes 
Z  No No No No No 
Z  No No No No No 
Z  No No No No No 
Z  No No No No No 

用於上述數據集的先驗概率是X-> 0.5333333 Y-> 0.2333333 Z-> 0.2333333

和條件概率爲: -

V1 
Y   No  Yes 
    X 0.7500000 0.2500000 
    Y 0.8571429 0.1428571 
    Z 1.0000000 0.0000000 

V2 
Y   No  Yes 
    X 0.5625000 0.4375000 
    Y 0.8571429 0.1428571 
    Z 0.8571429 0.1428571 

V3 
Y   No  Yes 
    X 1.0000000 0.0000000 
    Y 0.8571429 0.1428571 
    Z 0.8571429 0.1428571 

V4 
Y  No Yes 
    X 0.9375 0.0625 
    Y 1.0000 0.0000 
    Z 1.0000 0.0000 

V5 
Y   No  Yes 
    X 0.5625000 0.4375000 
    Y 0.5714286 0.4285714 
    Z 0.5714286 0.4285714 

案例1: - 拉普拉斯平滑未使用

我想知道V3屬於哪個類,給定值是。所以,我有我的測試數據: -

V3 
Yes 

所以,我必須找出每一類即概率(X | V3 =是)的概率,概率(Y | V3 =是),概率(Z | V3 =是),並從三者中取最大值。現在,

概率(X | V3 =是)=概率(X)*概率(V3 = YES | X)/ P(V3)

從上述條件概率,我們知道概率(V3因此,概率(X | V3 =是)應該是0,概率(Y | V3 =是),概率(Z | V3 =是)應該是0.5。

但在R輸出是不同的。從包e1071我已經使用naiveBayes功能。下面是代碼及其相應的輸出: -

#model_nb<-naiveBayes(Class~.,data = train,laplace=0) 
#results<-predict(model_nb,test,type = "raw") 
#print(results) 

#   X   Y   Z 
#[1,] 0.5714286 0.2142857 0.2142857 

有人可以解釋爲什麼這樣的輸出在R?

案例2: - 拉普拉斯平滑使用

相同的情況案例1 w.r.t.測試數據,只有使用拉普拉斯的差異是1.因此,我必須找出每個類別的概率,即概率(X | V3 =是),概率(Y | V3 =是),概率(Z | V3 =是)並且從三者中取出最大值。

下面是拉普拉斯平滑後的條件概率(K = 1)

V1 
Y   No  Yes 
    X 0.7222222 0.2777778 
    Y 0.7777778 0.2222222 
    Z 0.8888889 0.1111111 

V2 
Y   No  Yes 
    X 0.5555556 0.4444444 
    Y 0.7777778 0.2222222 
    Z 0.7777778 0.2222222 

V3 
Y   No  Yes 
    X 0.94444444 0.05555556 
    Y 0.77777778 0.22222222 
    Z 0.77777778 0.22222222 

V4 
Y   No  Yes 
    X 0.8888889 0.1111111 
    Y 0.8888889 0.1111111 
    Z 0.8888889 0.1111111 

V5 
Y   No  Yes 
    X 0.5555556 0.4444444 
    Y 0.5555556 0.4444444 
    Z 0.5555556 0.4444444 

從樸素貝葉斯定義,

概率(X | V3 =是)=概率(X)*概率(V3 =是| X)/ P(V3)

概率(Y | V3 =是)=概率(Y)*概率(V3 =是| X)/ P(V3)

概率(Z | V3 =是)=概率(Z)*概率(V3 =是| X)/ P(V3)

計算我後,

概率(X | V3(是)= 0.53 * 0.05555556/P(V3)= 0.029/P(V3)

概率(Y | V3 =是)= 0.23 * 0.22222222/P(V3)= 0。051/P(V3)

概率(Z | V3 =是)= 0.23 * 0.22222222/P(V3)= 0.051/P(V3)

從上述計算,應該有類之間的粘結Y和Z.但是R輸出是不同的。類X顯示爲輸出類。下面是代碼及其對應的輸出: -

#model_nb<-naiveBayes(Class~.,data = train,laplace=1) 
#results<-predict(model_nb,test,type = "raw") 
#print(results) 


#  X   Y   Z 
#[1,] 0.5811966 0.2094017 0.2094017 

同樣,有人可以解釋爲什麼在R,使得輸出?我的計算在任何地方出錯了嗎?

此外,需要一些解釋當拉普拉斯平滑完成時如何計算P(V3)。

在此先感謝!

回答

1

問題是,您只使用一個樣本作爲測試數據集,只有一個值爲V3。如果你給多一點的測試數據你會得到合理的/預期的結果(只專注於你的情況1):

test <- data.frame(V3=c("Yes", "No")) 
predict(model_nb, test, type="raw") 
       X   Y   Z 
[1,] 0.007936508 0.4960317 0.4960317 
[2,] 0.571428571 0.2142857 0.2142857 

注意你不要恰好爲0,0.5,0.5 V3 =「是」 ,因爲該功能正在使用可調節的閾值,請參閱?predict.naiveBayes瞭解更多信息。

問題實際上是由於predict.naiveBayes(源代碼位於CRAN存儲庫)的內部實現。我不會進入所有的細節,但基本上我已經調試功能,並在一定的步驟有這條線,

newdata <- data.matrix(newdata) 

稍後將決定使用哪個條件概率的列。有了您的原始數據data.matrix看起來是這樣的:

data.matrix(data.frame(V3="Yes")) 
    V3 
[1,] 1 

因此後來假設條件概率將被從列1所,即值1.0000000,0.8571429和0.8571429爲V3 =「否」,並這就是爲什麼你得到的結果,如果V3實際上是「否」。

然而,

data.matrix(data.frame(V3=c("Yes", "No"))) 
    V3 
[1,] 2 
[2,] 1 

給出了條件概率的2列時V3是「是」,這樣的話你得到正確的結果。

我很確定你的情況2只是類似的。

希望它有幫助。評論後

編輯:我想解決這個問題將是把所有的數據在一個data.frame,並選擇您使用的培訓指標/測試模型中的更簡單的方法。許多功能接受subset選擇您用於培訓的數據,naiveBayes也不例外。但是,對於predict.naiveBayes,您必須選擇索引。像這樣的東西。

all_data <- rbind(train, c(NA, NA, NA, "Yes", NA, NA)) 
trainIndex <- 1:30 
model_nb <- naiveBayes(Class~., data=all_data, laplace=0, subset=trainIndex) 
predict(model_nb, all_data[-trainIndex,], type="raw") 

給出了預期的結果。

   X   Y   Z 
[1,] 0.007936508 0.4960317 0.4960317 

注意這是因爲在這種情況下,當你做data.matrix操作你得到正確的結果。評論後

data.matrix(all_data[-trainIndex,]) 
    Class V1 V2 V3 V4 V5 
31 NA NA NA 2 NA NA 

EDIT2:上爲什麼發生這種情況更多的細節。

當你定義test數據幀只包括一個值等於「否」,由data.matrix進行的轉換實際上已經沒有辦法知道你的變量V3有2個可能的值,「是」和「否」。 test$V3實際上是一個因素:

test <- data.frame(V3="Yes") 
class(test$V3) 
[1] "factor" 

和說,它只有一個等級(沒有辦法,data.frame知道居然還有2)

levels(test$V3) 
[1] "Yes" 

data.matrix實施,爲你可以在docs中看到,使用因子的級別:

因子和有序因子被它們的內部代碼取代。

因此轉換測試data.matrix時解釋只有一種因素的可能值並對其進行解碼,

data.matrix(test) 
    V3 
[1,] 1 

但是,當你把訓練和測試的伎倆到同一個數據幀,因素水平被正確定義。

levels(all_data$V3) 
[1] "No" "Yes" 

其結果將是相同的,如果你這樣做:

test <- data.frame(V3=factor("Yes", levels=levels(all_data$V3))) 
test 
    V3 
1 Yes 
levels(test$V3) 
[1] "No" "Yes" 
data.matrix(test) 
    V3 
[1,] 2 
+0

是的,它幫助!在我的情況下,我會更感興趣的是僅僅找到這樣的實例P(Class | Attribute =「Yes」)。但由於predict.naiveBayes的內部實現,我將不得不提供屬性的值,即Yes&No來獲得所需結果(在我的情況下爲Yes)。任何解決這個問題的方法? – Kanishka

+0

我已經更新了我的答案,提供了比提供兩個值更實用的解決方案。如果您仍有疑問或問題,請告訴我。乾杯。 – lrnzcig

+0

謝謝。我喜歡把所有的值放在一個data.frame中,並使用索引來訓練/測試一個模型。只是最後一個疑問: - 當測試數據類似於''V3 =是'時 'data.matrix(data.frame(V3 =「是」)) V3 [1,] 1# 1' _當測試數據是類似的_'all_data < - rbind(train,c(NA,NA,NA,「是」,NA,NA))'data.matrix(all_data [-trainIndex,]) 類V1 V2 V3 V4 V5 正在採取 31 NA NA NA 2 NA NA #Here列是2' 爲什麼? – Kanishka

1

我有這個同樣的問題,它確實是所有關於因素!您必須同步訓練數據與提供的預測新數據之間的因子水平。 (正如Rinzcig在上面'編輯2'中所述)。

e1071中的樸素貝葉斯函數將所有字符數據轉換爲因子。你必須控制這種轉換,否則你會得到意想不到的結果。

這只是你需要這行代碼:

test <- data.frame(V3=factor("Yes", levels=levels(all_data$V3))) 

你可以看到,我有same issue and solution here.