question: private float wittenBell ( int [ ] ngram , int ngramOrder ) { int end = ngram . length ; double p = p0 ; int MAX_QCOUNT = getCount ( ngram , ngram . length - 1 , ngram . length , maxQ ) ; if ( MAX_QCOUNT == 0 ) return ( float ) p ; double pML = Math . log ( unQuantize ( MAX_QCOUNT ) ) - numTokens ; p = logAdd ( p , ( lambda0 + pML ) ) ; if ( ngram . length == 1 ) { return ( float ) p ; } for ( int i = end - 2 ; i >= end - ngramOrder && i >= 0 ; i -- ) { int historyCnt = getCount ( ngram , i , end , MAX_QCOUNT ) ; if ( historyCnt == 0 ) { return ( float ) p ; } int historyTypesAfter = getTypesAfter ( ngram , i , end , historyCnt ) ; double HC = unQuantize ( historyCnt ) ; double HTA = 1 + unQuantize ( historyTypesAfter ) ; double lambda = Math . log ( HTA ) - Math . log ( HTA + HC ) ; double oneMinusLambda = Math . log ( HC ) - Math . log ( HTA + HC ) ; p += oneMinusLambda ; int wordCount = getCount ( ngram , i + 1 , end , historyTypesAfter ) ; double WC = unQuantize ( wordCount ) ; if ( WC == 0 ) return ( float ) p ; p = logAdd ( p , lambda + Math . log ( WC ) - Math . log ( HC ) ) ; MAX_QCOUNT = wordCount ; } return ( float ) p ; }
target:  calculates the linearly-interpolated Witten-Bell probability for a given ngram. this is calculated as: p(w|h) = pML(w|h)L(h) - (1 - L(h))p(w|h') where: w is a word and h is a history h' is the history h with the first word removed pML is the maximum-likelihood estimate of the probability L(.) is lambda, the interpolation factor, which depends only on the history h: L(h) = s(h) / s(h) + c(h) where s(.) is the observed number of distinct types after h, and c is the observed number of counts of h in the training corpus. <p> in fact this model calculates the probability starting from the lowest order and working its way up, to take advantage of the one- sided error rate inherent in using a bloom filter data structure.