nltk 3.2__zip → 3.3__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nltk-3.2 → nltk-3.3}/INSTALL.txt +6 -6
- {nltk-3.2 → nltk-3.3}/LICENSE.txt +13 -13
- {nltk-3.2 → nltk-3.3}/MANIFEST.in +6 -6
- {nltk-3.2/nltk.egg-info → nltk-3.3}/PKG-INFO +13 -5
- nltk-3.2/README.txt → nltk-3.3/README.md +49 -48
- nltk-3.3/nltk/VERSION +1 -0
- {nltk-3.2 → nltk-3.3}/nltk/__init__.py +185 -185
- {nltk-3.2 → nltk-3.3}/nltk/app/__init__.py +52 -53
- {nltk-3.2 → nltk-3.3}/nltk/app/chartparser_app.py +2276 -2276
- {nltk-3.2 → nltk-3.3}/nltk/app/chunkparser_app.py +1262 -1264
- {nltk-3.2 → nltk-3.3}/nltk/app/collocations_app.py +347 -350
- {nltk-3.2 → nltk-3.3}/nltk/app/concordance_app.py +568 -570
- {nltk-3.2 → nltk-3.3}/nltk/app/nemo_app.py +156 -155
- {nltk-3.2 → nltk-3.3}/nltk/app/rdparser_app.py +892 -894
- {nltk-3.2 → nltk-3.3}/nltk/app/srparser_app.py +809 -809
- {nltk-3.2 → nltk-3.3}/nltk/app/wordfreq_app.py +32 -32
- {nltk-3.2 → nltk-3.3}/nltk/app/wordnet_app.py +968 -968
- {nltk-3.2 → nltk-3.3}/nltk/book.py +91 -90
- {nltk-3.2 → nltk-3.3}/nltk/ccg/__init__.py +22 -22
- {nltk-3.2 → nltk-3.3}/nltk/ccg/api.py +359 -335
- {nltk-3.2 → nltk-3.3}/nltk/ccg/chart.py +394 -361
- {nltk-3.2 → nltk-3.3}/nltk/ccg/combinator.py +343 -312
- {nltk-3.2 → nltk-3.3}/nltk/ccg/lexicon.py +328 -290
- nltk-3.3/nltk/ccg/logic.py +46 -0
- {nltk-3.2 → nltk-3.3}/nltk/chat/__init__.py +49 -49
- {nltk-3.2 → nltk-3.3}/nltk/chat/eliza.py +244 -244
- {nltk-3.2 → nltk-3.3}/nltk/chat/iesha.py +140 -140
- {nltk-3.2 → nltk-3.3}/nltk/chat/rude.py +92 -92
- {nltk-3.2 → nltk-3.3}/nltk/chat/suntsu.py +117 -117
- {nltk-3.2 → nltk-3.3}/nltk/chat/util.py +122 -120
- {nltk-3.2 → nltk-3.3}/nltk/chat/zen.py +282 -282
- {nltk-3.2 → nltk-3.3}/nltk/chunk/__init__.py +190 -190
- {nltk-3.2 → nltk-3.3}/nltk/chunk/api.py +51 -51
- {nltk-3.2 → nltk-3.3}/nltk/chunk/named_entity.py +331 -331
- {nltk-3.2 → nltk-3.3}/nltk/chunk/regexp.py +1390 -1384
- {nltk-3.2 → nltk-3.3}/nltk/chunk/util.py +600 -600
- {nltk-3.2 → nltk-3.3}/nltk/classify/__init__.py +98 -98
- {nltk-3.2 → nltk-3.3}/nltk/classify/api.py +193 -193
- {nltk-3.2 → nltk-3.3}/nltk/classify/decisiontree.py +295 -295
- {nltk-3.2 → nltk-3.3}/nltk/classify/maxent.py +1510 -1492
- {nltk-3.2 → nltk-3.3}/nltk/classify/megam.py +179 -178
- {nltk-3.2 → nltk-3.3}/nltk/classify/naivebayes.py +245 -242
- {nltk-3.2 → nltk-3.3}/nltk/classify/positivenaivebayes.py +170 -170
- {nltk-3.2 → nltk-3.3}/nltk/classify/rte_classify.py +160 -191
- {nltk-3.2 → nltk-3.3}/nltk/classify/scikitlearn.py +153 -151
- {nltk-3.2 → nltk-3.3}/nltk/classify/senna.py +183 -181
- {nltk-3.2 → nltk-3.3}/nltk/classify/svm.py +15 -15
- {nltk-3.2 → nltk-3.3}/nltk/classify/tadm.py +113 -112
- {nltk-3.2 → nltk-3.3}/nltk/classify/textcat.py +193 -193
- {nltk-3.2 → nltk-3.3}/nltk/classify/util.py +324 -312
- {nltk-3.2 → nltk-3.3}/nltk/classify/weka.py +346 -345
- {nltk-3.2 → nltk-3.3}/nltk/cluster/__init__.py +86 -86
- {nltk-3.2 → nltk-3.3}/nltk/cluster/api.py +74 -70
- {nltk-3.2 → nltk-3.3}/nltk/cluster/em.py +247 -247
- {nltk-3.2 → nltk-3.3}/nltk/cluster/gaac.py +168 -168
- {nltk-3.2 → nltk-3.3}/nltk/cluster/kmeans.py +221 -221
- {nltk-3.2 → nltk-3.3}/nltk/cluster/util.py +304 -289
- nltk-3.3/nltk/collections.py +640 -0
- {nltk-3.2 → nltk-3.3}/nltk/collocations.py +388 -388
- nltk-3.3/nltk/compat.py +365 -0
- {nltk-3.2 → nltk-3.3}/nltk/corpus/__init__.py +341 -320
- {nltk-3.2 → nltk-3.3}/nltk/corpus/europarl_raw.py +44 -44
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/__init__.py +147 -145
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/aligned.py +115 -114
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/api.py +448 -446
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bnc.py +252 -252
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bracket_parse.py +227 -227
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/categorized_sents.py +179 -178
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chasen.py +140 -139
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/childes.py +522 -494
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chunked.py +212 -212
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/cmudict.py +97 -95
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/comparative_sents.py +280 -278
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/conll.py +528 -521
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/crubadan.py +116 -116
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/dependency.py +101 -101
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/framenet.py +3059 -2093
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ieer.py +112 -111
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/indian.py +85 -86
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ipipan.py +332 -331
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/knbc.py +187 -187
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/lin.py +156 -156
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/mte.py +311 -310
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nkjp.py +429 -428
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nombank.py +421 -421
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nps_chat.py +73 -73
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/opinion_lexicon.py +115 -115
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/panlex_lite.py +165 -165
- nltk-3.3/nltk/corpus/reader/pl196x.py +292 -0
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/plaintext.py +232 -233
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ppattach.py +96 -95
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/propbank.py +479 -481
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/pros_cons.py +128 -126
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/reviews.py +330 -328
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/rte.py +144 -146
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/semcor.py +256 -256
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/senseval.py +203 -201
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sentiwordnet.py +137 -137
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sinica_treebank.py +75 -75
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/string_category.py +60 -59
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/switchboard.py +119 -119
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/tagged.py +295 -294
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/timit.py +452 -450
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/toolbox.py +68 -68
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/twitter.py +155 -157
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/udhr.py +80 -80
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/util.py +804 -800
- nltk-3.3/nltk/corpus/reader/verbnet.py +595 -0
- nltk-3.3/nltk/corpus/reader/wordlist.py +134 -0
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/wordnet.py +2108 -2036
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/xmldocs.py +392 -387
- {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ycoe.py +243 -242
- {nltk-3.2 → nltk-3.3}/nltk/corpus/util.py +144 -127
- {nltk-3.2 → nltk-3.3}/nltk/data.py +1487 -1451
- {nltk-3.2 → nltk-3.3}/nltk/decorators.py +219 -215
- {nltk-3.2 → nltk-3.3}/nltk/downloader.py +2278 -2274
- {nltk-3.2 → nltk-3.3}/nltk/draw/__init__.py +27 -27
- {nltk-3.2 → nltk-3.3}/nltk/draw/cfg.py +774 -777
- {nltk-3.2 → nltk-3.3}/nltk/draw/dispersion.py +58 -58
- {nltk-3.2 → nltk-3.3}/nltk/draw/table.py +1098 -1098
- {nltk-3.2 → nltk-3.3}/nltk/draw/tree.py +963 -966
- {nltk-3.2 → nltk-3.3}/nltk/draw/util.py +2356 -2356
- {nltk-3.2 → nltk-3.3}/nltk/featstruct.py +2617 -2500
- {nltk-3.2 → nltk-3.3}/nltk/grammar.py +1559 -1516
- {nltk-3.2 → nltk-3.3}/nltk/help.py +56 -56
- {nltk-3.2 → nltk-3.3}/nltk/inference/__init__.py +20 -20
- {nltk-3.2 → nltk-3.3}/nltk/inference/api.py +597 -589
- {nltk-3.2 → nltk-3.3}/nltk/inference/discourse.py +612 -608
- {nltk-3.2 → nltk-3.3}/nltk/inference/mace.py +311 -311
- {nltk-3.2 → nltk-3.3}/nltk/inference/nonmonotonic.py +509 -509
- {nltk-3.2 → nltk-3.3}/nltk/inference/prover9.py +431 -431
- {nltk-3.2 → nltk-3.3}/nltk/inference/resolution.py +687 -687
- {nltk-3.2 → nltk-3.3}/nltk/inference/tableau.py +607 -607
- {nltk-3.2 → nltk-3.3}/nltk/internals.py +982 -982
- {nltk-3.2 → nltk-3.3}/nltk/jsontags.py +63 -63
- {nltk-3.2 → nltk-3.3}/nltk/lazyimport.py +142 -142
- {nltk-3.2 → nltk-3.3}/nltk/metrics/__init__.py +30 -29
- {nltk-3.2 → nltk-3.3}/nltk/metrics/agreement.py +421 -401
- nltk-3.3/nltk/metrics/aline.py +607 -0
- {nltk-3.2 → nltk-3.3}/nltk/metrics/association.py +414 -410
- {nltk-3.2 → nltk-3.3}/nltk/metrics/confusionmatrix.py +206 -206
- {nltk-3.2 → nltk-3.3}/nltk/metrics/distance.py +207 -202
- {nltk-3.2 → nltk-3.3}/nltk/metrics/paice.py +381 -381
- {nltk-3.2 → nltk-3.3}/nltk/metrics/scores.py +228 -228
- {nltk-3.2 → nltk-3.3}/nltk/metrics/segmentation.py +231 -232
- {nltk-3.2 → nltk-3.3}/nltk/metrics/spearman.py +69 -69
- {nltk-3.2 → nltk-3.3}/nltk/misc/__init__.py +11 -11
- {nltk-3.2 → nltk-3.3}/nltk/misc/babelfish.py +10 -10
- {nltk-3.2 → nltk-3.3}/nltk/misc/chomsky.py +135 -133
- {nltk-3.2 → nltk-3.3}/nltk/misc/minimalset.py +83 -83
- {nltk-3.2 → nltk-3.3}/nltk/misc/sort.py +157 -157
- {nltk-3.2 → nltk-3.3}/nltk/misc/wordfinder.py +129 -129
- {nltk-3.2 → nltk-3.3}/nltk/parse/__init__.py +81 -80
- {nltk-3.2 → nltk-3.3}/nltk/parse/api.py +66 -66
- {nltk-3.2 → nltk-3.3}/nltk/parse/bllip.py +282 -282
- {nltk-3.2 → nltk-3.3}/nltk/parse/chart.py +1682 -1681
- nltk-3.3/nltk/parse/corenlp.py +780 -0
- {nltk-3.2 → nltk-3.3}/nltk/parse/dependencygraph.py +760 -758
- {nltk-3.2 → nltk-3.3}/nltk/parse/earleychart.py +452 -451
- {nltk-3.2 → nltk-3.3}/nltk/parse/evaluate.py +129 -129
- {nltk-3.2 → nltk-3.3}/nltk/parse/featurechart.py +580 -578
- {nltk-3.2 → nltk-3.3}/nltk/parse/generate.py +87 -76
- {nltk-3.2 → nltk-3.3}/nltk/parse/malt.py +356 -356
- {nltk-3.2 → nltk-3.3}/nltk/parse/nonprojectivedependencyparser.py +783 -783
- {nltk-3.2 → nltk-3.3}/nltk/parse/pchart.py +522 -522
- {nltk-3.2 → nltk-3.3}/nltk/parse/projectivedependencyparser.py +579 -578
- {nltk-3.2 → nltk-3.3}/nltk/parse/recursivedescent.py +655 -656
- {nltk-3.2 → nltk-3.3}/nltk/parse/shiftreduce.py +458 -459
- {nltk-3.2 → nltk-3.3}/nltk/parse/stanford.py +431 -406
- {nltk-3.2 → nltk-3.3}/nltk/parse/transitionparser.py +774 -772
- {nltk-3.2 → nltk-3.3}/nltk/parse/util.py +231 -231
- {nltk-3.2 → nltk-3.3}/nltk/parse/viterbi.py +401 -401
- {nltk-3.2 → nltk-3.3}/nltk/probability.py +2410 -2355
- {nltk-3.2 → nltk-3.3}/nltk/sem/__init__.py +61 -61
- {nltk-3.2 → nltk-3.3}/nltk/sem/boxer.py +1261 -1261
- {nltk-3.2 → nltk-3.3}/nltk/sem/chat80.py +782 -782
- {nltk-3.2 → nltk-3.3}/nltk/sem/cooper_storage.py +118 -118
- {nltk-3.2 → nltk-3.3}/nltk/sem/drt.py +1258 -1257
- {nltk-3.2 → nltk-3.3}/nltk/sem/drt_glue_demo.py +485 -489
- {nltk-3.2 → nltk-3.3}/nltk/sem/evaluate.py +790 -784
- {nltk-3.2 → nltk-3.3}/nltk/sem/glue.py +696 -694
- {nltk-3.2 → nltk-3.3}/nltk/sem/hole.py +386 -384
- {nltk-3.2 → nltk-3.3}/nltk/sem/lfg.py +210 -208
- {nltk-3.2 → nltk-3.3}/nltk/sem/linearlogic.py +451 -449
- {nltk-3.2 → nltk-3.3}/nltk/sem/logic.py +1910 -1910
- {nltk-3.2 → nltk-3.3}/nltk/sem/relextract.py +476 -483
- {nltk-3.2 → nltk-3.3}/nltk/sem/skolemize.py +101 -101
- {nltk-3.2 → nltk-3.3}/nltk/sem/util.py +249 -249
- {nltk-3.2 → nltk-3.3}/nltk/sentiment/__init__.py +14 -14
- {nltk-3.2 → nltk-3.3}/nltk/sentiment/sentiment_analyzer.py +229 -229
- {nltk-3.2 → nltk-3.3}/nltk/sentiment/util.py +762 -752
- {nltk-3.2 → nltk-3.3}/nltk/sentiment/vader.py +443 -445
- {nltk-3.2 → nltk-3.3}/nltk/stem/__init__.py +31 -33
- {nltk-3.2 → nltk-3.3}/nltk/stem/api.py +28 -25
- nltk-3.3/nltk/stem/arlstem.py +369 -0
- {nltk-3.2 → nltk-3.3}/nltk/stem/isri.py +345 -345
- {nltk-3.2 → nltk-3.3}/nltk/stem/lancaster.py +337 -310
- nltk-3.3/nltk/stem/porter.py +710 -0
- {nltk-3.2 → nltk-3.3}/nltk/stem/regexp.py +61 -61
- {nltk-3.2 → nltk-3.3}/nltk/stem/rslp.py +142 -142
- {nltk-3.2 → nltk-3.3}/nltk/stem/snowball.py +4236 -3712
- {nltk-3.2 → nltk-3.3}/nltk/stem/util.py +22 -12
- {nltk-3.2 → nltk-3.3}/nltk/stem/wordnet.py +51 -51
- {nltk-3.2 → nltk-3.3}/nltk/tag/__init__.py +152 -127
- {nltk-3.2 → nltk-3.3}/nltk/tag/api.py +86 -81
- {nltk-3.2 → nltk-3.3}/nltk/tag/brill.py +424 -426
- {nltk-3.2 → nltk-3.3}/nltk/tag/brill_trainer.py +608 -608
- {nltk-3.2 → nltk-3.3}/nltk/tag/crf.py +204 -200
- {nltk-3.2 → nltk-3.3}/nltk/tag/hmm.py +1277 -1277
- {nltk-3.2 → nltk-3.3}/nltk/tag/hunpos.py +132 -132
- {nltk-3.2 → nltk-3.3}/nltk/tag/mapping.py +101 -101
- {nltk-3.2 → nltk-3.3}/nltk/tag/perceptron.py +329 -314
- {nltk-3.2 → nltk-3.3}/nltk/tag/senna.py +147 -145
- {nltk-3.2 → nltk-3.3}/nltk/tag/sequential.py +740 -736
- {nltk-3.2 → nltk-3.3}/nltk/tag/stanford.py +219 -196
- {nltk-3.2 → nltk-3.3}/nltk/tag/tnt.py +595 -604
- {nltk-3.2 → nltk-3.3}/nltk/tag/util.py +72 -72
- {nltk-3.2 → nltk-3.3}/nltk/tbl/__init__.py +28 -28
- {nltk-3.2 → nltk-3.3}/nltk/tbl/api.py +1 -1
- {nltk-3.2 → nltk-3.3}/nltk/tbl/demo.py +366 -366
- {nltk-3.2 → nltk-3.3}/nltk/tbl/erroranalysis.py +39 -39
- {nltk-3.2 → nltk-3.3}/nltk/tbl/feature.py +259 -261
- {nltk-3.2 → nltk-3.3}/nltk/tbl/rule.py +321 -321
- {nltk-3.2 → nltk-3.3}/nltk/tbl/template.py +303 -308
- {nltk-3.2 → nltk-3.3}/nltk/test/__init__.py +18 -18
- {nltk-3.2 → nltk-3.3}/nltk/test/all.py +24 -23
- {nltk-3.2 → nltk-3.3}/nltk/test/bleu.doctest +14 -14
- {nltk-3.2 → nltk-3.3}/nltk/test/bnc.doctest +60 -60
- {nltk-3.2 → nltk-3.3}/nltk/test/ccg.doctest +376 -395
- nltk-3.3/nltk/test/ccg_semantics.doctest +553 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/chat80.doctest +234 -234
- {nltk-3.2 → nltk-3.3}/nltk/test/childes.doctest +184 -184
- {nltk-3.2 → nltk-3.3}/nltk/test/childes_fixt.py +14 -13
- {nltk-3.2 → nltk-3.3}/nltk/test/chunk.doctest +373 -373
- {nltk-3.2 → nltk-3.3}/nltk/test/classify.doctest +185 -185
- {nltk-3.2 → nltk-3.3}/nltk/test/classify_fixt.py +11 -10
- nltk-3.3/nltk/test/collections.doctest +20 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/collocations.doctest +276 -276
- {nltk-3.2 → nltk-3.3}/nltk/test/compat.doctest +134 -138
- {nltk-3.2 → nltk-3.3}/nltk/test/compat_fixt.py +9 -8
- nltk-3.3/nltk/test/concordance.doctest +55 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/corpus.doctest +2200 -2212
- {nltk-3.2 → nltk-3.3}/nltk/test/corpus_fixt.py +3 -3
- {nltk-3.2 → nltk-3.3}/nltk/test/crubadan.doctest +65 -65
- {nltk-3.2 → nltk-3.3}/nltk/test/data.doctest +379 -379
- {nltk-3.2 → nltk-3.3}/nltk/test/dependency.doctest +241 -241
- {nltk-3.2 → nltk-3.3}/nltk/test/discourse.doctest +546 -546
- {nltk-3.2 → nltk-3.3}/nltk/test/discourse_fixt.py +14 -13
- {nltk-3.2 → nltk-3.3}/nltk/test/doctest_nose_plugin.py +159 -156
- {nltk-3.2 → nltk-3.3}/nltk/test/drt.doctest +517 -517
- {nltk-3.2 → nltk-3.3}/nltk/test/featgram.doctest +607 -607
- {nltk-3.2 → nltk-3.3}/nltk/test/featstruct.doctest +1229 -1230
- {nltk-3.2 → nltk-3.3}/nltk/test/framenet.doctest +288 -239
- {nltk-3.2 → nltk-3.3}/nltk/test/generate.doctest +67 -67
- {nltk-3.2 → nltk-3.3}/nltk/test/gensim.doctest +140 -141
- {nltk-3.2 → nltk-3.3}/nltk/test/gensim_fixt.py +10 -9
- {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics.doctest +384 -386
- {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt.doctest +68 -68
- {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt_fixt.py +12 -11
- {nltk-3.2 → nltk-3.3}/nltk/test/grammar.doctest +48 -48
- {nltk-3.2 → nltk-3.3}/nltk/test/grammartestsuites.doctest +109 -109
- {nltk-3.2 → nltk-3.3}/nltk/test/index.doctest +100 -100
- {nltk-3.2 → nltk-3.3}/nltk/test/inference.doctest +534 -534
- {nltk-3.2 → nltk-3.3}/nltk/test/inference_fixt.py +12 -11
- {nltk-3.2 → nltk-3.3}/nltk/test/internals.doctest +140 -140
- {nltk-3.2 → nltk-3.3}/nltk/test/japanese.doctest +48 -48
- {nltk-3.2 → nltk-3.3}/nltk/test/logic.doctest +1098 -1098
- {nltk-3.2 → nltk-3.3}/nltk/test/metrics.doctest +270 -270
- {nltk-3.2 → nltk-3.3}/nltk/test/misc.doctest +118 -118
- {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic.doctest +286 -286
- {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic_fixt.py +12 -11
- {nltk-3.2 → nltk-3.3}/nltk/test/paice.doctest +35 -35
- {nltk-3.2 → nltk-3.3}/nltk/test/parse.doctest +884 -884
- {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en.doctest +565 -565
- {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en_fixt.py +16 -16
- {nltk-3.2 → nltk-3.3}/nltk/test/probability.doctest +304 -304
- {nltk-3.2 → nltk-3.3}/nltk/test/probability_fixt.py +13 -12
- {nltk-3.2 → nltk-3.3}/nltk/test/propbank.doctest +176 -176
- {nltk-3.2 → nltk-3.3}/nltk/test/relextract.doctest +263 -263
- {nltk-3.2 → nltk-3.3}/nltk/test/resolution.doctest +221 -221
- {nltk-3.2 → nltk-3.3}/nltk/test/runtests.py +86 -64
- {nltk-3.2 → nltk-3.3}/nltk/test/segmentation_fixt.py +10 -10
- {nltk-3.2 → nltk-3.3}/nltk/test/semantics.doctest +665 -665
- {nltk-3.2 → nltk-3.3}/nltk/test/semantics_fixt.py +7 -7
- {nltk-3.2 → nltk-3.3}/nltk/test/sentiment.doctest +233 -233
- {nltk-3.2 → nltk-3.3}/nltk/test/sentiwordnet.doctest +41 -41
- {nltk-3.2 → nltk-3.3}/nltk/test/simple.doctest +85 -85
- {nltk-3.2 → nltk-3.3}/nltk/test/stem.doctest +78 -78
- {nltk-3.2 → nltk-3.3}/nltk/test/tag.doctest +33 -33
- {nltk-3.2 → nltk-3.3}/nltk/test/tokenize.doctest +273 -166
- {nltk-3.2 → nltk-3.3}/nltk/test/toolbox.doctest +307 -307
- {nltk-3.2 → nltk-3.3}/nltk/test/translate.doctest +242 -242
- {nltk-3.2 → nltk-3.3}/nltk/test/translate_fixt.py +3 -3
- {nltk-3.2 → nltk-3.3}/nltk/test/tree.doctest +1101 -1101
- {nltk-3.2 → nltk-3.3}/nltk/test/treeprettyprinter.doctest +127 -127
- {nltk-3.2 → nltk-3.3}/nltk/test/treetransforms.doctest +156 -156
- nltk-3.3/nltk/test/unit/test_2x_compat.py +63 -0
- nltk-3.3/nltk/test/unit/test_aline.py +52 -0
- nltk-3.3/nltk/test/unit/test_chunk.py +56 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_classify.py +55 -53
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_collocations.py +88 -79
- nltk-3.3/nltk/test/unit/test_concordance.py +98 -0
- nltk-3.3/nltk/test/unit/test_corenlp.py +1000 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpora.py +200 -183
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpus_views.py +45 -45
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_hmm.py +88 -88
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_json2csv_corpus.py +188 -187
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_naivebayes.py +26 -26
- nltk-3.3/nltk/test/unit/test_rte_classify.py +86 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_seekable_unicode_stream_reader.py +124 -124
- nltk-3.3/nltk/test/unit/test_senna.py +74 -0
- nltk-3.3/nltk/test/unit/test_stem.py +121 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tag.py +20 -20
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tgrep.py +628 -626
- nltk-3.3/nltk/test/unit/test_tokenize.py +168 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_twitter_auth.py +185 -185
- nltk-3.3/nltk/test/unit/test_wordnet.py +134 -0
- nltk-3.3/nltk/test/unit/translate/test_bleu.py +244 -0
- nltk-3.3/nltk/test/unit/translate/test_gdfa.py +57 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm1.py +75 -75
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm2.py +87 -87
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm3.py +105 -105
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm4.py +126 -126
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm5.py +166 -166
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm_model.py +270 -270
- nltk-3.3/nltk/test/unit/translate/test_nist.py +37 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_stack_decoder.py +300 -300
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/utils.py +41 -41
- {nltk-3.2 → nltk-3.3}/nltk/test/util.doctest +48 -48
- {nltk-3.2 → nltk-3.3}/nltk/test/wordnet.doctest +595 -581
- {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_fixt.py +7 -6
- {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_lch.doctest +53 -53
- {nltk-3.2 → nltk-3.3}/nltk/test/wsd.doctest +68 -68
- {nltk-3.2 → nltk-3.3}/nltk/text.py +663 -610
- {nltk-3.2 → nltk-3.3}/nltk/tgrep.py +938 -937
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/__init__.py +130 -107
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/api.py +77 -78
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/casual.py +343 -342
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/mwe.py +120 -120
- nltk-3.3/nltk/tokenize/nist.py +173 -0
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/punkt.py +1620 -1601
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/regexp.py +208 -202
- nltk-3.3/nltk/tokenize/repp.py +151 -0
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/sexpr.py +140 -142
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/simple.py +138 -136
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/stanford.py +117 -113
- nltk-3.3/nltk/tokenize/stanford_segmenter.py +246 -0
- {nltk-3.2 → nltk-3.3}/nltk/tokenize/texttiling.py +458 -460
- nltk-3.3/nltk/tokenize/toktok.py +155 -0
- nltk-3.3/nltk/tokenize/treebank.py +363 -0
- nltk-3.3/nltk/tokenize/util.py +261 -0
- {nltk-3.2 → nltk-3.3}/nltk/toolbox.py +499 -497
- {nltk-3.2 → nltk-3.3}/nltk/translate/__init__.py +24 -24
- {nltk-3.2 → nltk-3.3}/nltk/translate/api.py +331 -321
- {nltk-3.2 → nltk-3.3}/nltk/translate/bleu_score.py +615 -556
- nltk-3.3/nltk/translate/chrf_score.py +137 -0
- {nltk-3.2 → nltk-3.3}/nltk/translate/gale_church.py +248 -235
- {nltk-3.2 → nltk-3.3}/nltk/translate/gdfa.py +135 -131
- nltk-3.3/nltk/translate/gleu_score.py +193 -0
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm1.py +250 -241
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm2.py +308 -308
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm3.py +337 -337
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm4.py +467 -467
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm5.py +639 -639
- {nltk-3.2 → nltk-3.3}/nltk/translate/ibm_model.py +536 -533
- {nltk-3.2 → nltk-3.3}/nltk/translate/metrics.py +40 -40
- nltk-3.3/nltk/translate/nist_score.py +178 -0
- {nltk-3.2 → nltk-3.3}/nltk/translate/phrase_based.py +175 -175
- {nltk-3.2 → nltk-3.3}/nltk/translate/ribes_score.py +325 -325
- {nltk-3.2 → nltk-3.3}/nltk/translate/stack_decoder.py +499 -495
- {nltk-3.2 → nltk-3.3}/nltk/tree.py +1605 -1603
- {nltk-3.2 → nltk-3.3}/nltk/treeprettyprinter.py +564 -564
- {nltk-3.2 → nltk-3.3}/nltk/treetransforms.py +309 -309
- {nltk-3.2 → nltk-3.3}/nltk/twitter/__init__.py +28 -28
- {nltk-3.2 → nltk-3.3}/nltk/twitter/api.py +141 -136
- {nltk-3.2 → nltk-3.3}/nltk/twitter/common.py +264 -258
- {nltk-3.2 → nltk-3.3}/nltk/twitter/twitter_demo.py +288 -288
- {nltk-3.2 → nltk-3.3}/nltk/twitter/twitterclient.py +530 -530
- {nltk-3.2 → nltk-3.3}/nltk/twitter/util.py +147 -146
- nltk-3.3/nltk/util.py +751 -0
- {nltk-3.2 → nltk-3.3}/nltk/wsd.py +53 -53
- {nltk-3.2 → nltk-3.3/nltk.egg-info}/PKG-INFO +13 -5
- {nltk-3.2 → nltk-3.3}/nltk.egg-info/SOURCES.txt +26 -3
- nltk-3.3/nltk.egg-info/requires.txt +31 -0
- {nltk-3.2 → nltk-3.3}/setup.cfg +0 -1
- {nltk-3.2 → nltk-3.3}/setup.py +102 -75
- nltk-3.2/nltk/VERSION +0 -1
- nltk-3.2/nltk/compat.py +0 -680
- nltk-3.2/nltk/corpus/reader/pl196x.py +0 -278
- nltk-3.2/nltk/corpus/reader/verbnet.py +0 -408
- nltk-3.2/nltk/corpus/reader/wordlist.py +0 -37
- nltk-3.2/nltk/sentiment/vader_lexicon.txt +0 -7517
- nltk-3.2/nltk/six.py +0 -868
- nltk-3.2/nltk/stem/porter.py +0 -692
- nltk-3.2/nltk/test/unit/test_2x_compat.py +0 -26
- nltk-3.2/nltk/test/unit/test_stem.py +0 -36
- nltk-3.2/nltk/test/unit/test_tokenize.py +0 -23
- nltk-3.2/nltk/test/unit/translate/test_bleu.py +0 -84
- nltk-3.2/nltk/tokenize/treebank.py +0 -124
- nltk-3.2/nltk/tokenize/util.py +0 -90
- nltk-3.2/nltk/util.py +0 -1364
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/__init__.py +0 -0
- {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/__init__.py +0 -0
- {nltk-3.2 → nltk-3.3}/nltk.egg-info/dependency_links.txt +0 -0
- {nltk-3.2 → nltk-3.3}/nltk.egg-info/not-zip-safe +0 -0
- {nltk-3.2 → nltk-3.3}/nltk.egg-info/top_level.txt +0 -0
|
@@ -1,242 +1,245 @@
|
|
|
1
|
-
# Natural Language Toolkit: Naive Bayes Classifiers
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2001-
|
|
4
|
-
# Author: Edward Loper <edloper@gmail.com>
|
|
5
|
-
# URL: <http://nltk.org/>
|
|
6
|
-
# For license information, see LICENSE.TXT
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
A classifier based on the Naive Bayes algorithm. In order to find the
|
|
10
|
-
probability for a label, this algorithm first uses the Bayes rule to
|
|
11
|
-
express P(label|features) in terms of P(label) and P(features|label):
|
|
12
|
-
|
|
13
|
-
| P(label) * P(features|label)
|
|
14
|
-
| P(label|features) = ------------------------------
|
|
15
|
-
| P(features)
|
|
16
|
-
|
|
17
|
-
The algorithm then makes the 'naive' assumption that all features are
|
|
18
|
-
independent, given the label:
|
|
19
|
-
|
|
20
|
-
| P(label) * P(f1|label) * ... * P(fn|label)
|
|
21
|
-
| P(label|features) = --------------------------------------------
|
|
22
|
-
| P(features)
|
|
23
|
-
|
|
24
|
-
Rather than computing P(
|
|
25
|
-
calculates the
|
|
26
|
-
sum to one:
|
|
27
|
-
|
|
28
|
-
| P(label) * P(f1|label) * ... * P(fn|label)
|
|
29
|
-
| P(label|features) = --------------------------------------------
|
|
30
|
-
| SUM[l]( P(l) * P(f1|l) * ... * P(fn|l) )
|
|
31
|
-
"""
|
|
32
|
-
from __future__ import print_function, unicode_literals
|
|
33
|
-
|
|
34
|
-
from collections import defaultdict
|
|
35
|
-
|
|
36
|
-
from nltk.probability import FreqDist, DictionaryProbDist, ELEProbDist, sum_logs
|
|
37
|
-
from nltk.classify.api import ClassifierI
|
|
38
|
-
|
|
39
|
-
##//////////////////////////////////////////////////////
|
|
40
|
-
## Naive Bayes Classifier
|
|
41
|
-
##//////////////////////////////////////////////////////
|
|
42
|
-
|
|
43
|
-
class NaiveBayesClassifier(ClassifierI):
|
|
44
|
-
"""
|
|
45
|
-
A Naive Bayes classifier. Naive Bayes classifiers are
|
|
46
|
-
paramaterized by two probability distributions:
|
|
47
|
-
|
|
48
|
-
- P(label) gives the probability that an input will receive each
|
|
49
|
-
label, given no information about the input's features.
|
|
50
|
-
|
|
51
|
-
- P(fname=fval|label) gives the probability that a given feature
|
|
52
|
-
(fname) will receive a given value (fval), given that the
|
|
53
|
-
label (label).
|
|
54
|
-
|
|
55
|
-
If the classifier encounters an input with a feature that has
|
|
56
|
-
never been seen with any label, then rather than assigning a
|
|
57
|
-
probability of 0 to all labels, it will ignore that feature.
|
|
58
|
-
|
|
59
|
-
The feature value 'None' is reserved for unseen feature values;
|
|
60
|
-
you generally should not use 'None' as a feature value for one of
|
|
61
|
-
your own features.
|
|
62
|
-
"""
|
|
63
|
-
def __init__(self, label_probdist, feature_probdist):
|
|
64
|
-
"""
|
|
65
|
-
:param label_probdist: P(label), the probability distribution
|
|
66
|
-
over labels. It is expressed as a ``ProbDistI`` whose
|
|
67
|
-
samples are labels. I.e., P(label) =
|
|
68
|
-
``label_probdist.prob(label)``.
|
|
69
|
-
|
|
70
|
-
:param feature_probdist: P(fname=fval|label), the probability
|
|
71
|
-
distribution for feature values, given labels. It is
|
|
72
|
-
expressed as a dictionary whose keys are ``(label, fname)``
|
|
73
|
-
pairs and whose values are ``ProbDistI`` objects over feature
|
|
74
|
-
values. I.e., P(fname=fval|label) =
|
|
75
|
-
``feature_probdist[label,fname].prob(fval)``. If a given
|
|
76
|
-
``(label,fname)`` is not a key in ``feature_probdist``, then
|
|
77
|
-
it is assumed that the corresponding P(fname=fval|label)
|
|
78
|
-
is 0 for all values of ``fval``.
|
|
79
|
-
"""
|
|
80
|
-
self._label_probdist = label_probdist
|
|
81
|
-
self._feature_probdist = feature_probdist
|
|
82
|
-
self._labels = list(label_probdist.samples())
|
|
83
|
-
|
|
84
|
-
def labels(self):
|
|
85
|
-
return self._labels
|
|
86
|
-
|
|
87
|
-
def classify(self, featureset):
|
|
88
|
-
return self.prob_classify(featureset).max()
|
|
89
|
-
|
|
90
|
-
def prob_classify(self, featureset):
|
|
91
|
-
# Discard any feature names that we've never seen before.
|
|
92
|
-
# Otherwise, we'll just assign a probability of 0 to
|
|
93
|
-
# everything.
|
|
94
|
-
featureset = featureset.copy()
|
|
95
|
-
for fname in list(featureset.keys()):
|
|
96
|
-
for label in self._labels:
|
|
97
|
-
if (label, fname) in self._feature_probdist:
|
|
98
|
-
break
|
|
99
|
-
else:
|
|
100
|
-
#print 'Ignoring unseen feature %s' % fname
|
|
101
|
-
del featureset[fname]
|
|
102
|
-
|
|
103
|
-
# Find the log probabilty of each label, given the features.
|
|
104
|
-
# Start with the log probability of the label itself.
|
|
105
|
-
logprob = {}
|
|
106
|
-
for label in self._labels:
|
|
107
|
-
logprob[label] = self._label_probdist.logprob(label)
|
|
108
|
-
|
|
109
|
-
# Then add in the log probability of features given labels.
|
|
110
|
-
for label in self._labels:
|
|
111
|
-
for (fname, fval) in featureset.items():
|
|
112
|
-
if (label, fname) in self._feature_probdist:
|
|
113
|
-
feature_probs = self._feature_probdist[label, fname]
|
|
114
|
-
logprob[label] += feature_probs.logprob(fval)
|
|
115
|
-
else:
|
|
116
|
-
# nb: This case will never come up if the
|
|
117
|
-
# classifier was created by
|
|
118
|
-
# NaiveBayesClassifier.train().
|
|
119
|
-
logprob[label] += sum_logs([]) # = -INF.
|
|
120
|
-
|
|
121
|
-
return DictionaryProbDist(logprob, normalize=True, log=True)
|
|
122
|
-
|
|
123
|
-
def show_most_informative_features(self, n=10):
|
|
124
|
-
# Determine the most relevant features, and display them.
|
|
125
|
-
cpdist = self._feature_probdist
|
|
126
|
-
print('Most Informative Features')
|
|
127
|
-
|
|
128
|
-
for (fname, fval) in self.most_informative_features(n):
|
|
129
|
-
def labelprob(l):
|
|
130
|
-
return cpdist[l, fname].prob(fval)
|
|
131
|
-
|
|
132
|
-
labels = sorted([l for l in self._labels
|
|
133
|
-
if fval in cpdist[l, fname].samples()],
|
|
134
|
-
key=labelprob)
|
|
135
|
-
if len(labels) == 1:
|
|
136
|
-
continue
|
|
137
|
-
l0 = labels[0]
|
|
138
|
-
l1 = labels[-1]
|
|
139
|
-
if cpdist[l0, fname].prob(fval) == 0:
|
|
140
|
-
ratio = 'INF'
|
|
141
|
-
else:
|
|
142
|
-
ratio = '%8.1f' % (cpdist[l1, fname].prob(fval) /
|
|
143
|
-
cpdist[l0, fname].prob(fval))
|
|
144
|
-
print(('%24s = %-14r %6s : %-6s = %s : 1.0' %
|
|
145
|
-
(fname, fval, ("%s" % l1)[:6], ("%s" % l0)[:6], ratio)))
|
|
146
|
-
|
|
147
|
-
def most_informative_features(self, n=100):
|
|
148
|
-
"""
|
|
149
|
-
Return a list of the 'most informative' features used by this
|
|
150
|
-
classifier. For the purpose of this function, the
|
|
151
|
-
informativeness of a feature ``(fname,fval)`` is equal to the
|
|
152
|
-
highest value of P(fname=fval|label), for any label, divided by
|
|
153
|
-
the lowest value of P(fname=fval|label), for any label:
|
|
154
|
-
|
|
155
|
-
| max[ P(fname=fval|label1) / P(fname=fval|label2) ]
|
|
156
|
-
"""
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"""
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
#
|
|
208
|
-
#
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
# Create the P(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
1
|
+
# Natural Language Toolkit: Naive Bayes Classifiers
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2001-2018 NLTK Project
|
|
4
|
+
# Author: Edward Loper <edloper@gmail.com>
|
|
5
|
+
# URL: <http://nltk.org/>
|
|
6
|
+
# For license information, see LICENSE.TXT
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
A classifier based on the Naive Bayes algorithm. In order to find the
|
|
10
|
+
probability for a label, this algorithm first uses the Bayes rule to
|
|
11
|
+
express P(label|features) in terms of P(label) and P(features|label):
|
|
12
|
+
|
|
13
|
+
| P(label) * P(features|label)
|
|
14
|
+
| P(label|features) = ------------------------------
|
|
15
|
+
| P(features)
|
|
16
|
+
|
|
17
|
+
The algorithm then makes the 'naive' assumption that all features are
|
|
18
|
+
independent, given the label:
|
|
19
|
+
|
|
20
|
+
| P(label) * P(f1|label) * ... * P(fn|label)
|
|
21
|
+
| P(label|features) = --------------------------------------------
|
|
22
|
+
| P(features)
|
|
23
|
+
|
|
24
|
+
Rather than computing P(features) explicitly, the algorithm just
|
|
25
|
+
calculates the numerator for each label, and normalizes them so they
|
|
26
|
+
sum to one:
|
|
27
|
+
|
|
28
|
+
| P(label) * P(f1|label) * ... * P(fn|label)
|
|
29
|
+
| P(label|features) = --------------------------------------------
|
|
30
|
+
| SUM[l]( P(l) * P(f1|l) * ... * P(fn|l) )
|
|
31
|
+
"""
|
|
32
|
+
from __future__ import print_function, unicode_literals
|
|
33
|
+
|
|
34
|
+
from collections import defaultdict
|
|
35
|
+
|
|
36
|
+
from nltk.probability import FreqDist, DictionaryProbDist, ELEProbDist, sum_logs
|
|
37
|
+
from nltk.classify.api import ClassifierI
|
|
38
|
+
|
|
39
|
+
##//////////////////////////////////////////////////////
|
|
40
|
+
## Naive Bayes Classifier
|
|
41
|
+
##//////////////////////////////////////////////////////
|
|
42
|
+
|
|
43
|
+
class NaiveBayesClassifier(ClassifierI):
|
|
44
|
+
"""
|
|
45
|
+
A Naive Bayes classifier. Naive Bayes classifiers are
|
|
46
|
+
paramaterized by two probability distributions:
|
|
47
|
+
|
|
48
|
+
- P(label) gives the probability that an input will receive each
|
|
49
|
+
label, given no information about the input's features.
|
|
50
|
+
|
|
51
|
+
- P(fname=fval|label) gives the probability that a given feature
|
|
52
|
+
(fname) will receive a given value (fval), given that the
|
|
53
|
+
label (label).
|
|
54
|
+
|
|
55
|
+
If the classifier encounters an input with a feature that has
|
|
56
|
+
never been seen with any label, then rather than assigning a
|
|
57
|
+
probability of 0 to all labels, it will ignore that feature.
|
|
58
|
+
|
|
59
|
+
The feature value 'None' is reserved for unseen feature values;
|
|
60
|
+
you generally should not use 'None' as a feature value for one of
|
|
61
|
+
your own features.
|
|
62
|
+
"""
|
|
63
|
+
def __init__(self, label_probdist, feature_probdist):
|
|
64
|
+
"""
|
|
65
|
+
:param label_probdist: P(label), the probability distribution
|
|
66
|
+
over labels. It is expressed as a ``ProbDistI`` whose
|
|
67
|
+
samples are labels. I.e., P(label) =
|
|
68
|
+
``label_probdist.prob(label)``.
|
|
69
|
+
|
|
70
|
+
:param feature_probdist: P(fname=fval|label), the probability
|
|
71
|
+
distribution for feature values, given labels. It is
|
|
72
|
+
expressed as a dictionary whose keys are ``(label, fname)``
|
|
73
|
+
pairs and whose values are ``ProbDistI`` objects over feature
|
|
74
|
+
values. I.e., P(fname=fval|label) =
|
|
75
|
+
``feature_probdist[label,fname].prob(fval)``. If a given
|
|
76
|
+
``(label,fname)`` is not a key in ``feature_probdist``, then
|
|
77
|
+
it is assumed that the corresponding P(fname=fval|label)
|
|
78
|
+
is 0 for all values of ``fval``.
|
|
79
|
+
"""
|
|
80
|
+
self._label_probdist = label_probdist
|
|
81
|
+
self._feature_probdist = feature_probdist
|
|
82
|
+
self._labels = list(label_probdist.samples())
|
|
83
|
+
|
|
84
|
+
def labels(self):
|
|
85
|
+
return self._labels
|
|
86
|
+
|
|
87
|
+
def classify(self, featureset):
|
|
88
|
+
return self.prob_classify(featureset).max()
|
|
89
|
+
|
|
90
|
+
def prob_classify(self, featureset):
|
|
91
|
+
# Discard any feature names that we've never seen before.
|
|
92
|
+
# Otherwise, we'll just assign a probability of 0 to
|
|
93
|
+
# everything.
|
|
94
|
+
featureset = featureset.copy()
|
|
95
|
+
for fname in list(featureset.keys()):
|
|
96
|
+
for label in self._labels:
|
|
97
|
+
if (label, fname) in self._feature_probdist:
|
|
98
|
+
break
|
|
99
|
+
else:
|
|
100
|
+
#print 'Ignoring unseen feature %s' % fname
|
|
101
|
+
del featureset[fname]
|
|
102
|
+
|
|
103
|
+
# Find the log probabilty of each label, given the features.
|
|
104
|
+
# Start with the log probability of the label itself.
|
|
105
|
+
logprob = {}
|
|
106
|
+
for label in self._labels:
|
|
107
|
+
logprob[label] = self._label_probdist.logprob(label)
|
|
108
|
+
|
|
109
|
+
# Then add in the log probability of features given labels.
|
|
110
|
+
for label in self._labels:
|
|
111
|
+
for (fname, fval) in featureset.items():
|
|
112
|
+
if (label, fname) in self._feature_probdist:
|
|
113
|
+
feature_probs = self._feature_probdist[label, fname]
|
|
114
|
+
logprob[label] += feature_probs.logprob(fval)
|
|
115
|
+
else:
|
|
116
|
+
# nb: This case will never come up if the
|
|
117
|
+
# classifier was created by
|
|
118
|
+
# NaiveBayesClassifier.train().
|
|
119
|
+
logprob[label] += sum_logs([]) # = -INF.
|
|
120
|
+
|
|
121
|
+
return DictionaryProbDist(logprob, normalize=True, log=True)
|
|
122
|
+
|
|
123
|
+
def show_most_informative_features(self, n=10):
|
|
124
|
+
# Determine the most relevant features, and display them.
|
|
125
|
+
cpdist = self._feature_probdist
|
|
126
|
+
print('Most Informative Features')
|
|
127
|
+
|
|
128
|
+
for (fname, fval) in self.most_informative_features(n):
|
|
129
|
+
def labelprob(l):
|
|
130
|
+
return cpdist[l, fname].prob(fval)
|
|
131
|
+
|
|
132
|
+
labels = sorted([l for l in self._labels
|
|
133
|
+
if fval in cpdist[l, fname].samples()],
|
|
134
|
+
key=labelprob)
|
|
135
|
+
if len(labels) == 1:
|
|
136
|
+
continue
|
|
137
|
+
l0 = labels[0]
|
|
138
|
+
l1 = labels[-1]
|
|
139
|
+
if cpdist[l0, fname].prob(fval) == 0:
|
|
140
|
+
ratio = 'INF'
|
|
141
|
+
else:
|
|
142
|
+
ratio = '%8.1f' % (cpdist[l1, fname].prob(fval) /
|
|
143
|
+
cpdist[l0, fname].prob(fval))
|
|
144
|
+
print(('%24s = %-14r %6s : %-6s = %s : 1.0' %
|
|
145
|
+
(fname, fval, ("%s" % l1)[:6], ("%s" % l0)[:6], ratio)))
|
|
146
|
+
|
|
147
|
+
def most_informative_features(self, n=100):
|
|
148
|
+
"""
|
|
149
|
+
Return a list of the 'most informative' features used by this
|
|
150
|
+
classifier. For the purpose of this function, the
|
|
151
|
+
informativeness of a feature ``(fname,fval)`` is equal to the
|
|
152
|
+
highest value of P(fname=fval|label), for any label, divided by
|
|
153
|
+
the lowest value of P(fname=fval|label), for any label:
|
|
154
|
+
|
|
155
|
+
| max[ P(fname=fval|label1) / P(fname=fval|label2) ]
|
|
156
|
+
"""
|
|
157
|
+
if hasattr(self, '_most_informative_features'):
|
|
158
|
+
return self._most_informative_features[:n]
|
|
159
|
+
else:
|
|
160
|
+
# The set of (fname, fval) pairs used by this classifier.
|
|
161
|
+
features = set()
|
|
162
|
+
# The max & min probability associated w/ each (fname, fval)
|
|
163
|
+
# pair. Maps (fname,fval) -> float.
|
|
164
|
+
maxprob = defaultdict(lambda: 0.0)
|
|
165
|
+
minprob = defaultdict(lambda: 1.0)
|
|
166
|
+
|
|
167
|
+
for (label, fname), probdist in self._feature_probdist.items():
|
|
168
|
+
for fval in probdist.samples():
|
|
169
|
+
feature = (fname, fval)
|
|
170
|
+
features.add(feature)
|
|
171
|
+
p = probdist.prob(fval)
|
|
172
|
+
maxprob[feature] = max(p, maxprob[feature])
|
|
173
|
+
minprob[feature] = min(p, minprob[feature])
|
|
174
|
+
if minprob[feature] == 0:
|
|
175
|
+
features.discard(feature)
|
|
176
|
+
|
|
177
|
+
# Convert features to a list, & sort it by how informative
|
|
178
|
+
# features are.
|
|
179
|
+
self._most_informative_features = sorted(features,
|
|
180
|
+
key=lambda feature_:
|
|
181
|
+
minprob[feature_]/maxprob[feature_])
|
|
182
|
+
return self._most_informative_features[:n]
|
|
183
|
+
|
|
184
|
+
@classmethod
|
|
185
|
+
def train(cls, labeled_featuresets, estimator=ELEProbDist):
|
|
186
|
+
"""
|
|
187
|
+
:param labeled_featuresets: A list of classified featuresets,
|
|
188
|
+
i.e., a list of tuples ``(featureset, label)``.
|
|
189
|
+
"""
|
|
190
|
+
label_freqdist = FreqDist()
|
|
191
|
+
feature_freqdist = defaultdict(FreqDist)
|
|
192
|
+
feature_values = defaultdict(set)
|
|
193
|
+
fnames = set()
|
|
194
|
+
|
|
195
|
+
# Count up how many times each feature value occurred, given
|
|
196
|
+
# the label and featurename.
|
|
197
|
+
for featureset, label in labeled_featuresets:
|
|
198
|
+
label_freqdist[label] += 1
|
|
199
|
+
for fname, fval in featureset.items():
|
|
200
|
+
# Increment freq(fval|label, fname)
|
|
201
|
+
feature_freqdist[label, fname][fval] += 1
|
|
202
|
+
# Record that fname can take the value fval.
|
|
203
|
+
feature_values[fname].add(fval)
|
|
204
|
+
# Keep a list of all feature names.
|
|
205
|
+
fnames.add(fname)
|
|
206
|
+
|
|
207
|
+
# If a feature didn't have a value given for an instance, then
|
|
208
|
+
# we assume that it gets the implicit value 'None.' This loop
|
|
209
|
+
# counts up the number of 'missing' feature values for each
|
|
210
|
+
# (label,fname) pair, and increments the count of the fval
|
|
211
|
+
# 'None' by that amount.
|
|
212
|
+
for label in label_freqdist:
|
|
213
|
+
num_samples = label_freqdist[label]
|
|
214
|
+
for fname in fnames:
|
|
215
|
+
count = feature_freqdist[label, fname].N()
|
|
216
|
+
# Only add a None key when necessary, i.e. if there are
|
|
217
|
+
# any samples with feature 'fname' missing.
|
|
218
|
+
if num_samples - count > 0:
|
|
219
|
+
feature_freqdist[label, fname][None] += num_samples - count
|
|
220
|
+
feature_values[fname].add(None)
|
|
221
|
+
|
|
222
|
+
# Create the P(label) distribution
|
|
223
|
+
label_probdist = estimator(label_freqdist)
|
|
224
|
+
|
|
225
|
+
# Create the P(fval|label, fname) distribution
|
|
226
|
+
feature_probdist = {}
|
|
227
|
+
for ((label, fname), freqdist) in feature_freqdist.items():
|
|
228
|
+
probdist = estimator(freqdist, bins=len(feature_values[fname]))
|
|
229
|
+
feature_probdist[label, fname] = probdist
|
|
230
|
+
|
|
231
|
+
return cls(label_probdist, feature_probdist)
|
|
232
|
+
|
|
233
|
+
##//////////////////////////////////////////////////////
|
|
234
|
+
## Demo
|
|
235
|
+
##//////////////////////////////////////////////////////
|
|
236
|
+
|
|
237
|
+
def demo():
|
|
238
|
+
from nltk.classify.util import names_demo
|
|
239
|
+
classifier = names_demo(NaiveBayesClassifier.train)
|
|
240
|
+
classifier.show_most_informative_features()
|
|
241
|
+
|
|
242
|
+
if __name__ == '__main__':
|
|
243
|
+
demo()
|
|
244
|
+
|
|
245
|
+
|