Fit a multinomial or Bernoulli Naive Bayes model, given a dfm and some training labels.

textmodel_nb(x, y, smooth = 1, prior = c("uniform", "docfreq", "termfreq"),
  distribution = c("multinomial", "Bernoulli"))

Arguments

x

the dfm on which the model will be fit. Does not need to contain only the training documents.

y

vector of training labels associated with each document identified in train. (These will be converted to factors if not already factors.)

smooth

smoothing parameter for feature counts by class

prior

prior distribution on texts; one of "uniform", "docfreq", or "termfreq". See Prior Distributions below.

distribution

count model for text features, can be multinomial or Bernoulli. To fit a "binary multinomial" model, first convert the dfm to a binary matrix using dfm_weight(x, scheme = "boolean").

Value

textmodel_nb() returns a list consisting of the following (where \(I\) is the total number of documents, \(J\) is the total number of features, and \(k\) is the total number of training classes):

call

original function call

PwGc

\(k \times J\); probability of the word given the class (empirical likelihood)

Pc

\(k\)-length named numeric vector of class prior probabilities

PcGw

\(k \times J\); posterior class probability given the word

Pw

\(J \times 1\); baseline probability of the word

x

the \(I \times J\) training dfm x

y

the \(I\)-length y training class vector

distribution

the distribution argument

prior

the prior argument

smooth

the value of the smoothing parameter

Prior distributions

Prior distributions refer to the prior probabilities assigned to the training classes, and the choice of prior distribution affects the calculation of the fitted probabilities. The default is uniform priors, which sets the unconditional probability of observing the one class to be the same as observing any other class.

"Document frequency" means that the class priors will be taken from the relative proportions of the class documents used in the training set. This approach is so common that it is assumed in many examples, such as the worked example from Manning, Raghavan, and Schütze (2008) below. It is not the default in quanteda, however, since there may be nothing informative in the relative numbers of documents used to train a classifier other than the relative availability of the documents. When training classes are balanced in their number of documents (usually advisable), however, then the empirically computed "docfreq" would be equivalent to "uniform" priors.

Setting prior to "termfreq" makes the priors equal to the proportions of total feature counts found in the grouped documents in each training class, so that the classes with the largest number of features are assigned the largest priors. If the total count of features in each training class was the same, then "uniform" and "termfreq" would be the same.

References

Manning, C. D., Raghavan, P., & Schütze, H. (2008). Introduction to Information Retrieval. Cambridge University Press. https://nlp.stanford.edu/IR-book/pdf/irbookonlinereading.pdf

Jurafsky, Daniel and James H. Martin. (2016) Speech and Language Processing. Draft of November 7, 2016. https://web.stanford.edu/~jurafsky/slp3/6.pdf

See also

Examples

## Example from 13.1 of _An Introduction to Information Retrieval_ txt <- c(d1 = "Chinese Beijing Chinese", d2 = "Chinese Chinese Shanghai", d3 = "Chinese Macao", d4 = "Tokyo Japan Chinese", d5 = "Chinese Chinese Chinese Tokyo Japan") trainingset <- dfm(txt, tolower = FALSE) trainingclass <- factor(c("Y", "Y", "Y", "N", NA), ordered = TRUE) ## replicate IIR p261 prediction for test set (document 5) (nb <- textmodel_nb(trainingset, trainingclass, prior = "docfreq"))
#> #> Call: #> textmodel_nb.dfm(x = trainingset, y = trainingclass, prior = "docfreq") #> #> Distribution: multinomial; prior: docfreq; smoothing value: 1; 4 training documents; 6 fitted features.
summary(nb)
#> #> Call: #> textmodel_nb.dfm(x = trainingset, y = trainingclass, prior = "docfreq") #> #> Class Priors: #> (showing first 2 elements) #> Y N #> 0.75 0.25 #> #> Estimated Feature Scores: #> Chinese Beijing Shanghai Macao Tokyo Japan #> Y 0.8526 0.7941 0.7941 0.7941 0.4909 0.4909 #> N 0.1474 0.2059 0.2059 0.2059 0.5091 0.5091
coef(nb)
#> classes #> features Y N #> Chinese 0.8526316 0.1473684 #> Beijing 0.7941176 0.2058824 #> Shanghai 0.7941176 0.2058824 #> Macao 0.7941176 0.2058824 #> Tokyo 0.4909091 0.5090909 #> Japan 0.4909091 0.5090909
predict(nb)
#> $log.posterior.lik #> Y N #> d1 -3.928188 -6.591674 #> d2 -3.928188 -6.591674 #> d3 -3.080890 -5.087596 #> d4 -6.413095 -5.898527 #> d5 -8.107690 -8.906681 #> #> $posterior.prob #> Y N #> d1 0.9348373 0.06516267 #> d2 0.9348373 0.06516267 #> d3 0.8814994 0.11850060 #> d4 0.3741233 0.62587672 #> d5 0.6897586 0.31024139 #> #> $nb.predicted #> [1] "Y" "Y" "Y" "N" "Y" #> #> $Pc #> Y N #> 0.75 0.25 #> #> $classlabels #> [1] "Y" "N" #> #> $call #> predict.textmodel_nb(object = nb) #>
# contrast with other priors predict(textmodel_nb(trainingset, trainingclass, prior = "uniform"))
#> $log.posterior.lik #> Y N #> d1 -4.333653 -5.898527 #> d2 -4.333653 -5.898527 #> d3 -3.486355 -4.394449 #> d4 -6.818560 -5.205379 #> d5 -8.513155 -8.213534 #> #> $posterior.prob #> Y N #> d1 0.8270516 0.1729484 #> d2 0.8270516 0.1729484 #> d3 0.7126100 0.2873900 #> d4 0.1661475 0.8338525 #> d5 0.4256501 0.5743499 #> #> $nb.predicted #> [1] "Y" "Y" "Y" "N" "N" #> #> $Pc #> Y N #> 0.5 0.5 #> #> $classlabels #> [1] "Y" "N" #> #> $call #> predict.textmodel_nb(object = textmodel_nb(trainingset, trainingclass, #> prior = "uniform")) #>
predict(textmodel_nb(trainingset, trainingclass, prior = "termfreq"))
#> $log.posterior.lik #> Y N #> d1 -3.958960 -6.504662 #> d2 -3.958960 -6.504662 #> d3 -3.111662 -5.000585 #> d4 -6.443866 -5.811515 #> d5 -8.138462 -8.819670 #> #> $posterior.prob #> Y N #> d1 0.9272843 0.07271571 #> d2 0.9272843 0.07271571 #> d3 0.8686327 0.13136729 #> d4 0.3469776 0.65302237 #> d5 0.6640083 0.33599174 #> #> $nb.predicted #> [1] "Y" "Y" "Y" "N" "Y" #> #> $Pc #> Y N #> 0.7272727 0.2727273 #> #> $classlabels #> [1] "Y" "N" #> #> $call #> predict.textmodel_nb(object = textmodel_nb(trainingset, trainingclass, #> prior = "termfreq")) #>
## replicate IIR p264 Bernoulli Naive Bayes nb_bern <- textmodel_nb(trainingset, trainingclass, distribution = "Bernoulli", prior = "docfreq") predict(nb_bern, newdata = trainingset[5, ])
#> $log.posterior.lik #> Y N #> d5 -5.262178 -3.819085 #> #> $posterior.prob #> Y N #> d5 0.1910668 0.8089332 #> #> $nb.predicted #> [1] "N" #> #> $Pc #> Y N #> 0.75 0.25 #> #> $classlabels #> [1] "Y" "N" #> #> $call #> predict.textmodel_nb(object = nb_bern, newdata = trainingset[5, #> ]) #>