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,388 +1,388 @@
|
|
|
1
|
-
# Natural Language Toolkit: Collocations and Association Measures
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2001-
|
|
4
|
-
# Author: Joel Nothman <jnothman@student.usyd.edu.au>
|
|
5
|
-
# URL: <http://nltk.org>
|
|
6
|
-
# For license information, see LICENSE.TXT
|
|
7
|
-
#
|
|
8
|
-
"""
|
|
9
|
-
Tools to identify collocations --- words that often appear consecutively
|
|
10
|
-
--- within corpora. They may also be used to find other associations between
|
|
11
|
-
word occurrences.
|
|
12
|
-
See Manning and Schutze ch. 5 at http://nlp.stanford.edu/fsnlp/promo/colloc.pdf
|
|
13
|
-
and the Text::NSP Perl package at http://ngram.sourceforge.net
|
|
14
|
-
|
|
15
|
-
Finding collocations requires first calculating the frequencies of words and
|
|
16
|
-
their appearance in the context of other words. Often the collection of words
|
|
17
|
-
will then requiring filtering to only retain useful content terms. Each ngram
|
|
18
|
-
of words may then be scored according to some association measure, in order
|
|
19
|
-
to determine the relative likelihood of each ngram being a collocation.
|
|
20
|
-
|
|
21
|
-
The ``BigramCollocationFinder`` and ``TrigramCollocationFinder`` classes provide
|
|
22
|
-
these functionalities, dependent on being provided a function which scores a
|
|
23
|
-
ngram given appropriate frequency counts. A number of standard association
|
|
24
|
-
measures are provided in bigram_measures and trigram_measures.
|
|
25
|
-
"""
|
|
26
|
-
from __future__ import print_function
|
|
27
|
-
|
|
28
|
-
# Possible TODOs:
|
|
29
|
-
# - consider the distinction between f(x,_) and f(x) and whether our
|
|
30
|
-
# approximation is good enough for fragmented data, and mention it
|
|
31
|
-
# - add a n-gram collocation finder with measures which only utilise n-gram
|
|
32
|
-
# and unigram counts (raw_freq, pmi, student_t)
|
|
33
|
-
|
|
34
|
-
import itertools as _itertools
|
|
35
|
-
from
|
|
36
|
-
|
|
37
|
-
from nltk.probability import FreqDist
|
|
38
|
-
from nltk.util import ngrams
|
|
39
|
-
from nltk.metrics import ContingencyMeasures, BigramAssocMeasures, TrigramAssocMeasures
|
|
40
|
-
from nltk.metrics.spearman import ranks_from_scores, spearman_correlation
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class AbstractCollocationFinder(object):
|
|
44
|
-
"""
|
|
45
|
-
An abstract base class for collocation finders whose purpose is to
|
|
46
|
-
collect collocation candidate frequencies, filter and rank them.
|
|
47
|
-
|
|
48
|
-
As a minimum, collocation finders require the frequencies of each
|
|
49
|
-
word in a corpus, and the joint frequency of word tuples. This data
|
|
50
|
-
should be provided through nltk.probability.FreqDist objects or an
|
|
51
|
-
identical interface.
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
def __init__(self, word_fd, ngram_fd):
|
|
55
|
-
self.word_fd = word_fd
|
|
56
|
-
self.N = word_fd.N()
|
|
57
|
-
self.ngram_fd = ngram_fd
|
|
58
|
-
|
|
59
|
-
@classmethod
|
|
60
|
-
def _build_new_documents(cls, documents, window_size, pad_left=False, pad_right=False, pad_symbol=None):
|
|
61
|
-
'''
|
|
62
|
-
Pad the document with the place holder according to the window_size
|
|
63
|
-
'''
|
|
64
|
-
padding = (pad_symbol,) * (window_size - 1)
|
|
65
|
-
if pad_right:
|
|
66
|
-
return _itertools.chain.from_iterable(_itertools.chain(doc, padding) for doc in documents)
|
|
67
|
-
if pad_left:
|
|
68
|
-
return _itertools.chain.from_iterable(_itertools.chain(padding, doc) for doc in documents)
|
|
69
|
-
|
|
70
|
-
@classmethod
|
|
71
|
-
def from_documents(cls, documents):
|
|
72
|
-
"""Constructs a collocation finder given a collection of documents,
|
|
73
|
-
each of which is a list (or iterable) of tokens.
|
|
74
|
-
"""
|
|
75
|
-
#return cls.from_words(_itertools.chain(*documents))
|
|
76
|
-
return cls.from_words(cls._build_new_documents(documents, cls.default_ws, pad_right=True))
|
|
77
|
-
|
|
78
|
-
@staticmethod
|
|
79
|
-
def _ngram_freqdist(words, n):
|
|
80
|
-
return FreqDist(tuple(words[i:i + n]) for i in range(len(words) - 1))
|
|
81
|
-
|
|
82
|
-
def _apply_filter(self, fn=lambda ngram, freq: False):
|
|
83
|
-
"""Generic filter removes ngrams from the frequency distribution
|
|
84
|
-
if the function returns True when passed an ngram tuple.
|
|
85
|
-
"""
|
|
86
|
-
tmp_ngram = FreqDist()
|
|
87
|
-
for ngram, freq in iteritems(self.ngram_fd):
|
|
88
|
-
if not fn(ngram, freq):
|
|
89
|
-
tmp_ngram[ngram] = freq
|
|
90
|
-
self.ngram_fd = tmp_ngram
|
|
91
|
-
|
|
92
|
-
def apply_freq_filter(self, min_freq):
|
|
93
|
-
"""Removes candidate ngrams which have frequency less than min_freq."""
|
|
94
|
-
self._apply_filter(lambda ng, freq: freq < min_freq)
|
|
95
|
-
|
|
96
|
-
def apply_ngram_filter(self, fn):
|
|
97
|
-
"""Removes candidate ngrams (w1, w2, ...) where fn(w1, w2, ...)
|
|
98
|
-
evaluates to True.
|
|
99
|
-
"""
|
|
100
|
-
self._apply_filter(lambda ng, f: fn(*ng))
|
|
101
|
-
|
|
102
|
-
def apply_word_filter(self, fn):
|
|
103
|
-
"""Removes candidate ngrams (w1, w2, ...) where any of (fn(w1), fn(w2),
|
|
104
|
-
...) evaluates to True.
|
|
105
|
-
"""
|
|
106
|
-
self._apply_filter(lambda ng, f: any(fn(w) for w in ng))
|
|
107
|
-
|
|
108
|
-
def _score_ngrams(self, score_fn):
|
|
109
|
-
"""Generates of (ngram, score) pairs as determined by the scoring
|
|
110
|
-
function provided.
|
|
111
|
-
"""
|
|
112
|
-
for tup in self.ngram_fd:
|
|
113
|
-
score = self.score_ngram(score_fn, *tup)
|
|
114
|
-
if score is not None:
|
|
115
|
-
yield tup, score
|
|
116
|
-
|
|
117
|
-
def score_ngrams(self, score_fn):
|
|
118
|
-
"""Returns a sequence of (ngram, score) pairs ordered from highest to
|
|
119
|
-
lowest score, as determined by the scoring function provided.
|
|
120
|
-
"""
|
|
121
|
-
return sorted(self._score_ngrams(score_fn), key=lambda t: (-t[1], t[0]))
|
|
122
|
-
|
|
123
|
-
def nbest(self, score_fn, n):
|
|
124
|
-
"""Returns the top n ngrams when scored by the given function."""
|
|
125
|
-
return [p for p, s in self.score_ngrams(score_fn)[:n]]
|
|
126
|
-
|
|
127
|
-
def above_score(self, score_fn, min_score):
|
|
128
|
-
"""Returns a sequence of ngrams, ordered by decreasing score, whose
|
|
129
|
-
scores each exceed the given minimum score.
|
|
130
|
-
"""
|
|
131
|
-
for ngram, score in self.score_ngrams(score_fn):
|
|
132
|
-
if score > min_score:
|
|
133
|
-
yield ngram
|
|
134
|
-
else:
|
|
135
|
-
break
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
class BigramCollocationFinder(AbstractCollocationFinder):
|
|
139
|
-
"""A tool for the finding and ranking of bigram collocations or other
|
|
140
|
-
association measures. It is often useful to use from_words() rather than
|
|
141
|
-
constructing an instance directly.
|
|
142
|
-
"""
|
|
143
|
-
default_ws = 2
|
|
144
|
-
|
|
145
|
-
def __init__(self, word_fd, bigram_fd, window_size=2):
|
|
146
|
-
"""Construct a BigramCollocationFinder, given FreqDists for
|
|
147
|
-
appearances of words and (possibly non-contiguous) bigrams.
|
|
148
|
-
"""
|
|
149
|
-
AbstractCollocationFinder.__init__(self, word_fd, bigram_fd)
|
|
150
|
-
self.window_size = window_size
|
|
151
|
-
|
|
152
|
-
@classmethod
|
|
153
|
-
def from_words(cls, words, window_size=2):
|
|
154
|
-
"""Construct a BigramCollocationFinder for all bigrams in the given
|
|
155
|
-
sequence. When window_size > 2, count non-contiguous bigrams, in the
|
|
156
|
-
style of Church and Hanks's (1990) association ratio.
|
|
157
|
-
"""
|
|
158
|
-
wfd = FreqDist()
|
|
159
|
-
bfd = FreqDist()
|
|
160
|
-
|
|
161
|
-
if window_size < 2:
|
|
162
|
-
raise ValueError("Specify window_size at least 2")
|
|
163
|
-
|
|
164
|
-
for window in ngrams(words, window_size, pad_right=True):
|
|
165
|
-
w1 = window[0]
|
|
166
|
-
if w1 is None:
|
|
167
|
-
continue
|
|
168
|
-
wfd[w1] += 1
|
|
169
|
-
for w2 in window[1:]:
|
|
170
|
-
if w2 is not None:
|
|
171
|
-
bfd[(w1, w2)] += 1
|
|
172
|
-
return cls(wfd, bfd, window_size=window_size)
|
|
173
|
-
|
|
174
|
-
def score_ngram(self, score_fn, w1, w2):
|
|
175
|
-
"""Returns the score for a given bigram using the given scoring
|
|
176
|
-
function. Following Church and Hanks (1990), counts are scaled by
|
|
177
|
-
a factor of 1/(window_size - 1).
|
|
178
|
-
"""
|
|
179
|
-
n_all = self.N
|
|
180
|
-
n_ii = self.ngram_fd[(w1, w2)] / (self.window_size - 1.0)
|
|
181
|
-
if not n_ii:
|
|
182
|
-
return
|
|
183
|
-
n_ix = self.word_fd[w1]
|
|
184
|
-
n_xi = self.word_fd[w2]
|
|
185
|
-
return score_fn(n_ii, (n_ix, n_xi), n_all)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
class TrigramCollocationFinder(AbstractCollocationFinder):
|
|
189
|
-
"""A tool for the finding and ranking of trigram collocations or other
|
|
190
|
-
association measures. It is often useful to use from_words() rather than
|
|
191
|
-
constructing an instance directly.
|
|
192
|
-
"""
|
|
193
|
-
default_ws = 3
|
|
194
|
-
|
|
195
|
-
def __init__(self, word_fd, bigram_fd, wildcard_fd, trigram_fd):
|
|
196
|
-
"""Construct a TrigramCollocationFinder, given FreqDists for
|
|
197
|
-
appearances of words, bigrams, two words with any word between them,
|
|
198
|
-
and trigrams.
|
|
199
|
-
"""
|
|
200
|
-
AbstractCollocationFinder.__init__(self, word_fd, trigram_fd)
|
|
201
|
-
self.wildcard_fd = wildcard_fd
|
|
202
|
-
self.bigram_fd = bigram_fd
|
|
203
|
-
|
|
204
|
-
@classmethod
|
|
205
|
-
def from_words(cls, words, window_size=3):
|
|
206
|
-
"""Construct a TrigramCollocationFinder for all trigrams in the given
|
|
207
|
-
sequence.
|
|
208
|
-
"""
|
|
209
|
-
if window_size < 3:
|
|
210
|
-
raise ValueError("Specify window_size at least 3")
|
|
211
|
-
|
|
212
|
-
wfd = FreqDist()
|
|
213
|
-
wildfd = FreqDist()
|
|
214
|
-
bfd = FreqDist()
|
|
215
|
-
tfd = FreqDist()
|
|
216
|
-
for window in ngrams(words, window_size, pad_right=True):
|
|
217
|
-
w1 = window[0]
|
|
218
|
-
if w1 is None:
|
|
219
|
-
continue
|
|
220
|
-
for w2, w3 in _itertools.combinations(window[1:], 2):
|
|
221
|
-
wfd[w1] += 1
|
|
222
|
-
if w2 is None:
|
|
223
|
-
continue
|
|
224
|
-
bfd[(w1, w2)] += 1
|
|
225
|
-
if w3 is None:
|
|
226
|
-
continue
|
|
227
|
-
wildfd[(w1, w3)] += 1
|
|
228
|
-
tfd[(w1, w2, w3)] += 1
|
|
229
|
-
return cls(wfd, bfd, wildfd, tfd)
|
|
230
|
-
|
|
231
|
-
def bigram_finder(self):
|
|
232
|
-
"""Constructs a bigram collocation finder with the bigram and unigram
|
|
233
|
-
data from this finder. Note that this does not include any filtering
|
|
234
|
-
applied to this finder.
|
|
235
|
-
"""
|
|
236
|
-
return BigramCollocationFinder(self.word_fd, self.bigram_fd)
|
|
237
|
-
|
|
238
|
-
def score_ngram(self, score_fn, w1, w2, w3):
|
|
239
|
-
"""Returns the score for a given trigram using the given scoring
|
|
240
|
-
function.
|
|
241
|
-
"""
|
|
242
|
-
n_all = self.N
|
|
243
|
-
n_iii = self.ngram_fd[(w1, w2, w3)]
|
|
244
|
-
if not n_iii:
|
|
245
|
-
return
|
|
246
|
-
n_iix = self.bigram_fd[(w1, w2)]
|
|
247
|
-
n_ixi = self.wildcard_fd[(w1, w3)]
|
|
248
|
-
n_xii = self.bigram_fd[(w2, w3)]
|
|
249
|
-
n_ixx = self.word_fd[w1]
|
|
250
|
-
n_xix = self.word_fd[w2]
|
|
251
|
-
n_xxi = self.word_fd[w3]
|
|
252
|
-
return score_fn(n_iii,
|
|
253
|
-
(n_iix, n_ixi, n_xii),
|
|
254
|
-
(n_ixx, n_xix, n_xxi),
|
|
255
|
-
n_all)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
class QuadgramCollocationFinder(AbstractCollocationFinder):
|
|
259
|
-
"""A tool for the finding and ranking of quadgram collocations or other association measures.
|
|
260
|
-
It is often useful to use from_words() rather than constructing an instance directly.
|
|
261
|
-
"""
|
|
262
|
-
default_ws = 4
|
|
263
|
-
|
|
264
|
-
def __init__(self, word_fd, quadgram_fd, ii, iii, ixi, ixxi, iixi, ixii):
|
|
265
|
-
"""Construct a QuadgramCollocationFinder, given FreqDists for appearances of words,
|
|
266
|
-
bigrams, trigrams, two words with one word and two words between them, three words
|
|
267
|
-
with a word between them in both variations.
|
|
268
|
-
"""
|
|
269
|
-
AbstractCollocationFinder.__init__(self, word_fd, quadgram_fd)
|
|
270
|
-
self.iii = iii
|
|
271
|
-
self.ii = ii
|
|
272
|
-
self.ixi = ixi
|
|
273
|
-
self.ixxi = ixxi
|
|
274
|
-
self.iixi = iixi
|
|
275
|
-
self.ixii = ixii
|
|
276
|
-
|
|
277
|
-
@classmethod
|
|
278
|
-
def from_words(cls, words, window_size=4):
|
|
279
|
-
if window_size < 4:
|
|
280
|
-
raise ValueError("Specify window_size at least 4")
|
|
281
|
-
ixxx = FreqDist()
|
|
282
|
-
iiii = FreqDist()
|
|
283
|
-
ii = FreqDist()
|
|
284
|
-
iii = FreqDist()
|
|
285
|
-
ixi = FreqDist()
|
|
286
|
-
ixxi = FreqDist()
|
|
287
|
-
iixi = FreqDist()
|
|
288
|
-
ixii = FreqDist()
|
|
289
|
-
|
|
290
|
-
for window in ngrams(words, window_size, pad_right=True):
|
|
291
|
-
w1 = window[0]
|
|
292
|
-
if w1 is None:
|
|
293
|
-
continue
|
|
294
|
-
for w2, w3, w4 in _itertools.combinations(window[1:], 3):
|
|
295
|
-
ixxx[w1] += 1
|
|
296
|
-
if w2 is None:
|
|
297
|
-
continue
|
|
298
|
-
ii[(w1, w2)] += 1
|
|
299
|
-
if w3 is None:
|
|
300
|
-
continue
|
|
301
|
-
iii[(w1, w2, w3)] += 1
|
|
302
|
-
ixi[(w1, w3)] += 1
|
|
303
|
-
if w4 is None:
|
|
304
|
-
continue
|
|
305
|
-
iiii[(w1, w2, w3, w4)] += 1
|
|
306
|
-
ixxi[(w1, w4)] += 1
|
|
307
|
-
ixii[(w1, w3, w4)] += 1
|
|
308
|
-
iixi[(w1, w2, w4)] += 1
|
|
309
|
-
|
|
310
|
-
return cls(ixxx, iiii, ii, iii, ixi, ixxi, iixi, ixii)
|
|
311
|
-
|
|
312
|
-
def score_ngram(self, score_fn, w1, w2, w3, w4):
|
|
313
|
-
n_all = self.N
|
|
314
|
-
n_iiii = self.ngram_fd[(w1, w2, w3, w4)]
|
|
315
|
-
if not n_iiii:
|
|
316
|
-
return
|
|
317
|
-
n_iiix = self.iii[(w1, w2, w3)]
|
|
318
|
-
n_xiii = self.iii[(w2, w3, w4)]
|
|
319
|
-
n_iixi = self.iixi[(w1, w2, w4)]
|
|
320
|
-
n_ixii = self.ixii[(w1, w3, w4)]
|
|
321
|
-
|
|
322
|
-
n_iixx = self.ii[(w1, w2)]
|
|
323
|
-
n_xxii = self.ii[(w3, w4)]
|
|
324
|
-
n_xiix = self.ii[(w2, w3)]
|
|
325
|
-
n_ixix = self.ixi[(w1, w3)]
|
|
326
|
-
n_ixxi = self.ixxi[(w1, w4)]
|
|
327
|
-
n_xixi = self.ixi[(w2, w4)]
|
|
328
|
-
|
|
329
|
-
n_ixxx = self.word_fd[w1]
|
|
330
|
-
n_xixx = self.word_fd[w2]
|
|
331
|
-
n_xxix = self.word_fd[w3]
|
|
332
|
-
n_xxxi = self.word_fd[w4]
|
|
333
|
-
return score_fn(n_iiii,
|
|
334
|
-
(n_iiix, n_iixi, n_ixii, n_xiii),
|
|
335
|
-
(n_iixx, n_ixix, n_ixxi, n_xixi, n_xxii, n_xiix),
|
|
336
|
-
(n_ixxx, n_xixx, n_xxix, n_xxxi),
|
|
337
|
-
n_all)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
def demo(scorer=None, compare_scorer=None):
|
|
341
|
-
"""Finds bigram collocations in the files of the WebText corpus."""
|
|
342
|
-
from nltk.metrics import BigramAssocMeasures, spearman_correlation, ranks_from_scores
|
|
343
|
-
|
|
344
|
-
if scorer is None:
|
|
345
|
-
scorer = BigramAssocMeasures.likelihood_ratio
|
|
346
|
-
if compare_scorer is None:
|
|
347
|
-
compare_scorer = BigramAssocMeasures.raw_freq
|
|
348
|
-
|
|
349
|
-
from nltk.corpus import stopwords, webtext
|
|
350
|
-
|
|
351
|
-
ignored_words = stopwords.words('english')
|
|
352
|
-
word_filter = lambda w: len(w) < 3 or w.lower() in ignored_words
|
|
353
|
-
|
|
354
|
-
for file in webtext.fileids():
|
|
355
|
-
words = [word.lower()
|
|
356
|
-
for word in webtext.words(file)]
|
|
357
|
-
|
|
358
|
-
cf = BigramCollocationFinder.from_words(words)
|
|
359
|
-
cf.apply_freq_filter(3)
|
|
360
|
-
cf.apply_word_filter(word_filter)
|
|
361
|
-
|
|
362
|
-
corr = spearman_correlation(ranks_from_scores(cf.score_ngrams(scorer)),
|
|
363
|
-
ranks_from_scores(cf.score_ngrams(compare_scorer)))
|
|
364
|
-
print(file)
|
|
365
|
-
print('\t', [' '.join(tup) for tup in cf.nbest(scorer, 15)])
|
|
366
|
-
print('\t Correlation to %s: %0.4f' % (compare_scorer.__name__, corr))
|
|
367
|
-
|
|
368
|
-
# Slows down loading too much
|
|
369
|
-
# bigram_measures = BigramAssocMeasures()
|
|
370
|
-
# trigram_measures = TrigramAssocMeasures()
|
|
371
|
-
|
|
372
|
-
if __name__ == '__main__':
|
|
373
|
-
import sys
|
|
374
|
-
from nltk.metrics import BigramAssocMeasures
|
|
375
|
-
|
|
376
|
-
try:
|
|
377
|
-
scorer = eval('BigramAssocMeasures.' + sys.argv[1])
|
|
378
|
-
except IndexError:
|
|
379
|
-
scorer = None
|
|
380
|
-
try:
|
|
381
|
-
compare_scorer = eval('BigramAssocMeasures.' + sys.argv[2])
|
|
382
|
-
except IndexError:
|
|
383
|
-
compare_scorer = None
|
|
384
|
-
|
|
385
|
-
demo(scorer, compare_scorer)
|
|
386
|
-
|
|
387
|
-
__all__ = ['BigramCollocationFinder',
|
|
388
|
-
'TrigramCollocationFinder', 'QuadgramCollocationFinder']
|
|
1
|
+
# Natural Language Toolkit: Collocations and Association Measures
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2001-2018 NLTK Project
|
|
4
|
+
# Author: Joel Nothman <jnothman@student.usyd.edu.au>
|
|
5
|
+
# URL: <http://nltk.org>
|
|
6
|
+
# For license information, see LICENSE.TXT
|
|
7
|
+
#
|
|
8
|
+
"""
|
|
9
|
+
Tools to identify collocations --- words that often appear consecutively
|
|
10
|
+
--- within corpora. They may also be used to find other associations between
|
|
11
|
+
word occurrences.
|
|
12
|
+
See Manning and Schutze ch. 5 at http://nlp.stanford.edu/fsnlp/promo/colloc.pdf
|
|
13
|
+
and the Text::NSP Perl package at http://ngram.sourceforge.net
|
|
14
|
+
|
|
15
|
+
Finding collocations requires first calculating the frequencies of words and
|
|
16
|
+
their appearance in the context of other words. Often the collection of words
|
|
17
|
+
will then requiring filtering to only retain useful content terms. Each ngram
|
|
18
|
+
of words may then be scored according to some association measure, in order
|
|
19
|
+
to determine the relative likelihood of each ngram being a collocation.
|
|
20
|
+
|
|
21
|
+
The ``BigramCollocationFinder`` and ``TrigramCollocationFinder`` classes provide
|
|
22
|
+
these functionalities, dependent on being provided a function which scores a
|
|
23
|
+
ngram given appropriate frequency counts. A number of standard association
|
|
24
|
+
measures are provided in bigram_measures and trigram_measures.
|
|
25
|
+
"""
|
|
26
|
+
from __future__ import print_function
|
|
27
|
+
|
|
28
|
+
# Possible TODOs:
|
|
29
|
+
# - consider the distinction between f(x,_) and f(x) and whether our
|
|
30
|
+
# approximation is good enough for fragmented data, and mention it
|
|
31
|
+
# - add a n-gram collocation finder with measures which only utilise n-gram
|
|
32
|
+
# and unigram counts (raw_freq, pmi, student_t)
|
|
33
|
+
|
|
34
|
+
import itertools as _itertools
|
|
35
|
+
from six import iteritems
|
|
36
|
+
|
|
37
|
+
from nltk.probability import FreqDist
|
|
38
|
+
from nltk.util import ngrams
|
|
39
|
+
from nltk.metrics import ContingencyMeasures, BigramAssocMeasures, TrigramAssocMeasures
|
|
40
|
+
from nltk.metrics.spearman import ranks_from_scores, spearman_correlation
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AbstractCollocationFinder(object):
|
|
44
|
+
"""
|
|
45
|
+
An abstract base class for collocation finders whose purpose is to
|
|
46
|
+
collect collocation candidate frequencies, filter and rank them.
|
|
47
|
+
|
|
48
|
+
As a minimum, collocation finders require the frequencies of each
|
|
49
|
+
word in a corpus, and the joint frequency of word tuples. This data
|
|
50
|
+
should be provided through nltk.probability.FreqDist objects or an
|
|
51
|
+
identical interface.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, word_fd, ngram_fd):
|
|
55
|
+
self.word_fd = word_fd
|
|
56
|
+
self.N = word_fd.N()
|
|
57
|
+
self.ngram_fd = ngram_fd
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def _build_new_documents(cls, documents, window_size, pad_left=False, pad_right=False, pad_symbol=None):
|
|
61
|
+
'''
|
|
62
|
+
Pad the document with the place holder according to the window_size
|
|
63
|
+
'''
|
|
64
|
+
padding = (pad_symbol,) * (window_size - 1)
|
|
65
|
+
if pad_right:
|
|
66
|
+
return _itertools.chain.from_iterable(_itertools.chain(doc, padding) for doc in documents)
|
|
67
|
+
if pad_left:
|
|
68
|
+
return _itertools.chain.from_iterable(_itertools.chain(padding, doc) for doc in documents)
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def from_documents(cls, documents):
|
|
72
|
+
"""Constructs a collocation finder given a collection of documents,
|
|
73
|
+
each of which is a list (or iterable) of tokens.
|
|
74
|
+
"""
|
|
75
|
+
#return cls.from_words(_itertools.chain(*documents))
|
|
76
|
+
return cls.from_words(cls._build_new_documents(documents, cls.default_ws, pad_right=True))
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def _ngram_freqdist(words, n):
|
|
80
|
+
return FreqDist(tuple(words[i:i + n]) for i in range(len(words) - 1))
|
|
81
|
+
|
|
82
|
+
def _apply_filter(self, fn=lambda ngram, freq: False):
|
|
83
|
+
"""Generic filter removes ngrams from the frequency distribution
|
|
84
|
+
if the function returns True when passed an ngram tuple.
|
|
85
|
+
"""
|
|
86
|
+
tmp_ngram = FreqDist()
|
|
87
|
+
for ngram, freq in iteritems(self.ngram_fd):
|
|
88
|
+
if not fn(ngram, freq):
|
|
89
|
+
tmp_ngram[ngram] = freq
|
|
90
|
+
self.ngram_fd = tmp_ngram
|
|
91
|
+
|
|
92
|
+
def apply_freq_filter(self, min_freq):
|
|
93
|
+
"""Removes candidate ngrams which have frequency less than min_freq."""
|
|
94
|
+
self._apply_filter(lambda ng, freq: freq < min_freq)
|
|
95
|
+
|
|
96
|
+
def apply_ngram_filter(self, fn):
|
|
97
|
+
"""Removes candidate ngrams (w1, w2, ...) where fn(w1, w2, ...)
|
|
98
|
+
evaluates to True.
|
|
99
|
+
"""
|
|
100
|
+
self._apply_filter(lambda ng, f: fn(*ng))
|
|
101
|
+
|
|
102
|
+
def apply_word_filter(self, fn):
|
|
103
|
+
"""Removes candidate ngrams (w1, w2, ...) where any of (fn(w1), fn(w2),
|
|
104
|
+
...) evaluates to True.
|
|
105
|
+
"""
|
|
106
|
+
self._apply_filter(lambda ng, f: any(fn(w) for w in ng))
|
|
107
|
+
|
|
108
|
+
def _score_ngrams(self, score_fn):
|
|
109
|
+
"""Generates of (ngram, score) pairs as determined by the scoring
|
|
110
|
+
function provided.
|
|
111
|
+
"""
|
|
112
|
+
for tup in self.ngram_fd:
|
|
113
|
+
score = self.score_ngram(score_fn, *tup)
|
|
114
|
+
if score is not None:
|
|
115
|
+
yield tup, score
|
|
116
|
+
|
|
117
|
+
def score_ngrams(self, score_fn):
|
|
118
|
+
"""Returns a sequence of (ngram, score) pairs ordered from highest to
|
|
119
|
+
lowest score, as determined by the scoring function provided.
|
|
120
|
+
"""
|
|
121
|
+
return sorted(self._score_ngrams(score_fn), key=lambda t: (-t[1], t[0]))
|
|
122
|
+
|
|
123
|
+
def nbest(self, score_fn, n):
|
|
124
|
+
"""Returns the top n ngrams when scored by the given function."""
|
|
125
|
+
return [p for p, s in self.score_ngrams(score_fn)[:n]]
|
|
126
|
+
|
|
127
|
+
def above_score(self, score_fn, min_score):
|
|
128
|
+
"""Returns a sequence of ngrams, ordered by decreasing score, whose
|
|
129
|
+
scores each exceed the given minimum score.
|
|
130
|
+
"""
|
|
131
|
+
for ngram, score in self.score_ngrams(score_fn):
|
|
132
|
+
if score > min_score:
|
|
133
|
+
yield ngram
|
|
134
|
+
else:
|
|
135
|
+
break
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class BigramCollocationFinder(AbstractCollocationFinder):
|
|
139
|
+
"""A tool for the finding and ranking of bigram collocations or other
|
|
140
|
+
association measures. It is often useful to use from_words() rather than
|
|
141
|
+
constructing an instance directly.
|
|
142
|
+
"""
|
|
143
|
+
default_ws = 2
|
|
144
|
+
|
|
145
|
+
def __init__(self, word_fd, bigram_fd, window_size=2):
|
|
146
|
+
"""Construct a BigramCollocationFinder, given FreqDists for
|
|
147
|
+
appearances of words and (possibly non-contiguous) bigrams.
|
|
148
|
+
"""
|
|
149
|
+
AbstractCollocationFinder.__init__(self, word_fd, bigram_fd)
|
|
150
|
+
self.window_size = window_size
|
|
151
|
+
|
|
152
|
+
@classmethod
|
|
153
|
+
def from_words(cls, words, window_size=2):
|
|
154
|
+
"""Construct a BigramCollocationFinder for all bigrams in the given
|
|
155
|
+
sequence. When window_size > 2, count non-contiguous bigrams, in the
|
|
156
|
+
style of Church and Hanks's (1990) association ratio.
|
|
157
|
+
"""
|
|
158
|
+
wfd = FreqDist()
|
|
159
|
+
bfd = FreqDist()
|
|
160
|
+
|
|
161
|
+
if window_size < 2:
|
|
162
|
+
raise ValueError("Specify window_size at least 2")
|
|
163
|
+
|
|
164
|
+
for window in ngrams(words, window_size, pad_right=True):
|
|
165
|
+
w1 = window[0]
|
|
166
|
+
if w1 is None:
|
|
167
|
+
continue
|
|
168
|
+
wfd[w1] += 1
|
|
169
|
+
for w2 in window[1:]:
|
|
170
|
+
if w2 is not None:
|
|
171
|
+
bfd[(w1, w2)] += 1
|
|
172
|
+
return cls(wfd, bfd, window_size=window_size)
|
|
173
|
+
|
|
174
|
+
def score_ngram(self, score_fn, w1, w2):
|
|
175
|
+
"""Returns the score for a given bigram using the given scoring
|
|
176
|
+
function. Following Church and Hanks (1990), counts are scaled by
|
|
177
|
+
a factor of 1/(window_size - 1).
|
|
178
|
+
"""
|
|
179
|
+
n_all = self.N
|
|
180
|
+
n_ii = self.ngram_fd[(w1, w2)] / (self.window_size - 1.0)
|
|
181
|
+
if not n_ii:
|
|
182
|
+
return
|
|
183
|
+
n_ix = self.word_fd[w1]
|
|
184
|
+
n_xi = self.word_fd[w2]
|
|
185
|
+
return score_fn(n_ii, (n_ix, n_xi), n_all)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class TrigramCollocationFinder(AbstractCollocationFinder):
|
|
189
|
+
"""A tool for the finding and ranking of trigram collocations or other
|
|
190
|
+
association measures. It is often useful to use from_words() rather than
|
|
191
|
+
constructing an instance directly.
|
|
192
|
+
"""
|
|
193
|
+
default_ws = 3
|
|
194
|
+
|
|
195
|
+
def __init__(self, word_fd, bigram_fd, wildcard_fd, trigram_fd):
|
|
196
|
+
"""Construct a TrigramCollocationFinder, given FreqDists for
|
|
197
|
+
appearances of words, bigrams, two words with any word between them,
|
|
198
|
+
and trigrams.
|
|
199
|
+
"""
|
|
200
|
+
AbstractCollocationFinder.__init__(self, word_fd, trigram_fd)
|
|
201
|
+
self.wildcard_fd = wildcard_fd
|
|
202
|
+
self.bigram_fd = bigram_fd
|
|
203
|
+
|
|
204
|
+
@classmethod
|
|
205
|
+
def from_words(cls, words, window_size=3):
|
|
206
|
+
"""Construct a TrigramCollocationFinder for all trigrams in the given
|
|
207
|
+
sequence.
|
|
208
|
+
"""
|
|
209
|
+
if window_size < 3:
|
|
210
|
+
raise ValueError("Specify window_size at least 3")
|
|
211
|
+
|
|
212
|
+
wfd = FreqDist()
|
|
213
|
+
wildfd = FreqDist()
|
|
214
|
+
bfd = FreqDist()
|
|
215
|
+
tfd = FreqDist()
|
|
216
|
+
for window in ngrams(words, window_size, pad_right=True):
|
|
217
|
+
w1 = window[0]
|
|
218
|
+
if w1 is None:
|
|
219
|
+
continue
|
|
220
|
+
for w2, w3 in _itertools.combinations(window[1:], 2):
|
|
221
|
+
wfd[w1] += 1
|
|
222
|
+
if w2 is None:
|
|
223
|
+
continue
|
|
224
|
+
bfd[(w1, w2)] += 1
|
|
225
|
+
if w3 is None:
|
|
226
|
+
continue
|
|
227
|
+
wildfd[(w1, w3)] += 1
|
|
228
|
+
tfd[(w1, w2, w3)] += 1
|
|
229
|
+
return cls(wfd, bfd, wildfd, tfd)
|
|
230
|
+
|
|
231
|
+
def bigram_finder(self):
|
|
232
|
+
"""Constructs a bigram collocation finder with the bigram and unigram
|
|
233
|
+
data from this finder. Note that this does not include any filtering
|
|
234
|
+
applied to this finder.
|
|
235
|
+
"""
|
|
236
|
+
return BigramCollocationFinder(self.word_fd, self.bigram_fd)
|
|
237
|
+
|
|
238
|
+
def score_ngram(self, score_fn, w1, w2, w3):
|
|
239
|
+
"""Returns the score for a given trigram using the given scoring
|
|
240
|
+
function.
|
|
241
|
+
"""
|
|
242
|
+
n_all = self.N
|
|
243
|
+
n_iii = self.ngram_fd[(w1, w2, w3)]
|
|
244
|
+
if not n_iii:
|
|
245
|
+
return
|
|
246
|
+
n_iix = self.bigram_fd[(w1, w2)]
|
|
247
|
+
n_ixi = self.wildcard_fd[(w1, w3)]
|
|
248
|
+
n_xii = self.bigram_fd[(w2, w3)]
|
|
249
|
+
n_ixx = self.word_fd[w1]
|
|
250
|
+
n_xix = self.word_fd[w2]
|
|
251
|
+
n_xxi = self.word_fd[w3]
|
|
252
|
+
return score_fn(n_iii,
|
|
253
|
+
(n_iix, n_ixi, n_xii),
|
|
254
|
+
(n_ixx, n_xix, n_xxi),
|
|
255
|
+
n_all)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class QuadgramCollocationFinder(AbstractCollocationFinder):
|
|
259
|
+
"""A tool for the finding and ranking of quadgram collocations or other association measures.
|
|
260
|
+
It is often useful to use from_words() rather than constructing an instance directly.
|
|
261
|
+
"""
|
|
262
|
+
default_ws = 4
|
|
263
|
+
|
|
264
|
+
def __init__(self, word_fd, quadgram_fd, ii, iii, ixi, ixxi, iixi, ixii):
|
|
265
|
+
"""Construct a QuadgramCollocationFinder, given FreqDists for appearances of words,
|
|
266
|
+
bigrams, trigrams, two words with one word and two words between them, three words
|
|
267
|
+
with a word between them in both variations.
|
|
268
|
+
"""
|
|
269
|
+
AbstractCollocationFinder.__init__(self, word_fd, quadgram_fd)
|
|
270
|
+
self.iii = iii
|
|
271
|
+
self.ii = ii
|
|
272
|
+
self.ixi = ixi
|
|
273
|
+
self.ixxi = ixxi
|
|
274
|
+
self.iixi = iixi
|
|
275
|
+
self.ixii = ixii
|
|
276
|
+
|
|
277
|
+
@classmethod
|
|
278
|
+
def from_words(cls, words, window_size=4):
|
|
279
|
+
if window_size < 4:
|
|
280
|
+
raise ValueError("Specify window_size at least 4")
|
|
281
|
+
ixxx = FreqDist()
|
|
282
|
+
iiii = FreqDist()
|
|
283
|
+
ii = FreqDist()
|
|
284
|
+
iii = FreqDist()
|
|
285
|
+
ixi = FreqDist()
|
|
286
|
+
ixxi = FreqDist()
|
|
287
|
+
iixi = FreqDist()
|
|
288
|
+
ixii = FreqDist()
|
|
289
|
+
|
|
290
|
+
for window in ngrams(words, window_size, pad_right=True):
|
|
291
|
+
w1 = window[0]
|
|
292
|
+
if w1 is None:
|
|
293
|
+
continue
|
|
294
|
+
for w2, w3, w4 in _itertools.combinations(window[1:], 3):
|
|
295
|
+
ixxx[w1] += 1
|
|
296
|
+
if w2 is None:
|
|
297
|
+
continue
|
|
298
|
+
ii[(w1, w2)] += 1
|
|
299
|
+
if w3 is None:
|
|
300
|
+
continue
|
|
301
|
+
iii[(w1, w2, w3)] += 1
|
|
302
|
+
ixi[(w1, w3)] += 1
|
|
303
|
+
if w4 is None:
|
|
304
|
+
continue
|
|
305
|
+
iiii[(w1, w2, w3, w4)] += 1
|
|
306
|
+
ixxi[(w1, w4)] += 1
|
|
307
|
+
ixii[(w1, w3, w4)] += 1
|
|
308
|
+
iixi[(w1, w2, w4)] += 1
|
|
309
|
+
|
|
310
|
+
return cls(ixxx, iiii, ii, iii, ixi, ixxi, iixi, ixii)
|
|
311
|
+
|
|
312
|
+
def score_ngram(self, score_fn, w1, w2, w3, w4):
|
|
313
|
+
n_all = self.N
|
|
314
|
+
n_iiii = self.ngram_fd[(w1, w2, w3, w4)]
|
|
315
|
+
if not n_iiii:
|
|
316
|
+
return
|
|
317
|
+
n_iiix = self.iii[(w1, w2, w3)]
|
|
318
|
+
n_xiii = self.iii[(w2, w3, w4)]
|
|
319
|
+
n_iixi = self.iixi[(w1, w2, w4)]
|
|
320
|
+
n_ixii = self.ixii[(w1, w3, w4)]
|
|
321
|
+
|
|
322
|
+
n_iixx = self.ii[(w1, w2)]
|
|
323
|
+
n_xxii = self.ii[(w3, w4)]
|
|
324
|
+
n_xiix = self.ii[(w2, w3)]
|
|
325
|
+
n_ixix = self.ixi[(w1, w3)]
|
|
326
|
+
n_ixxi = self.ixxi[(w1, w4)]
|
|
327
|
+
n_xixi = self.ixi[(w2, w4)]
|
|
328
|
+
|
|
329
|
+
n_ixxx = self.word_fd[w1]
|
|
330
|
+
n_xixx = self.word_fd[w2]
|
|
331
|
+
n_xxix = self.word_fd[w3]
|
|
332
|
+
n_xxxi = self.word_fd[w4]
|
|
333
|
+
return score_fn(n_iiii,
|
|
334
|
+
(n_iiix, n_iixi, n_ixii, n_xiii),
|
|
335
|
+
(n_iixx, n_ixix, n_ixxi, n_xixi, n_xxii, n_xiix),
|
|
336
|
+
(n_ixxx, n_xixx, n_xxix, n_xxxi),
|
|
337
|
+
n_all)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def demo(scorer=None, compare_scorer=None):
|
|
341
|
+
"""Finds bigram collocations in the files of the WebText corpus."""
|
|
342
|
+
from nltk.metrics import BigramAssocMeasures, spearman_correlation, ranks_from_scores
|
|
343
|
+
|
|
344
|
+
if scorer is None:
|
|
345
|
+
scorer = BigramAssocMeasures.likelihood_ratio
|
|
346
|
+
if compare_scorer is None:
|
|
347
|
+
compare_scorer = BigramAssocMeasures.raw_freq
|
|
348
|
+
|
|
349
|
+
from nltk.corpus import stopwords, webtext
|
|
350
|
+
|
|
351
|
+
ignored_words = stopwords.words('english')
|
|
352
|
+
word_filter = lambda w: len(w) < 3 or w.lower() in ignored_words
|
|
353
|
+
|
|
354
|
+
for file in webtext.fileids():
|
|
355
|
+
words = [word.lower()
|
|
356
|
+
for word in webtext.words(file)]
|
|
357
|
+
|
|
358
|
+
cf = BigramCollocationFinder.from_words(words)
|
|
359
|
+
cf.apply_freq_filter(3)
|
|
360
|
+
cf.apply_word_filter(word_filter)
|
|
361
|
+
|
|
362
|
+
corr = spearman_correlation(ranks_from_scores(cf.score_ngrams(scorer)),
|
|
363
|
+
ranks_from_scores(cf.score_ngrams(compare_scorer)))
|
|
364
|
+
print(file)
|
|
365
|
+
print('\t', [' '.join(tup) for tup in cf.nbest(scorer, 15)])
|
|
366
|
+
print('\t Correlation to %s: %0.4f' % (compare_scorer.__name__, corr))
|
|
367
|
+
|
|
368
|
+
# Slows down loading too much
|
|
369
|
+
# bigram_measures = BigramAssocMeasures()
|
|
370
|
+
# trigram_measures = TrigramAssocMeasures()
|
|
371
|
+
|
|
372
|
+
if __name__ == '__main__':
|
|
373
|
+
import sys
|
|
374
|
+
from nltk.metrics import BigramAssocMeasures
|
|
375
|
+
|
|
376
|
+
try:
|
|
377
|
+
scorer = eval('BigramAssocMeasures.' + sys.argv[1])
|
|
378
|
+
except IndexError:
|
|
379
|
+
scorer = None
|
|
380
|
+
try:
|
|
381
|
+
compare_scorer = eval('BigramAssocMeasures.' + sys.argv[2])
|
|
382
|
+
except IndexError:
|
|
383
|
+
compare_scorer = None
|
|
384
|
+
|
|
385
|
+
demo(scorer, compare_scorer)
|
|
386
|
+
|
|
387
|
+
__all__ = ['BigramCollocationFinder',
|
|
388
|
+
'TrigramCollocationFinder', 'QuadgramCollocationFinder']
|