以下代码应该是可重现的
someFrameA = data.frame(label="A", amount=rnorm(10000, 100, 20))
someFrameB = data.frame(label="B", amount=rnorm(1000, 50000, 20))
wholeFrame = rbind(someFrameA, someFrameB)
fit <- e1071::naiveBayes(label ~ amount, wholeFrame)
wholeFrame$predicted = predict(fit, wholeFrame)
nrow(subset(wholeFrame, predicted != label))
就我而言,这给了243个错误分类。
注意这两行: (行数,标签,金额,预测)
10252 B 50024.81895 A
2955 A 100.55977 A
10678 B 50010.26213 B
虽然输入仅相差12.6,但分类会发生变化。很奇怪这样的行的后验概率非常接近:
> predict(fit, wholeFrame[10683, ], type="raw")
A B
[1,] 0.5332296 0.4667704
我正在尝试使用交易金额对某些银行交易进行分类。我在原始模型中有许多其他基于文本的功能,但是在使用数字模型时发现了一些可疑的东西。
> head(trainingSet)
category amount
1 check 688.00
2 non-businesstransaction 2.50
3 non-businesstransaction 36.00
4 non-businesstransaction 243.22
5 payroll 302.22
6 non-businesstransaction 16.18
fit <- e1071::naiveBayes(category ~ amount, data=trainingSet)
fit
离散预测变量的朴素贝叶斯分类器
呼叫: naiveBayes.default(x = X,y = Y,laplace = laplace)
A-priori probabilities:
Y
bankfee check creditcardpayment e-commercedeposit insurance
0.029798103 0.189613233 0.054001459 0.018973486 0.008270494
intrabanktransfer loanpayment mcapayment non-businesstransaction nsf
0.045001216 0.015689613 0.011432741 0.563853077 0.023351982
other payroll taxpayment utilitypayment
0.003405497 0.014838239 0.005716371 0.016054488
Conditional probabilities:
amount
Y [,1] [,2]
bankfee 103.58490 533.67098
check 803.44668 2172.12515
creditcardpayment 819.27502 2683.43571
e-commercedeposit 42.15026 59.24806
insurance 302.16500 727.52321
intrabanktransfer 1795.54065 11080.73658
loanpayment 308.43233 387.71165
mcapayment 356.62755 508.02412
non-businesstransaction 162.41626 951.65934
nsf 44.92198 78.70680
other 9374.81071 18074.36629
payroll 1192.79639 2155.32633
taxpayment 1170.74340 1164.08019
utilitypayment 362.13409 1064.16875
根据e1071文档,&#34;条件概率的第一列&#34;是数字变量的平均值,另一个是标准偏差。这些手段和标准是正确的,先验概率也是如此。
所以,这一行令人不安:
> thatRow
category amount
40 other 11268.53
接收这些后期:
> predict(fit, newdata=thatRow, type="raw")
bankfee check creditcardpayment e-commercedeposit insurance intrabanktransfer loanpayment mcapayment
[1,] 4.634535e-96 7.28883e-06 9.401975e-05 0.4358822 4.778703e-51 0.02582751 1.103762e-174 1.358662e-101
non-businesstransaction nsf other payroll taxpayment utilitypayment
[1,] 1.446923e-29 0.5364704 0.001717378 1.133719e-06 2.059156e-18 2.149142e-24
请注意&#34; nsf&#34;得分约为其他&#34;其他&#34;确实。由于这笔交易的金额为11.2万美元,如果要遵循这个&#34; nsf&#34;分布,它将与平均值相差超过100个标准偏差。同时,因为&#34;其他&#34;交易的样本均值约为9k美元,且标准偏差很大,我认为此交易更可能是一个&#34;其他&#34;。虽然&#34; nsf&#34;它更可能与之前的概率相比,它们不会超过尾部观察,并且还有很多其他可行的候选者除了&#34;其他&#34;同样。
我假设这个软件包只是查看了正常的(mew = samplemean,stdev = samplestdev)pdf并使用该值进行乘法,但情况并非如此?我无法弄清楚如何查看来源。
数据类型似乎也很好:
> class(trainingSet$amount)
[1] "numeric"
> class(trainingSet$category)
[1] "factor"
用于离散预测变量的&#34;朴素贝叶斯分类器&#34;在打印输出中可能是奇怪的,因为这是一个连续的预测器,但我认为这个包可以处理连续预测器。
我的klaR包有类似的结果。也许我需要在那上面设置内核选项?
答案 0 :(得分:1)
阈值参数是其中很大一部分。包中的代码有点像这样:
L <- sapply(1:nrow(newdata), function(i) {
ndata <- newdata[i, ]
L <- log(object$apriori) + apply(log(sapply(seq_along(attribs),
function(v) {
nd <- ndata[attribs[v]]
if (is.na(nd)) rep(1, length(object$apriori)) else {
prob <- if (isnumeric[attribs[v]]) {
msd <- object$tables[[v]]
msd[, 2][msd[, 2] <= eps] <- threshold
dnorm(nd, msd[, 1], msd[, 2])
} else object$tables[[v]][, nd]
prob[prob <= eps] <- threshold
prob
}
阈值(此 记录)将替换小于eps的任何概率。因此,如果连续变量的正常pdf为0.000000000,则默认为.001。
> wholeFrame$predicted = predict(fit, wholeFrame, threshold=0.001)
> nrow(subset(wholeFrame, predicted != label))
[1] 249
> wholeFrame$predicted = predict(fit, wholeFrame, threshold=0.0001)
> nrow(subset(wholeFrame, predicted != label))
[1] 17
> wholeFrame$predicted = predict(fit, wholeFrame, threshold=0.00001)
> nrow(subset(wholeFrame, predicted != label))
[1] 3
现在,我相信 sapply 返回的数量不正确,因为当“调试”它时,我得到的东西就像.012应该是什么dnorm (49990,100,20),我认为有些东西会被遗漏/与平均值和标准差矩阵混淆,但无论如何,设置阈值将有助于此。
.001 *(10/11)&gt; pdfB *(1/11)或由于这种情况而具有高于B的后者的A意味着pdfB必须小于.01。
> dnorm(49977, 50000, 20)
[1] 0.01029681
> 2*pnorm(49977, 50000, 20)
[1] 0.2501439
由于B级有1000个观测值,我们应该预计会有大约250个误分类,这与原来的243非常接近。