2014-09-18 2 views
1

내가 R 사회 경험이없는, 그래서R e1071 Naive Bayes의 버그? 이 적절한 포럼이 아닌 경우

길고도 짧은 이야기, 나는 e1071::naiveBayes 호의 알파벳 순서에 의해 라벨을주는 것을 두려워 ... 다른 곳에서 날 지점하시기 바랍니다.

이전 문의 : here 순진한 베이 즈의 구현에서 숫자 예측 자로 이상한 동작을 발견했습니다. 좀 더 합리적인 답을 얻었지만 일부 확률은 위쪽으로 치우친 것처럼 보였습니다.

왜이 시뮬레이션이 이런 식으로 끝날지 알 수있는 사람이 있습니까? (100을 의미 즉

enter image description here

모든 라벨 에게 같은 정규 분포주기 : 나는 단지이 같은 플롯을 제공

library(e1071) 

# get a data frame with numObs rows, and numDistinctLabels possible labels 
# each label is randomly drawn from letters a-z 
# each label has its own distribution of a numeric variable 
# this is normal(i*100, 10), i in 1:numDistinctLabels 
# so, if labels are t, m, and q, t is normal(100, 10), m is normal(200, 10), etc 
# the idea is that all labels should be predicted just as often 
# but it seems that "a" will be predicted most, "b" second, etc 

doExperiment = function(numObs, numDistinctLabels){ 
    possibleLabels = sample(letters, numDistinctLabels, replace=F) 
    someFrame = data.frame(
     x=rep(NA, numObs), 
     label=rep(NA, numObs) 
    ) 
    numObsPerLabel = numObs/numDistinctLabels 
    for(i in 1:length(possibleLabels)){ 
     label = possibleLabels[i] 
     whichAreNA = which(is.na(someFrame$label)) 
     whichToSet = sample(whichAreNA, numObsPerLabel, replace=F) 
     someFrame[whichToSet, "label"] = label 
     someFrame[whichToSet, "x"] = rnorm(numObsPerLabel, 100*i, 10) 
    } 
    someFrame = as.data.frame(unclass(someFrame)) 
    fit = e1071::naiveBayes(label ~ x, someFrame) 
    # The threshold argument doesn't seem to change the matter... 
    someFrame$predictions = predict(fit, someFrame, threshold=0) 
    someFrame 
} 

# given a labeled frame, return the label that was predicted most 
getMostFrequentPrediction = function(labeledFrame){ 
    names(which.max(sort(table(labeledFrame$prediction)))) 
} 

# run the experiment a few thousand times 
mostPredictedClasses = sapply(1:2000, function(x) getMostFrequentPrediction(doExperiment(100, 5))) 

# make a bar chart of the most frequently predicted labels 
plot(table(mostPredictedClasses)) 

... 그것은이 시점에서 버그가 있음을 상상할 수 CO에 대해서는

enter image description here

: 표준 편차 10) 준다 논평에서 nfusion :

여기 아마 스택 오버플로 영토에서 벗어나고 있지만, 어쨌든 ... 분류가 덜 울퉁불퉁 할 것으로 예상되지만, 표준 편차의 효과는 PDF를 평평하게 만드는 데 많은 도움이됩니다. 당신은 하나 또는 두 가지가 실제로 지배적 인 경향이 있음을 관찰 할 수 있습니다 (이 경우 빨간색과 검정색).

enter image description here

너무 나쁜 우리는 표준 편차가 그들 모두에 대해 동일한 것을 지식을 활용할 수 없습니다.

약간의 소음을 추가하면 더 많은 균등하게 분배되며, 여전히 오판이 다소 있습니다.

enter image description here

답변

1

이 문제는 당신 getMostFrequentPrediction 함수의, naiveBayes 없습니다. 처음에는 동점이있는 경우에도 하나의 가치 만 반환합니다. table()을 사용하고 있기 때문에 카운트는 암시 적으로 테이블에서 사전 순으로 정렬됩니다. 따라서 첫 번째 최대 값을 얻을 때 알파벳순으로 "가장 작은"값이됩니다. 그래서 던이 배의 무리는 경우 :

getMostFrequentPrediction(data.frame(predictions=sample(rep(letters[1:3], 5)))) 

당신은 항상 GET "는"심지어 문자 "A" "B"와 "C"하지만 모두 5 번 나타납니다.

는 무작위로 가장 많이 예측 범주 중 하나를 선택하려는 경우, 여기에 또 다른 가능한 구현을의

getMostFrequentPrediction = function(labeledFrame){ 
    tt<-table(labeledFrame$predictions) 
    names(sample(tt[tt==max(tt)], 1)) 
} 

enter image description here

+0

당신은 참으로 타이 브레이크에 대한 올바른 있습니다. 그 점을 지적 해 주셔서 감사합니다!나는 우위의 예측이 라벨을 바꿔서 바꿀 수있는 직업에서 일어나는 일을 재현하려고 노력하고있다. 그러나 아마 나는 잘못된 나무를 짖고있다. – dcc310

+0

왜 100 * i를 제거하는지에 대한 설명이 있는가? (즉, 모든 레이블에 동일한 분포를 부여하면)이 묶음 분리 효과가 제거됩니까? 나는 여전히 a와 b와 같은 글자에 약간의 편향이있을 것이라고 생각 하겠지만, 두 번째 줄거리와 추가로 땜질부터, 그렇지 않습니다. – dcc310

+1

당신이 그들에게 모든 다른 배포본 (평균 ='100 * i', sd = 10)을 줄 때, 그것들은 거의 중첩되지 않으므로 카테고리는 구별하기가 훨씬 쉽습니다. 당신의 예측은 거의 완벽하므로 많은 유대 관계를 가지고 있습니다. 완전한 중첩 (평균 = '100', 모두에 대해 sd = 10)을 사용하면 동일한 문제가 발생하지 않도록 훨씬 적은 수의 연결을 얻을 수 있습니다. – MrFlick

관련 문제