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,309 +1,309 @@
|
|
|
1
|
-
# Natural Language Toolkit: Tree Transformations
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2005-2007 Oregon Graduate Institute
|
|
4
|
-
# Author: Nathan Bodenstab <bodenstab@cslu.ogi.edu>
|
|
5
|
-
# URL: <http://nltk.org/>
|
|
6
|
-
# For license information, see LICENSE.TXT
|
|
7
|
-
|
|
8
|
-
"""
|
|
9
|
-
A collection of methods for tree (grammar) transformations used
|
|
10
|
-
in parsing natural language.
|
|
11
|
-
|
|
12
|
-
Although many of these methods are technically grammar transformations
|
|
13
|
-
(ie. Chomsky Norm Form), when working with treebanks it is much more
|
|
14
|
-
natural to visualize these modifications in a tree structure. Hence,
|
|
15
|
-
we will do all transformation directly to the tree itself.
|
|
16
|
-
Transforming the tree directly also allows us to do parent annotation.
|
|
17
|
-
A grammar can then be simply induced from the modified tree.
|
|
18
|
-
|
|
19
|
-
The following is a short tutorial on the available transformations.
|
|
20
|
-
|
|
21
|
-
1. Chomsky Normal Form (binarization)
|
|
22
|
-
|
|
23
|
-
It is well known that any grammar has a Chomsky Normal Form (CNF)
|
|
24
|
-
equivalent grammar where CNF is defined by every production having
|
|
25
|
-
either two non-terminals or one terminal on its right hand side.
|
|
26
|
-
When we have hierarchically structured data (ie. a treebank), it is
|
|
27
|
-
natural to view this in terms of productions where the root of every
|
|
28
|
-
subtree is the head (left hand side) of the production and all of
|
|
29
|
-
its children are the right hand side constituents. In order to
|
|
30
|
-
convert a tree into CNF, we simply need to ensure that every subtree
|
|
31
|
-
has either two subtrees as children (binarization), or one leaf node
|
|
32
|
-
(non-terminal). In order to binarize a subtree with more than two
|
|
33
|
-
children, we must introduce artificial nodes.
|
|
34
|
-
|
|
35
|
-
There are two popular methods to convert a tree into CNF: left
|
|
36
|
-
factoring and right factoring. The following example demonstrates
|
|
37
|
-
the difference between them. Example::
|
|
38
|
-
|
|
39
|
-
Original Right-Factored Left-Factored
|
|
40
|
-
|
|
41
|
-
A A A
|
|
42
|
-
/ | \ / \ / \
|
|
43
|
-
B C D ==> B A|<C-D> OR A|<B-C> D
|
|
44
|
-
/ \ / \
|
|
45
|
-
C D B C
|
|
46
|
-
|
|
47
|
-
2. Parent Annotation
|
|
48
|
-
|
|
49
|
-
In addition to binarizing the tree, there are two standard
|
|
50
|
-
modifications to node labels we can do in the same traversal: parent
|
|
51
|
-
annotation and Markov order-N smoothing (or sibling smoothing).
|
|
52
|
-
|
|
53
|
-
The purpose of parent annotation is to refine the probabilities of
|
|
54
|
-
productions by adding a small amount of context. With this simple
|
|
55
|
-
addition, a CYK (inside-outside, dynamic programming chart parse)
|
|
56
|
-
can improve from 74% to 79% accuracy. A natural generalization from
|
|
57
|
-
parent annotation is to grandparent annotation and beyond. The
|
|
58
|
-
tradeoff becomes accuracy gain vs. computational complexity. We
|
|
59
|
-
must also keep in mind data sparcity issues. Example::
|
|
60
|
-
|
|
61
|
-
Original Parent Annotation
|
|
62
|
-
|
|
63
|
-
A A^<?>
|
|
64
|
-
/ | \ / \
|
|
65
|
-
B C D ==> B^<A> A|<C-D>^<?> where ? is the
|
|
66
|
-
/ \ parent of A
|
|
67
|
-
C^<A> D^<A>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
3. Markov order-N smoothing
|
|
71
|
-
|
|
72
|
-
Markov smoothing combats data sparcity issues as well as decreasing
|
|
73
|
-
computational requirements by limiting the number of children
|
|
74
|
-
included in artificial nodes. In practice, most people use an order
|
|
75
|
-
2 grammar. Example::
|
|
76
|
-
|
|
77
|
-
Original No Smoothing Markov order 1 Markov order 2 etc.
|
|
78
|
-
|
|
79
|
-
__A__ A A A
|
|
80
|
-
/ /|\ \ / \ / \ / \
|
|
81
|
-
B C D E F ==> B A|<C-D-E-F> ==> B A|<C> ==> B A|<C-D>
|
|
82
|
-
/ \ / \ / \
|
|
83
|
-
C ... C ... C ...
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Annotation decisions can be thought about in the vertical direction
|
|
88
|
-
(parent, grandparent, etc) and the horizontal direction (number of
|
|
89
|
-
siblings to keep). Parameters to the following functions specify
|
|
90
|
-
these values. For more information see:
|
|
91
|
-
|
|
92
|
-
Dan Klein and Chris Manning (2003) "Accurate Unlexicalized
|
|
93
|
-
Parsing", ACL-03. http://www.aclweb.org/anthology/P03-1054
|
|
94
|
-
|
|
95
|
-
4. Unary Collapsing
|
|
96
|
-
|
|
97
|
-
Collapse unary productions (ie. subtrees with a single child) into a
|
|
98
|
-
new non-terminal (Tree node). This is useful when working with
|
|
99
|
-
algorithms that do not allow unary productions, yet you do not wish
|
|
100
|
-
to lose the parent information. Example::
|
|
101
|
-
|
|
102
|
-
A
|
|
103
|
-
|
|
|
104
|
-
B ==> A+B
|
|
105
|
-
/ \ / \
|
|
106
|
-
C D C D
|
|
107
|
-
|
|
108
|
-
"""
|
|
109
|
-
from __future__ import print_function
|
|
110
|
-
|
|
111
|
-
from nltk.tree import Tree
|
|
112
|
-
|
|
113
|
-
def chomsky_normal_form(tree, factor="right", horzMarkov=None, vertMarkov=0, childChar="|", parentChar="^"):
|
|
114
|
-
# assume all subtrees have homogeneous children
|
|
115
|
-
# assume all terminals have no siblings
|
|
116
|
-
|
|
117
|
-
# A semi-hack to have elegant looking code below. As a result,
|
|
118
|
-
# any subtree with a branching factor greater than 999 will be incorrectly truncated.
|
|
119
|
-
if horzMarkov is None: horzMarkov = 999
|
|
120
|
-
|
|
121
|
-
# Traverse the tree depth-first keeping a list of ancestor nodes to the root.
|
|
122
|
-
# I chose not to use the tree.treepositions() method since it requires
|
|
123
|
-
# two traversals of the tree (one to get the positions, one to iterate
|
|
124
|
-
# over them) and node access time is proportional to the height of the node.
|
|
125
|
-
# This method is 7x faster which helps when parsing 40,000 sentences.
|
|
126
|
-
|
|
127
|
-
nodeList = [(tree, [tree.label()])]
|
|
128
|
-
while nodeList != []:
|
|
129
|
-
node, parent = nodeList.pop()
|
|
130
|
-
if isinstance(node,Tree):
|
|
131
|
-
|
|
132
|
-
# parent annotation
|
|
133
|
-
parentString = ""
|
|
134
|
-
originalNode = node.label()
|
|
135
|
-
if vertMarkov != 0 and node != tree and isinstance(node[0],Tree):
|
|
136
|
-
parentString = "%s<%s>" % (parentChar, "-".join(parent))
|
|
137
|
-
node.set_label(node.label() + parentString)
|
|
138
|
-
parent = [originalNode] + parent[:vertMarkov - 1]
|
|
139
|
-
|
|
140
|
-
# add children to the agenda before we mess with them
|
|
141
|
-
for child in node:
|
|
142
|
-
nodeList.append((child, parent))
|
|
143
|
-
|
|
144
|
-
# chomsky normal form factorization
|
|
145
|
-
if len(node) > 2:
|
|
146
|
-
childNodes = [child.label() for child in node]
|
|
147
|
-
nodeCopy = node.copy()
|
|
148
|
-
node[0:] = [] # delete the children
|
|
149
|
-
|
|
150
|
-
curNode = node
|
|
151
|
-
numChildren = len(nodeCopy)
|
|
152
|
-
for i in range(1,numChildren - 1):
|
|
153
|
-
if factor == "right":
|
|
154
|
-
newHead = "%s%s<%s>%s" % (originalNode, childChar, "-".join(childNodes[i:min([i+horzMarkov,numChildren])]),parentString) # create new head
|
|
155
|
-
newNode = Tree(newHead, [])
|
|
156
|
-
curNode[0:] = [nodeCopy.pop(0), newNode]
|
|
157
|
-
else:
|
|
158
|
-
newHead = "%s%s<%s>%s" % (originalNode, childChar, "-".join(childNodes[max([numChildren-i-horzMarkov,0]):-i]),parentString)
|
|
159
|
-
newNode = Tree(newHead, [])
|
|
160
|
-
curNode[0:] = [newNode, nodeCopy.pop()]
|
|
161
|
-
|
|
162
|
-
curNode = newNode
|
|
163
|
-
|
|
164
|
-
curNode[0:] = [child for child in nodeCopy]
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def un_chomsky_normal_form(tree, expandUnary = True, childChar = "|", parentChar = "^", unaryChar = "+"):
|
|
168
|
-
# Traverse the tree-depth first keeping a pointer to the parent for modification purposes.
|
|
169
|
-
nodeList = [(tree,[])]
|
|
170
|
-
while nodeList != []:
|
|
171
|
-
node,parent = nodeList.pop()
|
|
172
|
-
if isinstance(node,Tree):
|
|
173
|
-
# if the node contains the 'childChar' character it means that
|
|
174
|
-
# it is an artificial node and can be removed, although we still need
|
|
175
|
-
# to move its children to its parent
|
|
176
|
-
childIndex = node.label().find(childChar)
|
|
177
|
-
if childIndex != -1:
|
|
178
|
-
nodeIndex = parent.index(node)
|
|
179
|
-
parent.remove(parent[nodeIndex])
|
|
180
|
-
# Generated node was on the left if the nodeIndex is 0 which
|
|
181
|
-
# means the grammar was left factored. We must insert the children
|
|
182
|
-
# at the beginning of the parent's children
|
|
183
|
-
if nodeIndex == 0:
|
|
184
|
-
parent.insert(0,node[0])
|
|
185
|
-
parent.insert(1,node[1])
|
|
186
|
-
else:
|
|
187
|
-
parent.extend([node[0],node[1]])
|
|
188
|
-
|
|
189
|
-
# parent is now the current node so the children of parent will be added to the agenda
|
|
190
|
-
node = parent
|
|
191
|
-
else:
|
|
192
|
-
parentIndex = node.label().find(parentChar)
|
|
193
|
-
if parentIndex != -1:
|
|
194
|
-
# strip the node name of the parent annotation
|
|
195
|
-
node.set_label(node.label()[:parentIndex])
|
|
196
|
-
|
|
197
|
-
# expand collapsed unary productions
|
|
198
|
-
if expandUnary == True:
|
|
199
|
-
unaryIndex = node.label().find(unaryChar)
|
|
200
|
-
if unaryIndex != -1:
|
|
201
|
-
newNode = Tree(node.label()[unaryIndex + 1:], [i for i in node])
|
|
202
|
-
node.set_label(node.label()[:unaryIndex])
|
|
203
|
-
node[0:] = [newNode]
|
|
204
|
-
|
|
205
|
-
for child in node:
|
|
206
|
-
nodeList.append((child,node))
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def collapse_unary(tree, collapsePOS = False, collapseRoot = False, joinChar = "+"):
|
|
210
|
-
"""
|
|
211
|
-
Collapse subtrees with a single child (ie. unary productions)
|
|
212
|
-
into a new non-terminal (Tree node) joined by 'joinChar'.
|
|
213
|
-
This is useful when working with algorithms that do not allow
|
|
214
|
-
unary productions, and completely removing the unary productions
|
|
215
|
-
would require loss of useful information. The Tree is modified
|
|
216
|
-
directly (since it is passed by reference) and no value is returned.
|
|
217
|
-
|
|
218
|
-
:param tree: The Tree to be collapsed
|
|
219
|
-
:type tree: Tree
|
|
220
|
-
:param collapsePOS: 'False' (default) will not collapse the parent of leaf nodes (ie.
|
|
221
|
-
Part-of-Speech tags) since they are always unary productions
|
|
222
|
-
:type collapsePOS: bool
|
|
223
|
-
:param collapseRoot: 'False' (default) will not modify the root production
|
|
224
|
-
if it is unary. For the Penn WSJ treebank corpus, this corresponds
|
|
225
|
-
to the TOP -> productions.
|
|
226
|
-
:type collapseRoot: bool
|
|
227
|
-
:param joinChar: A string used to connect collapsed node values (default = "+")
|
|
228
|
-
:type joinChar: str
|
|
229
|
-
"""
|
|
230
|
-
|
|
231
|
-
if collapseRoot == False and isinstance(tree, Tree) and len(tree) == 1:
|
|
232
|
-
nodeList = [tree[0]]
|
|
233
|
-
else:
|
|
234
|
-
nodeList = [tree]
|
|
235
|
-
|
|
236
|
-
# depth-first traversal of tree
|
|
237
|
-
while nodeList != []:
|
|
238
|
-
node = nodeList.pop()
|
|
239
|
-
if isinstance(node,Tree):
|
|
240
|
-
if len(node) == 1 and isinstance(node[0], Tree) and (collapsePOS == True or isinstance(node[0,0], Tree)):
|
|
241
|
-
node.set_label(node.label() + joinChar + node[0].label())
|
|
242
|
-
node[0:] = [child for child in node[0]]
|
|
243
|
-
# since we assigned the child's children to the current node,
|
|
244
|
-
# evaluate the current node again
|
|
245
|
-
nodeList.append(node)
|
|
246
|
-
else:
|
|
247
|
-
for child in node:
|
|
248
|
-
nodeList.append(child)
|
|
249
|
-
|
|
250
|
-
#################################################################
|
|
251
|
-
# Demonstration
|
|
252
|
-
#################################################################
|
|
253
|
-
|
|
254
|
-
def demo():
|
|
255
|
-
"""
|
|
256
|
-
A demonstration showing how each tree transform can be used.
|
|
257
|
-
"""
|
|
258
|
-
|
|
259
|
-
from nltk.draw.tree import draw_trees
|
|
260
|
-
from nltk import tree, treetransforms
|
|
261
|
-
from copy import deepcopy
|
|
262
|
-
|
|
263
|
-
# original tree from WSJ bracketed text
|
|
264
|
-
sentence = """(TOP
|
|
265
|
-
(S
|
|
266
|
-
(S
|
|
267
|
-
(VP
|
|
268
|
-
(VBN Turned)
|
|
269
|
-
(ADVP (RB loose))
|
|
270
|
-
(PP
|
|
271
|
-
(IN in)
|
|
272
|
-
(NP
|
|
273
|
-
(NP (NNP Shane) (NNP Longman) (POS 's))
|
|
274
|
-
(NN trading)
|
|
275
|
-
(NN room)))))
|
|
276
|
-
(, ,)
|
|
277
|
-
(NP (DT the) (NN yuppie) (NNS dealers))
|
|
278
|
-
(VP (AUX do) (NP (NP (RB little)) (ADJP (RB right))))
|
|
279
|
-
(. .)))"""
|
|
280
|
-
t = tree.Tree.fromstring(sentence, remove_empty_top_bracketing=True)
|
|
281
|
-
|
|
282
|
-
# collapse subtrees with only one child
|
|
283
|
-
collapsedTree = deepcopy(t)
|
|
284
|
-
treetransforms.collapse_unary(collapsedTree)
|
|
285
|
-
|
|
286
|
-
# convert the tree to CNF
|
|
287
|
-
cnfTree = deepcopy(collapsedTree)
|
|
288
|
-
treetransforms.chomsky_normal_form(cnfTree)
|
|
289
|
-
|
|
290
|
-
# convert the tree to CNF with parent annotation (one level) and horizontal smoothing of order two
|
|
291
|
-
parentTree = deepcopy(collapsedTree)
|
|
292
|
-
treetransforms.chomsky_normal_form(parentTree, horzMarkov=2, vertMarkov=1)
|
|
293
|
-
|
|
294
|
-
# convert the tree back to its original form (used to make CYK results comparable)
|
|
295
|
-
original = deepcopy(parentTree)
|
|
296
|
-
treetransforms.un_chomsky_normal_form(original)
|
|
297
|
-
|
|
298
|
-
# convert tree back to bracketed text
|
|
299
|
-
sentence2 = original.pprint()
|
|
300
|
-
print(sentence)
|
|
301
|
-
print(sentence2)
|
|
302
|
-
print("Sentences the same? ", sentence == sentence2)
|
|
303
|
-
|
|
304
|
-
draw_trees(t, collapsedTree, cnfTree, parentTree, original)
|
|
305
|
-
|
|
306
|
-
if __name__ == '__main__':
|
|
307
|
-
demo()
|
|
308
|
-
|
|
309
|
-
__all__ = ["chomsky_normal_form", "un_chomsky_normal_form", "collapse_unary"]
|
|
1
|
+
# Natural Language Toolkit: Tree Transformations
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2005-2007 Oregon Graduate Institute
|
|
4
|
+
# Author: Nathan Bodenstab <bodenstab@cslu.ogi.edu>
|
|
5
|
+
# URL: <http://nltk.org/>
|
|
6
|
+
# For license information, see LICENSE.TXT
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
A collection of methods for tree (grammar) transformations used
|
|
10
|
+
in parsing natural language.
|
|
11
|
+
|
|
12
|
+
Although many of these methods are technically grammar transformations
|
|
13
|
+
(ie. Chomsky Norm Form), when working with treebanks it is much more
|
|
14
|
+
natural to visualize these modifications in a tree structure. Hence,
|
|
15
|
+
we will do all transformation directly to the tree itself.
|
|
16
|
+
Transforming the tree directly also allows us to do parent annotation.
|
|
17
|
+
A grammar can then be simply induced from the modified tree.
|
|
18
|
+
|
|
19
|
+
The following is a short tutorial on the available transformations.
|
|
20
|
+
|
|
21
|
+
1. Chomsky Normal Form (binarization)
|
|
22
|
+
|
|
23
|
+
It is well known that any grammar has a Chomsky Normal Form (CNF)
|
|
24
|
+
equivalent grammar where CNF is defined by every production having
|
|
25
|
+
either two non-terminals or one terminal on its right hand side.
|
|
26
|
+
When we have hierarchically structured data (ie. a treebank), it is
|
|
27
|
+
natural to view this in terms of productions where the root of every
|
|
28
|
+
subtree is the head (left hand side) of the production and all of
|
|
29
|
+
its children are the right hand side constituents. In order to
|
|
30
|
+
convert a tree into CNF, we simply need to ensure that every subtree
|
|
31
|
+
has either two subtrees as children (binarization), or one leaf node
|
|
32
|
+
(non-terminal). In order to binarize a subtree with more than two
|
|
33
|
+
children, we must introduce artificial nodes.
|
|
34
|
+
|
|
35
|
+
There are two popular methods to convert a tree into CNF: left
|
|
36
|
+
factoring and right factoring. The following example demonstrates
|
|
37
|
+
the difference between them. Example::
|
|
38
|
+
|
|
39
|
+
Original Right-Factored Left-Factored
|
|
40
|
+
|
|
41
|
+
A A A
|
|
42
|
+
/ | \ / \ / \
|
|
43
|
+
B C D ==> B A|<C-D> OR A|<B-C> D
|
|
44
|
+
/ \ / \
|
|
45
|
+
C D B C
|
|
46
|
+
|
|
47
|
+
2. Parent Annotation
|
|
48
|
+
|
|
49
|
+
In addition to binarizing the tree, there are two standard
|
|
50
|
+
modifications to node labels we can do in the same traversal: parent
|
|
51
|
+
annotation and Markov order-N smoothing (or sibling smoothing).
|
|
52
|
+
|
|
53
|
+
The purpose of parent annotation is to refine the probabilities of
|
|
54
|
+
productions by adding a small amount of context. With this simple
|
|
55
|
+
addition, a CYK (inside-outside, dynamic programming chart parse)
|
|
56
|
+
can improve from 74% to 79% accuracy. A natural generalization from
|
|
57
|
+
parent annotation is to grandparent annotation and beyond. The
|
|
58
|
+
tradeoff becomes accuracy gain vs. computational complexity. We
|
|
59
|
+
must also keep in mind data sparcity issues. Example::
|
|
60
|
+
|
|
61
|
+
Original Parent Annotation
|
|
62
|
+
|
|
63
|
+
A A^<?>
|
|
64
|
+
/ | \ / \
|
|
65
|
+
B C D ==> B^<A> A|<C-D>^<?> where ? is the
|
|
66
|
+
/ \ parent of A
|
|
67
|
+
C^<A> D^<A>
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
3. Markov order-N smoothing
|
|
71
|
+
|
|
72
|
+
Markov smoothing combats data sparcity issues as well as decreasing
|
|
73
|
+
computational requirements by limiting the number of children
|
|
74
|
+
included in artificial nodes. In practice, most people use an order
|
|
75
|
+
2 grammar. Example::
|
|
76
|
+
|
|
77
|
+
Original No Smoothing Markov order 1 Markov order 2 etc.
|
|
78
|
+
|
|
79
|
+
__A__ A A A
|
|
80
|
+
/ /|\ \ / \ / \ / \
|
|
81
|
+
B C D E F ==> B A|<C-D-E-F> ==> B A|<C> ==> B A|<C-D>
|
|
82
|
+
/ \ / \ / \
|
|
83
|
+
C ... C ... C ...
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
Annotation decisions can be thought about in the vertical direction
|
|
88
|
+
(parent, grandparent, etc) and the horizontal direction (number of
|
|
89
|
+
siblings to keep). Parameters to the following functions specify
|
|
90
|
+
these values. For more information see:
|
|
91
|
+
|
|
92
|
+
Dan Klein and Chris Manning (2003) "Accurate Unlexicalized
|
|
93
|
+
Parsing", ACL-03. http://www.aclweb.org/anthology/P03-1054
|
|
94
|
+
|
|
95
|
+
4. Unary Collapsing
|
|
96
|
+
|
|
97
|
+
Collapse unary productions (ie. subtrees with a single child) into a
|
|
98
|
+
new non-terminal (Tree node). This is useful when working with
|
|
99
|
+
algorithms that do not allow unary productions, yet you do not wish
|
|
100
|
+
to lose the parent information. Example::
|
|
101
|
+
|
|
102
|
+
A
|
|
103
|
+
|
|
|
104
|
+
B ==> A+B
|
|
105
|
+
/ \ / \
|
|
106
|
+
C D C D
|
|
107
|
+
|
|
108
|
+
"""
|
|
109
|
+
from __future__ import print_function
|
|
110
|
+
|
|
111
|
+
from nltk.tree import Tree
|
|
112
|
+
|
|
113
|
+
def chomsky_normal_form(tree, factor="right", horzMarkov=None, vertMarkov=0, childChar="|", parentChar="^"):
|
|
114
|
+
# assume all subtrees have homogeneous children
|
|
115
|
+
# assume all terminals have no siblings
|
|
116
|
+
|
|
117
|
+
# A semi-hack to have elegant looking code below. As a result,
|
|
118
|
+
# any subtree with a branching factor greater than 999 will be incorrectly truncated.
|
|
119
|
+
if horzMarkov is None: horzMarkov = 999
|
|
120
|
+
|
|
121
|
+
# Traverse the tree depth-first keeping a list of ancestor nodes to the root.
|
|
122
|
+
# I chose not to use the tree.treepositions() method since it requires
|
|
123
|
+
# two traversals of the tree (one to get the positions, one to iterate
|
|
124
|
+
# over them) and node access time is proportional to the height of the node.
|
|
125
|
+
# This method is 7x faster which helps when parsing 40,000 sentences.
|
|
126
|
+
|
|
127
|
+
nodeList = [(tree, [tree.label()])]
|
|
128
|
+
while nodeList != []:
|
|
129
|
+
node, parent = nodeList.pop()
|
|
130
|
+
if isinstance(node,Tree):
|
|
131
|
+
|
|
132
|
+
# parent annotation
|
|
133
|
+
parentString = ""
|
|
134
|
+
originalNode = node.label()
|
|
135
|
+
if vertMarkov != 0 and node != tree and isinstance(node[0],Tree):
|
|
136
|
+
parentString = "%s<%s>" % (parentChar, "-".join(parent))
|
|
137
|
+
node.set_label(node.label() + parentString)
|
|
138
|
+
parent = [originalNode] + parent[:vertMarkov - 1]
|
|
139
|
+
|
|
140
|
+
# add children to the agenda before we mess with them
|
|
141
|
+
for child in node:
|
|
142
|
+
nodeList.append((child, parent))
|
|
143
|
+
|
|
144
|
+
# chomsky normal form factorization
|
|
145
|
+
if len(node) > 2:
|
|
146
|
+
childNodes = [child.label() for child in node]
|
|
147
|
+
nodeCopy = node.copy()
|
|
148
|
+
node[0:] = [] # delete the children
|
|
149
|
+
|
|
150
|
+
curNode = node
|
|
151
|
+
numChildren = len(nodeCopy)
|
|
152
|
+
for i in range(1,numChildren - 1):
|
|
153
|
+
if factor == "right":
|
|
154
|
+
newHead = "%s%s<%s>%s" % (originalNode, childChar, "-".join(childNodes[i:min([i+horzMarkov,numChildren])]),parentString) # create new head
|
|
155
|
+
newNode = Tree(newHead, [])
|
|
156
|
+
curNode[0:] = [nodeCopy.pop(0), newNode]
|
|
157
|
+
else:
|
|
158
|
+
newHead = "%s%s<%s>%s" % (originalNode, childChar, "-".join(childNodes[max([numChildren-i-horzMarkov,0]):-i]),parentString)
|
|
159
|
+
newNode = Tree(newHead, [])
|
|
160
|
+
curNode[0:] = [newNode, nodeCopy.pop()]
|
|
161
|
+
|
|
162
|
+
curNode = newNode
|
|
163
|
+
|
|
164
|
+
curNode[0:] = [child for child in nodeCopy]
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def un_chomsky_normal_form(tree, expandUnary = True, childChar = "|", parentChar = "^", unaryChar = "+"):
|
|
168
|
+
# Traverse the tree-depth first keeping a pointer to the parent for modification purposes.
|
|
169
|
+
nodeList = [(tree,[])]
|
|
170
|
+
while nodeList != []:
|
|
171
|
+
node,parent = nodeList.pop()
|
|
172
|
+
if isinstance(node,Tree):
|
|
173
|
+
# if the node contains the 'childChar' character it means that
|
|
174
|
+
# it is an artificial node and can be removed, although we still need
|
|
175
|
+
# to move its children to its parent
|
|
176
|
+
childIndex = node.label().find(childChar)
|
|
177
|
+
if childIndex != -1:
|
|
178
|
+
nodeIndex = parent.index(node)
|
|
179
|
+
parent.remove(parent[nodeIndex])
|
|
180
|
+
# Generated node was on the left if the nodeIndex is 0 which
|
|
181
|
+
# means the grammar was left factored. We must insert the children
|
|
182
|
+
# at the beginning of the parent's children
|
|
183
|
+
if nodeIndex == 0:
|
|
184
|
+
parent.insert(0,node[0])
|
|
185
|
+
parent.insert(1,node[1])
|
|
186
|
+
else:
|
|
187
|
+
parent.extend([node[0],node[1]])
|
|
188
|
+
|
|
189
|
+
# parent is now the current node so the children of parent will be added to the agenda
|
|
190
|
+
node = parent
|
|
191
|
+
else:
|
|
192
|
+
parentIndex = node.label().find(parentChar)
|
|
193
|
+
if parentIndex != -1:
|
|
194
|
+
# strip the node name of the parent annotation
|
|
195
|
+
node.set_label(node.label()[:parentIndex])
|
|
196
|
+
|
|
197
|
+
# expand collapsed unary productions
|
|
198
|
+
if expandUnary == True:
|
|
199
|
+
unaryIndex = node.label().find(unaryChar)
|
|
200
|
+
if unaryIndex != -1:
|
|
201
|
+
newNode = Tree(node.label()[unaryIndex + 1:], [i for i in node])
|
|
202
|
+
node.set_label(node.label()[:unaryIndex])
|
|
203
|
+
node[0:] = [newNode]
|
|
204
|
+
|
|
205
|
+
for child in node:
|
|
206
|
+
nodeList.append((child,node))
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def collapse_unary(tree, collapsePOS = False, collapseRoot = False, joinChar = "+"):
|
|
210
|
+
"""
|
|
211
|
+
Collapse subtrees with a single child (ie. unary productions)
|
|
212
|
+
into a new non-terminal (Tree node) joined by 'joinChar'.
|
|
213
|
+
This is useful when working with algorithms that do not allow
|
|
214
|
+
unary productions, and completely removing the unary productions
|
|
215
|
+
would require loss of useful information. The Tree is modified
|
|
216
|
+
directly (since it is passed by reference) and no value is returned.
|
|
217
|
+
|
|
218
|
+
:param tree: The Tree to be collapsed
|
|
219
|
+
:type tree: Tree
|
|
220
|
+
:param collapsePOS: 'False' (default) will not collapse the parent of leaf nodes (ie.
|
|
221
|
+
Part-of-Speech tags) since they are always unary productions
|
|
222
|
+
:type collapsePOS: bool
|
|
223
|
+
:param collapseRoot: 'False' (default) will not modify the root production
|
|
224
|
+
if it is unary. For the Penn WSJ treebank corpus, this corresponds
|
|
225
|
+
to the TOP -> productions.
|
|
226
|
+
:type collapseRoot: bool
|
|
227
|
+
:param joinChar: A string used to connect collapsed node values (default = "+")
|
|
228
|
+
:type joinChar: str
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
if collapseRoot == False and isinstance(tree, Tree) and len(tree) == 1:
|
|
232
|
+
nodeList = [tree[0]]
|
|
233
|
+
else:
|
|
234
|
+
nodeList = [tree]
|
|
235
|
+
|
|
236
|
+
# depth-first traversal of tree
|
|
237
|
+
while nodeList != []:
|
|
238
|
+
node = nodeList.pop()
|
|
239
|
+
if isinstance(node,Tree):
|
|
240
|
+
if len(node) == 1 and isinstance(node[0], Tree) and (collapsePOS == True or isinstance(node[0,0], Tree)):
|
|
241
|
+
node.set_label(node.label() + joinChar + node[0].label())
|
|
242
|
+
node[0:] = [child for child in node[0]]
|
|
243
|
+
# since we assigned the child's children to the current node,
|
|
244
|
+
# evaluate the current node again
|
|
245
|
+
nodeList.append(node)
|
|
246
|
+
else:
|
|
247
|
+
for child in node:
|
|
248
|
+
nodeList.append(child)
|
|
249
|
+
|
|
250
|
+
#################################################################
|
|
251
|
+
# Demonstration
|
|
252
|
+
#################################################################
|
|
253
|
+
|
|
254
|
+
def demo():
|
|
255
|
+
"""
|
|
256
|
+
A demonstration showing how each tree transform can be used.
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
from nltk.draw.tree import draw_trees
|
|
260
|
+
from nltk import tree, treetransforms
|
|
261
|
+
from copy import deepcopy
|
|
262
|
+
|
|
263
|
+
# original tree from WSJ bracketed text
|
|
264
|
+
sentence = """(TOP
|
|
265
|
+
(S
|
|
266
|
+
(S
|
|
267
|
+
(VP
|
|
268
|
+
(VBN Turned)
|
|
269
|
+
(ADVP (RB loose))
|
|
270
|
+
(PP
|
|
271
|
+
(IN in)
|
|
272
|
+
(NP
|
|
273
|
+
(NP (NNP Shane) (NNP Longman) (POS 's))
|
|
274
|
+
(NN trading)
|
|
275
|
+
(NN room)))))
|
|
276
|
+
(, ,)
|
|
277
|
+
(NP (DT the) (NN yuppie) (NNS dealers))
|
|
278
|
+
(VP (AUX do) (NP (NP (RB little)) (ADJP (RB right))))
|
|
279
|
+
(. .)))"""
|
|
280
|
+
t = tree.Tree.fromstring(sentence, remove_empty_top_bracketing=True)
|
|
281
|
+
|
|
282
|
+
# collapse subtrees with only one child
|
|
283
|
+
collapsedTree = deepcopy(t)
|
|
284
|
+
treetransforms.collapse_unary(collapsedTree)
|
|
285
|
+
|
|
286
|
+
# convert the tree to CNF
|
|
287
|
+
cnfTree = deepcopy(collapsedTree)
|
|
288
|
+
treetransforms.chomsky_normal_form(cnfTree)
|
|
289
|
+
|
|
290
|
+
# convert the tree to CNF with parent annotation (one level) and horizontal smoothing of order two
|
|
291
|
+
parentTree = deepcopy(collapsedTree)
|
|
292
|
+
treetransforms.chomsky_normal_form(parentTree, horzMarkov=2, vertMarkov=1)
|
|
293
|
+
|
|
294
|
+
# convert the tree back to its original form (used to make CYK results comparable)
|
|
295
|
+
original = deepcopy(parentTree)
|
|
296
|
+
treetransforms.un_chomsky_normal_form(original)
|
|
297
|
+
|
|
298
|
+
# convert tree back to bracketed text
|
|
299
|
+
sentence2 = original.pprint()
|
|
300
|
+
print(sentence)
|
|
301
|
+
print(sentence2)
|
|
302
|
+
print("Sentences the same? ", sentence == sentence2)
|
|
303
|
+
|
|
304
|
+
draw_trees(t, collapsedTree, cnfTree, parentTree, original)
|
|
305
|
+
|
|
306
|
+
if __name__ == '__main__':
|
|
307
|
+
demo()
|
|
308
|
+
|
|
309
|
+
__all__ = ["chomsky_normal_form", "un_chomsky_normal_form", "collapse_unary"]
|