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,758 +1,760 @@
|
|
|
1
|
-
# Natural Language Toolkit: Dependency Grammars
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2001-
|
|
4
|
-
# Author: Jason Narad <jason.narad@gmail.com>
|
|
5
|
-
# Steven Bird <stevenbird1@gmail.com> (modifications)
|
|
6
|
-
#
|
|
7
|
-
# URL: <http://nltk.org/>
|
|
8
|
-
# For license information, see LICENSE.TXT
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
"""
|
|
12
|
-
Tools for reading and writing dependency trees.
|
|
13
|
-
The input is assumed to be in Malt-TAB format
|
|
14
|
-
(http://stp.lingfil.uu.se/~nivre/research/MaltXML.html).
|
|
15
|
-
"""
|
|
16
|
-
from __future__ import print_function, unicode_literals
|
|
17
|
-
|
|
18
|
-
from collections import defaultdict
|
|
19
|
-
from itertools import chain
|
|
20
|
-
from pprint import pformat
|
|
21
|
-
import subprocess
|
|
22
|
-
import warnings
|
|
23
|
-
|
|
24
|
-
from
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
#################################################################
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
'
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
new_deps.append(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
self.nodes[
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
... '
|
|
150
|
-
...
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
2 [label="
|
|
160
|
-
|
|
161
|
-
2
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
s
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
s += '\n%s -> %s ' % (node['address'], dep)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
... '
|
|
191
|
-
...
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"""
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
:param
|
|
228
|
-
|
|
229
|
-
:param str
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
#
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
'
|
|
359
|
-
'
|
|
360
|
-
'
|
|
361
|
-
'
|
|
362
|
-
'
|
|
363
|
-
'
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
node
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
return word
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
>>>
|
|
454
|
-
>>>
|
|
455
|
-
>>>
|
|
456
|
-
>>>
|
|
457
|
-
>>>
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
...
|
|
461
|
-
...
|
|
462
|
-
...
|
|
463
|
-
...
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
>>> cyclic_dg.
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
:
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
template = '{word}\t{tag}\t{head}\
|
|
518
|
-
elif style ==
|
|
519
|
-
template = '{
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
g.
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
.
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
networkx.
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
pylab.
|
|
599
|
-
pylab.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
tree.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
cyclic_dg
|
|
630
|
-
cyclic_dg.add_node({'word': None, 'deps': [
|
|
631
|
-
cyclic_dg.add_node({'word': None, 'deps': [
|
|
632
|
-
cyclic_dg.add_node({'word': None, 'deps': [
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
.
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
10
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
1
|
+
# Natural Language Toolkit: Dependency Grammars
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2001-2018 NLTK Project
|
|
4
|
+
# Author: Jason Narad <jason.narad@gmail.com>
|
|
5
|
+
# Steven Bird <stevenbird1@gmail.com> (modifications)
|
|
6
|
+
#
|
|
7
|
+
# URL: <http://nltk.org/>
|
|
8
|
+
# For license information, see LICENSE.TXT
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
Tools for reading and writing dependency trees.
|
|
13
|
+
The input is assumed to be in Malt-TAB format
|
|
14
|
+
(http://stp.lingfil.uu.se/~nivre/research/MaltXML.html).
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import print_function, unicode_literals
|
|
17
|
+
|
|
18
|
+
from collections import defaultdict
|
|
19
|
+
from itertools import chain
|
|
20
|
+
from pprint import pformat
|
|
21
|
+
import subprocess
|
|
22
|
+
import warnings
|
|
23
|
+
|
|
24
|
+
from six import string_types
|
|
25
|
+
|
|
26
|
+
from nltk.tree import Tree
|
|
27
|
+
from nltk.compat import python_2_unicode_compatible
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
#################################################################
|
|
31
|
+
# DependencyGraph Class
|
|
32
|
+
#################################################################
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@python_2_unicode_compatible
|
|
36
|
+
class DependencyGraph(object):
|
|
37
|
+
"""
|
|
38
|
+
A container for the nodes and labelled edges of a dependency structure.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, tree_str=None, cell_extractor=None, zero_based=False, cell_separator=None, top_relation_label='ROOT'):
|
|
42
|
+
"""Dependency graph.
|
|
43
|
+
|
|
44
|
+
We place a dummy `TOP` node with the index 0, since the root node is
|
|
45
|
+
often assigned 0 as its head. This also means that the indexing of the
|
|
46
|
+
nodes corresponds directly to the Malt-TAB format, which starts at 1.
|
|
47
|
+
|
|
48
|
+
If zero-based is True, then Malt-TAB-like input with node numbers
|
|
49
|
+
starting at 0 and the root node assigned -1 (as produced by, e.g.,
|
|
50
|
+
zpar).
|
|
51
|
+
|
|
52
|
+
:param str cell_separator: the cell separator. If not provided, cells
|
|
53
|
+
are split by whitespace.
|
|
54
|
+
|
|
55
|
+
:param str top_relation_label: the label by which the top relation is
|
|
56
|
+
identified, for examlple, `ROOT`, `null` or `TOP`.
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
self.nodes = defaultdict(lambda: {'address': None,
|
|
60
|
+
'word': None,
|
|
61
|
+
'lemma': None,
|
|
62
|
+
'ctag': None,
|
|
63
|
+
'tag': None,
|
|
64
|
+
'feats': None,
|
|
65
|
+
'head': None,
|
|
66
|
+
'deps': defaultdict(list),
|
|
67
|
+
'rel': None,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
self.nodes[0].update(
|
|
71
|
+
{
|
|
72
|
+
'ctag': 'TOP',
|
|
73
|
+
'tag': 'TOP',
|
|
74
|
+
'address': 0,
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
self.root = None
|
|
79
|
+
|
|
80
|
+
if tree_str:
|
|
81
|
+
self._parse(
|
|
82
|
+
tree_str,
|
|
83
|
+
cell_extractor=cell_extractor,
|
|
84
|
+
zero_based=zero_based,
|
|
85
|
+
cell_separator=cell_separator,
|
|
86
|
+
top_relation_label=top_relation_label,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def remove_by_address(self, address):
|
|
90
|
+
"""
|
|
91
|
+
Removes the node with the given address. References
|
|
92
|
+
to this node in others will still exist.
|
|
93
|
+
"""
|
|
94
|
+
del self.nodes[address]
|
|
95
|
+
|
|
96
|
+
def redirect_arcs(self, originals, redirect):
|
|
97
|
+
"""
|
|
98
|
+
Redirects arcs to any of the nodes in the originals list
|
|
99
|
+
to the redirect node address.
|
|
100
|
+
"""
|
|
101
|
+
for node in self.nodes.values():
|
|
102
|
+
new_deps = []
|
|
103
|
+
for dep in node['deps']:
|
|
104
|
+
if dep in originals:
|
|
105
|
+
new_deps.append(redirect)
|
|
106
|
+
else:
|
|
107
|
+
new_deps.append(dep)
|
|
108
|
+
node['deps'] = new_deps
|
|
109
|
+
|
|
110
|
+
def add_arc(self, head_address, mod_address):
|
|
111
|
+
"""
|
|
112
|
+
Adds an arc from the node specified by head_address to the
|
|
113
|
+
node specified by the mod address.
|
|
114
|
+
"""
|
|
115
|
+
relation = self.nodes[mod_address]['rel']
|
|
116
|
+
self.nodes[head_address]['deps'].setdefault(relation, [])
|
|
117
|
+
self.nodes[head_address]['deps'][relation].append(mod_address)
|
|
118
|
+
#self.nodes[head_address]['deps'].append(mod_address)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def connect_graph(self):
|
|
122
|
+
"""
|
|
123
|
+
Fully connects all non-root nodes. All nodes are set to be dependents
|
|
124
|
+
of the root node.
|
|
125
|
+
"""
|
|
126
|
+
for node1 in self.nodes.values():
|
|
127
|
+
for node2 in self.nodes.values():
|
|
128
|
+
if node1['address'] != node2['address'] and node2['rel'] != 'TOP':
|
|
129
|
+
relation = node2['rel']
|
|
130
|
+
node1['deps'].setdefault(relation, [])
|
|
131
|
+
node1['deps'][relation].append(node2['address'])
|
|
132
|
+
#node1['deps'].append(node2['address'])
|
|
133
|
+
|
|
134
|
+
def get_by_address(self, node_address):
|
|
135
|
+
"""Return the node with the given address."""
|
|
136
|
+
return self.nodes[node_address]
|
|
137
|
+
|
|
138
|
+
def contains_address(self, node_address):
|
|
139
|
+
"""
|
|
140
|
+
Returns true if the graph contains a node with the given node
|
|
141
|
+
address, false otherwise.
|
|
142
|
+
"""
|
|
143
|
+
return node_address in self.nodes
|
|
144
|
+
|
|
145
|
+
def to_dot(self):
|
|
146
|
+
"""Return a dot representation suitable for using with Graphviz.
|
|
147
|
+
|
|
148
|
+
>>> dg = DependencyGraph(
|
|
149
|
+
... 'John N 2\\n'
|
|
150
|
+
... 'loves V 0\\n'
|
|
151
|
+
... 'Mary N 2'
|
|
152
|
+
... )
|
|
153
|
+
>>> print(dg.to_dot())
|
|
154
|
+
digraph G{
|
|
155
|
+
edge [dir=forward]
|
|
156
|
+
node [shape=plaintext]
|
|
157
|
+
<BLANKLINE>
|
|
158
|
+
0 [label="0 (None)"]
|
|
159
|
+
0 -> 2 [label="ROOT"]
|
|
160
|
+
1 [label="1 (John)"]
|
|
161
|
+
2 [label="2 (loves)"]
|
|
162
|
+
2 -> 1 [label=""]
|
|
163
|
+
2 -> 3 [label=""]
|
|
164
|
+
3 [label="3 (Mary)"]
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
"""
|
|
168
|
+
# Start the digraph specification
|
|
169
|
+
s = 'digraph G{\n'
|
|
170
|
+
s += 'edge [dir=forward]\n'
|
|
171
|
+
s += 'node [shape=plaintext]\n'
|
|
172
|
+
|
|
173
|
+
# Draw the remaining nodes
|
|
174
|
+
for node in sorted(self.nodes.values(), key=lambda v: v['address']):
|
|
175
|
+
s += '\n%s [label="%s (%s)"]' % (node['address'], node['address'], node['word'])
|
|
176
|
+
for rel, deps in node['deps'].items():
|
|
177
|
+
for dep in deps:
|
|
178
|
+
if rel is not None:
|
|
179
|
+
s += '\n%s -> %s [label="%s"]' % (node['address'], dep, rel)
|
|
180
|
+
else:
|
|
181
|
+
s += '\n%s -> %s ' % (node['address'], dep)
|
|
182
|
+
s += "\n}"
|
|
183
|
+
|
|
184
|
+
return s
|
|
185
|
+
|
|
186
|
+
def _repr_svg_(self):
|
|
187
|
+
"""Show SVG representation of the transducer (IPython magic).
|
|
188
|
+
|
|
189
|
+
>>> dg = DependencyGraph(
|
|
190
|
+
... 'John N 2\\n'
|
|
191
|
+
... 'loves V 0\\n'
|
|
192
|
+
... 'Mary N 2'
|
|
193
|
+
... )
|
|
194
|
+
>>> dg._repr_svg_().split('\\n')[0]
|
|
195
|
+
'<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
|
|
196
|
+
|
|
197
|
+
"""
|
|
198
|
+
dot_string = self.to_dot()
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
process = subprocess.Popen(
|
|
202
|
+
['dot', '-Tsvg'],
|
|
203
|
+
stdin=subprocess.PIPE,
|
|
204
|
+
stdout=subprocess.PIPE,
|
|
205
|
+
stderr=subprocess.PIPE,
|
|
206
|
+
universal_newlines=True,
|
|
207
|
+
)
|
|
208
|
+
except OSError:
|
|
209
|
+
raise Exception('Cannot find the dot binary from Graphviz package')
|
|
210
|
+
out, err = process.communicate(dot_string)
|
|
211
|
+
if err:
|
|
212
|
+
raise Exception(
|
|
213
|
+
'Cannot create svg representation by running dot from string: {}'
|
|
214
|
+
''.format(dot_string))
|
|
215
|
+
return out
|
|
216
|
+
|
|
217
|
+
def __str__(self):
|
|
218
|
+
return pformat(self.nodes)
|
|
219
|
+
|
|
220
|
+
def __repr__(self):
|
|
221
|
+
return "<DependencyGraph with {0} nodes>".format(len(self.nodes))
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def load(filename, zero_based=False, cell_separator=None, top_relation_label='ROOT'):
|
|
225
|
+
"""
|
|
226
|
+
:param filename: a name of a file in Malt-TAB format
|
|
227
|
+
:param zero_based: nodes in the input file are numbered starting from 0
|
|
228
|
+
rather than 1 (as produced by, e.g., zpar)
|
|
229
|
+
:param str cell_separator: the cell separator. If not provided, cells
|
|
230
|
+
are split by whitespace.
|
|
231
|
+
:param str top_relation_label: the label by which the top relation is
|
|
232
|
+
identified, for examlple, `ROOT`, `null` or `TOP`.
|
|
233
|
+
|
|
234
|
+
:return: a list of DependencyGraphs
|
|
235
|
+
|
|
236
|
+
"""
|
|
237
|
+
with open(filename) as infile:
|
|
238
|
+
return [
|
|
239
|
+
DependencyGraph(
|
|
240
|
+
tree_str,
|
|
241
|
+
zero_based=zero_based,
|
|
242
|
+
cell_separator=cell_separator,
|
|
243
|
+
top_relation_label=top_relation_label,
|
|
244
|
+
)
|
|
245
|
+
for tree_str in infile.read().split('\n\n')
|
|
246
|
+
]
|
|
247
|
+
|
|
248
|
+
def left_children(self, node_index):
|
|
249
|
+
"""
|
|
250
|
+
Returns the number of left children under the node specified
|
|
251
|
+
by the given address.
|
|
252
|
+
"""
|
|
253
|
+
children = chain.from_iterable(self.nodes[node_index]['deps'].values())
|
|
254
|
+
index = self.nodes[node_index]['address']
|
|
255
|
+
return sum(1 for c in children if c < index)
|
|
256
|
+
|
|
257
|
+
def right_children(self, node_index):
|
|
258
|
+
"""
|
|
259
|
+
Returns the number of right children under the node specified
|
|
260
|
+
by the given address.
|
|
261
|
+
"""
|
|
262
|
+
children = chain.from_iterable(self.nodes[node_index]['deps'].values())
|
|
263
|
+
index = self.nodes[node_index]['address']
|
|
264
|
+
return sum(1 for c in children if c > index)
|
|
265
|
+
|
|
266
|
+
def add_node(self, node):
|
|
267
|
+
if not self.contains_address(node['address']):
|
|
268
|
+
self.nodes[node['address']].update(node)
|
|
269
|
+
|
|
270
|
+
def _parse(self, input_, cell_extractor=None, zero_based=False, cell_separator=None, top_relation_label='ROOT'):
|
|
271
|
+
"""Parse a sentence.
|
|
272
|
+
|
|
273
|
+
:param extractor: a function that given a tuple of cells returns a
|
|
274
|
+
7-tuple, where the values are ``word, lemma, ctag, tag, feats, head,
|
|
275
|
+
rel``.
|
|
276
|
+
|
|
277
|
+
:param str cell_separator: the cell separator. If not provided, cells
|
|
278
|
+
are split by whitespace.
|
|
279
|
+
|
|
280
|
+
:param str top_relation_label: the label by which the top relation is
|
|
281
|
+
identified, for examlple, `ROOT`, `null` or `TOP`.
|
|
282
|
+
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
def extract_3_cells(cells, index):
|
|
286
|
+
word, tag, head = cells
|
|
287
|
+
return index, word, word, tag, tag, '', head, ''
|
|
288
|
+
|
|
289
|
+
def extract_4_cells(cells, index):
|
|
290
|
+
word, tag, head, rel = cells
|
|
291
|
+
return index, word, word, tag, tag, '', head, rel
|
|
292
|
+
|
|
293
|
+
def extract_7_cells(cells, index):
|
|
294
|
+
line_index, word, lemma, tag, _, head, rel = cells
|
|
295
|
+
try:
|
|
296
|
+
index = int(line_index)
|
|
297
|
+
except ValueError:
|
|
298
|
+
# index can't be parsed as an integer, use default
|
|
299
|
+
pass
|
|
300
|
+
return index, word, lemma, tag, tag, '', head, rel
|
|
301
|
+
|
|
302
|
+
def extract_10_cells(cells, index):
|
|
303
|
+
line_index, word, lemma, ctag, tag, feats, head, rel, _, _ = cells
|
|
304
|
+
try:
|
|
305
|
+
index = int(line_index)
|
|
306
|
+
except ValueError:
|
|
307
|
+
# index can't be parsed as an integer, use default
|
|
308
|
+
pass
|
|
309
|
+
return index, word, lemma, ctag, tag, feats, head, rel
|
|
310
|
+
|
|
311
|
+
extractors = {
|
|
312
|
+
3: extract_3_cells,
|
|
313
|
+
4: extract_4_cells,
|
|
314
|
+
7: extract_7_cells,
|
|
315
|
+
10: extract_10_cells,
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if isinstance(input_, string_types):
|
|
319
|
+
input_ = (line for line in input_.split('\n'))
|
|
320
|
+
|
|
321
|
+
lines = (l.rstrip() for l in input_)
|
|
322
|
+
lines = (l for l in lines if l)
|
|
323
|
+
|
|
324
|
+
cell_number = None
|
|
325
|
+
for index, line in enumerate(lines, start=1):
|
|
326
|
+
cells = line.split(cell_separator)
|
|
327
|
+
if cell_number is None:
|
|
328
|
+
cell_number = len(cells)
|
|
329
|
+
else:
|
|
330
|
+
assert cell_number == len(cells)
|
|
331
|
+
|
|
332
|
+
if cell_extractor is None:
|
|
333
|
+
try:
|
|
334
|
+
cell_extractor = extractors[cell_number]
|
|
335
|
+
except KeyError:
|
|
336
|
+
raise ValueError(
|
|
337
|
+
'Number of tab-delimited fields ({0}) not supported by '
|
|
338
|
+
'CoNLL(10) or Malt-Tab(4) format'.format(cell_number)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
try:
|
|
342
|
+
index, word, lemma, ctag, tag, feats, head, rel = cell_extractor(cells, index)
|
|
343
|
+
except (TypeError, ValueError):
|
|
344
|
+
# cell_extractor doesn't take 2 arguments or doesn't return 8
|
|
345
|
+
# values; assume the cell_extractor is an older external
|
|
346
|
+
# extractor and doesn't accept or return an index.
|
|
347
|
+
word, lemma, ctag, tag, feats, head, rel = cell_extractor(cells)
|
|
348
|
+
|
|
349
|
+
if head == '_':
|
|
350
|
+
continue
|
|
351
|
+
|
|
352
|
+
head = int(head)
|
|
353
|
+
if zero_based:
|
|
354
|
+
head += 1
|
|
355
|
+
|
|
356
|
+
self.nodes[index].update(
|
|
357
|
+
{
|
|
358
|
+
'address': index,
|
|
359
|
+
'word': word,
|
|
360
|
+
'lemma': lemma,
|
|
361
|
+
'ctag': ctag,
|
|
362
|
+
'tag': tag,
|
|
363
|
+
'feats': feats,
|
|
364
|
+
'head': head,
|
|
365
|
+
'rel': rel,
|
|
366
|
+
}
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
# Make sure that the fake root node has labeled dependencies.
|
|
370
|
+
if (cell_number == 3) and (head == 0):
|
|
371
|
+
rel = top_relation_label
|
|
372
|
+
self.nodes[head]['deps'][rel].append(index)
|
|
373
|
+
|
|
374
|
+
if self.nodes[0]['deps'][top_relation_label]:
|
|
375
|
+
root_address = self.nodes[0]['deps'][top_relation_label][0]
|
|
376
|
+
self.root = self.nodes[root_address]
|
|
377
|
+
self.top_relation_label = top_relation_label
|
|
378
|
+
else:
|
|
379
|
+
warnings.warn(
|
|
380
|
+
"The graph doesn't contain a node "
|
|
381
|
+
"that depends on the root element."
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
def _word(self, node, filter=True):
|
|
385
|
+
w = node['word']
|
|
386
|
+
if filter:
|
|
387
|
+
if w != ',':
|
|
388
|
+
return w
|
|
389
|
+
return w
|
|
390
|
+
|
|
391
|
+
def _tree(self, i):
|
|
392
|
+
""" Turn dependency graphs into NLTK trees.
|
|
393
|
+
|
|
394
|
+
:param int i: index of a node
|
|
395
|
+
:return: either a word (if the indexed node is a leaf) or a ``Tree``.
|
|
396
|
+
"""
|
|
397
|
+
node = self.get_by_address(i)
|
|
398
|
+
word = node['word']
|
|
399
|
+
deps = sorted(chain.from_iterable(node['deps'].values()))
|
|
400
|
+
|
|
401
|
+
if deps:
|
|
402
|
+
return Tree(word, [self._tree(dep) for dep in deps])
|
|
403
|
+
else:
|
|
404
|
+
return word
|
|
405
|
+
|
|
406
|
+
def tree(self):
|
|
407
|
+
"""
|
|
408
|
+
Starting with the ``root`` node, build a dependency tree using the NLTK
|
|
409
|
+
``Tree`` constructor. Dependency labels are omitted.
|
|
410
|
+
"""
|
|
411
|
+
node = self.root
|
|
412
|
+
|
|
413
|
+
word = node['word']
|
|
414
|
+
deps = sorted(chain.from_iterable(node['deps'].values()))
|
|
415
|
+
return Tree(word, [self._tree(dep) for dep in deps])
|
|
416
|
+
|
|
417
|
+
def triples(self, node=None):
|
|
418
|
+
"""
|
|
419
|
+
Extract dependency triples of the form:
|
|
420
|
+
((head word, head tag), rel, (dep word, dep tag))
|
|
421
|
+
"""
|
|
422
|
+
|
|
423
|
+
if not node:
|
|
424
|
+
node = self.root
|
|
425
|
+
|
|
426
|
+
head = (node['word'], node['ctag'])
|
|
427
|
+
for i in sorted(chain.from_iterable(node['deps'].values())):
|
|
428
|
+
dep = self.get_by_address(i)
|
|
429
|
+
yield (head, dep['rel'], (dep['word'], dep['ctag']))
|
|
430
|
+
for triple in self.triples(node=dep):
|
|
431
|
+
yield triple
|
|
432
|
+
|
|
433
|
+
def _hd(self, i):
|
|
434
|
+
try:
|
|
435
|
+
return self.nodes[i]['head']
|
|
436
|
+
except IndexError:
|
|
437
|
+
return None
|
|
438
|
+
|
|
439
|
+
def _rel(self, i):
|
|
440
|
+
try:
|
|
441
|
+
return self.nodes[i]['rel']
|
|
442
|
+
except IndexError:
|
|
443
|
+
return None
|
|
444
|
+
|
|
445
|
+
# what's the return type? Boolean or list?
|
|
446
|
+
def contains_cycle(self):
|
|
447
|
+
"""Check whether there are cycles.
|
|
448
|
+
|
|
449
|
+
>>> dg = DependencyGraph(treebank_data)
|
|
450
|
+
>>> dg.contains_cycle()
|
|
451
|
+
False
|
|
452
|
+
|
|
453
|
+
>>> cyclic_dg = DependencyGraph()
|
|
454
|
+
>>> top = {'word': None, 'deps': [1], 'rel': 'TOP', 'address': 0}
|
|
455
|
+
>>> child1 = {'word': None, 'deps': [2], 'rel': 'NTOP', 'address': 1}
|
|
456
|
+
>>> child2 = {'word': None, 'deps': [4], 'rel': 'NTOP', 'address': 2}
|
|
457
|
+
>>> child3 = {'word': None, 'deps': [1], 'rel': 'NTOP', 'address': 3}
|
|
458
|
+
>>> child4 = {'word': None, 'deps': [3], 'rel': 'NTOP', 'address': 4}
|
|
459
|
+
>>> cyclic_dg.nodes = {
|
|
460
|
+
... 0: top,
|
|
461
|
+
... 1: child1,
|
|
462
|
+
... 2: child2,
|
|
463
|
+
... 3: child3,
|
|
464
|
+
... 4: child4,
|
|
465
|
+
... }
|
|
466
|
+
>>> cyclic_dg.root = top
|
|
467
|
+
|
|
468
|
+
>>> cyclic_dg.contains_cycle()
|
|
469
|
+
[3, 1, 2, 4]
|
|
470
|
+
|
|
471
|
+
"""
|
|
472
|
+
distances = {}
|
|
473
|
+
|
|
474
|
+
for node in self.nodes.values():
|
|
475
|
+
for dep in node['deps']:
|
|
476
|
+
key = tuple([node['address'], dep])
|
|
477
|
+
distances[key] = 1
|
|
478
|
+
|
|
479
|
+
for _ in self.nodes:
|
|
480
|
+
new_entries = {}
|
|
481
|
+
|
|
482
|
+
for pair1 in distances:
|
|
483
|
+
for pair2 in distances:
|
|
484
|
+
if pair1[1] == pair2[0]:
|
|
485
|
+
key = tuple([pair1[0], pair2[1]])
|
|
486
|
+
new_entries[key] = distances[pair1] + distances[pair2]
|
|
487
|
+
|
|
488
|
+
for pair in new_entries:
|
|
489
|
+
distances[pair] = new_entries[pair]
|
|
490
|
+
if pair[0] == pair[1]:
|
|
491
|
+
path = self.get_cycle_path(self.get_by_address(pair[0]), pair[0])
|
|
492
|
+
return path
|
|
493
|
+
|
|
494
|
+
return False # return []?
|
|
495
|
+
|
|
496
|
+
def get_cycle_path(self, curr_node, goal_node_index):
|
|
497
|
+
for dep in curr_node['deps']:
|
|
498
|
+
if dep == goal_node_index:
|
|
499
|
+
return [curr_node['address']]
|
|
500
|
+
for dep in curr_node['deps']:
|
|
501
|
+
path = self.get_cycle_path(self.get_by_address(dep), goal_node_index)
|
|
502
|
+
if len(path) > 0:
|
|
503
|
+
path.insert(0, curr_node['address'])
|
|
504
|
+
return path
|
|
505
|
+
return []
|
|
506
|
+
|
|
507
|
+
def to_conll(self, style):
|
|
508
|
+
"""
|
|
509
|
+
The dependency graph in CoNLL format.
|
|
510
|
+
|
|
511
|
+
:param style: the style to use for the format (3, 4, 10 columns)
|
|
512
|
+
:type style: int
|
|
513
|
+
:rtype: str
|
|
514
|
+
"""
|
|
515
|
+
|
|
516
|
+
if style == 3:
|
|
517
|
+
template = '{word}\t{tag}\t{head}\n'
|
|
518
|
+
elif style == 4:
|
|
519
|
+
template = '{word}\t{tag}\t{head}\t{rel}\n'
|
|
520
|
+
elif style == 10:
|
|
521
|
+
template = '{i}\t{word}\t{lemma}\t{ctag}\t{tag}\t{feats}\t{head}\t{rel}\t_\t_\n'
|
|
522
|
+
else:
|
|
523
|
+
raise ValueError(
|
|
524
|
+
'Number of tab-delimited fields ({0}) not supported by '
|
|
525
|
+
'CoNLL(10) or Malt-Tab(4) format'.format(style)
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
return ''.join(template.format(i=i, **node) for i, node in sorted(self.nodes.items()) if node['tag'] != 'TOP')
|
|
529
|
+
|
|
530
|
+
def nx_graph(self):
|
|
531
|
+
"""Convert the data in a ``nodelist`` into a networkx labeled directed graph."""
|
|
532
|
+
import networkx
|
|
533
|
+
|
|
534
|
+
nx_nodelist = list(range(1, len(self.nodes)))
|
|
535
|
+
nx_edgelist = [
|
|
536
|
+
(n, self._hd(n), self._rel(n))
|
|
537
|
+
for n in nx_nodelist if self._hd(n)
|
|
538
|
+
]
|
|
539
|
+
self.nx_labels = {}
|
|
540
|
+
for n in nx_nodelist:
|
|
541
|
+
self.nx_labels[n] = self.nodes[n]['word']
|
|
542
|
+
|
|
543
|
+
g = networkx.MultiDiGraph()
|
|
544
|
+
g.add_nodes_from(nx_nodelist)
|
|
545
|
+
g.add_edges_from(nx_edgelist)
|
|
546
|
+
|
|
547
|
+
return g
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
class DependencyGraphError(Exception):
|
|
551
|
+
"""Dependency graph exception."""
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def demo():
|
|
555
|
+
malt_demo()
|
|
556
|
+
conll_demo()
|
|
557
|
+
conll_file_demo()
|
|
558
|
+
cycle_finding_demo()
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def malt_demo(nx=False):
|
|
562
|
+
"""
|
|
563
|
+
A demonstration of the result of reading a dependency
|
|
564
|
+
version of the first sentence of the Penn Treebank.
|
|
565
|
+
"""
|
|
566
|
+
dg = DependencyGraph("""Pierre NNP 2 NMOD
|
|
567
|
+
Vinken NNP 8 SUB
|
|
568
|
+
, , 2 P
|
|
569
|
+
61 CD 5 NMOD
|
|
570
|
+
years NNS 6 AMOD
|
|
571
|
+
old JJ 2 NMOD
|
|
572
|
+
, , 2 P
|
|
573
|
+
will MD 0 ROOT
|
|
574
|
+
join VB 8 VC
|
|
575
|
+
the DT 11 NMOD
|
|
576
|
+
board NN 9 OBJ
|
|
577
|
+
as IN 9 VMOD
|
|
578
|
+
a DT 15 NMOD
|
|
579
|
+
nonexecutive JJ 15 NMOD
|
|
580
|
+
director NN 12 PMOD
|
|
581
|
+
Nov. NNP 9 VMOD
|
|
582
|
+
29 CD 16 NMOD
|
|
583
|
+
. . 9 VMOD
|
|
584
|
+
""")
|
|
585
|
+
tree = dg.tree()
|
|
586
|
+
tree.pprint()
|
|
587
|
+
if nx:
|
|
588
|
+
# currently doesn't work
|
|
589
|
+
import networkx
|
|
590
|
+
from matplotlib import pylab
|
|
591
|
+
|
|
592
|
+
g = dg.nx_graph()
|
|
593
|
+
g.info()
|
|
594
|
+
pos = networkx.spring_layout(g, dim=1)
|
|
595
|
+
networkx.draw_networkx_nodes(g, pos, node_size=50)
|
|
596
|
+
# networkx.draw_networkx_edges(g, pos, edge_color='k', width=8)
|
|
597
|
+
networkx.draw_networkx_labels(g, pos, dg.nx_labels)
|
|
598
|
+
pylab.xticks([])
|
|
599
|
+
pylab.yticks([])
|
|
600
|
+
pylab.savefig('tree.png')
|
|
601
|
+
pylab.show()
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def conll_demo():
|
|
605
|
+
"""
|
|
606
|
+
A demonstration of how to read a string representation of
|
|
607
|
+
a CoNLL format dependency tree.
|
|
608
|
+
"""
|
|
609
|
+
dg = DependencyGraph(conll_data1)
|
|
610
|
+
tree = dg.tree()
|
|
611
|
+
tree.pprint()
|
|
612
|
+
print(dg)
|
|
613
|
+
print(dg.to_conll(4))
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def conll_file_demo():
|
|
617
|
+
print('Mass conll_read demo...')
|
|
618
|
+
graphs = [DependencyGraph(entry)
|
|
619
|
+
for entry in conll_data2.split('\n\n') if entry]
|
|
620
|
+
for graph in graphs:
|
|
621
|
+
tree = graph.tree()
|
|
622
|
+
print('\n')
|
|
623
|
+
tree.pprint()
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def cycle_finding_demo():
|
|
627
|
+
dg = DependencyGraph(treebank_data)
|
|
628
|
+
print(dg.contains_cycle())
|
|
629
|
+
cyclic_dg = DependencyGraph()
|
|
630
|
+
cyclic_dg.add_node({'word': None, 'deps': [1], 'rel': 'TOP', 'address': 0})
|
|
631
|
+
cyclic_dg.add_node({'word': None, 'deps': [2], 'rel': 'NTOP', 'address': 1})
|
|
632
|
+
cyclic_dg.add_node({'word': None, 'deps': [4], 'rel': 'NTOP', 'address': 2})
|
|
633
|
+
cyclic_dg.add_node({'word': None, 'deps': [1], 'rel': 'NTOP', 'address': 3})
|
|
634
|
+
cyclic_dg.add_node({'word': None, 'deps': [3], 'rel': 'NTOP', 'address': 4})
|
|
635
|
+
print(cyclic_dg.contains_cycle())
|
|
636
|
+
|
|
637
|
+
treebank_data = """Pierre NNP 2 NMOD
|
|
638
|
+
Vinken NNP 8 SUB
|
|
639
|
+
, , 2 P
|
|
640
|
+
61 CD 5 NMOD
|
|
641
|
+
years NNS 6 AMOD
|
|
642
|
+
old JJ 2 NMOD
|
|
643
|
+
, , 2 P
|
|
644
|
+
will MD 0 ROOT
|
|
645
|
+
join VB 8 VC
|
|
646
|
+
the DT 11 NMOD
|
|
647
|
+
board NN 9 OBJ
|
|
648
|
+
as IN 9 VMOD
|
|
649
|
+
a DT 15 NMOD
|
|
650
|
+
nonexecutive JJ 15 NMOD
|
|
651
|
+
director NN 12 PMOD
|
|
652
|
+
Nov. NNP 9 VMOD
|
|
653
|
+
29 CD 16 NMOD
|
|
654
|
+
. . 9 VMOD
|
|
655
|
+
"""
|
|
656
|
+
|
|
657
|
+
conll_data1 = """
|
|
658
|
+
1 Ze ze Pron Pron per|3|evofmv|nom 2 su _ _
|
|
659
|
+
2 had heb V V trans|ovt|1of2of3|ev 0 ROOT _ _
|
|
660
|
+
3 met met Prep Prep voor 8 mod _ _
|
|
661
|
+
4 haar haar Pron Pron bez|3|ev|neut|attr 5 det _ _
|
|
662
|
+
5 moeder moeder N N soort|ev|neut 3 obj1 _ _
|
|
663
|
+
6 kunnen kan V V hulp|ott|1of2of3|mv 2 vc _ _
|
|
664
|
+
7 gaan ga V V hulp|inf 6 vc _ _
|
|
665
|
+
8 winkelen winkel V V intrans|inf 11 cnj _ _
|
|
666
|
+
9 , , Punc Punc komma 8 punct _ _
|
|
667
|
+
10 zwemmen zwem V V intrans|inf 11 cnj _ _
|
|
668
|
+
11 of of Conj Conj neven 7 vc _ _
|
|
669
|
+
12 terrassen terras N N soort|mv|neut 11 cnj _ _
|
|
670
|
+
13 . . Punc Punc punt 12 punct _ _
|
|
671
|
+
"""
|
|
672
|
+
|
|
673
|
+
conll_data2 = """1 Cathy Cathy N N eigen|ev|neut 2 su _ _
|
|
674
|
+
2 zag zie V V trans|ovt|1of2of3|ev 0 ROOT _ _
|
|
675
|
+
3 hen hen Pron Pron per|3|mv|datofacc 2 obj1 _ _
|
|
676
|
+
4 wild wild Adj Adj attr|stell|onverv 5 mod _ _
|
|
677
|
+
5 zwaaien zwaai N N soort|mv|neut 2 vc _ _
|
|
678
|
+
6 . . Punc Punc punt 5 punct _ _
|
|
679
|
+
|
|
680
|
+
1 Ze ze Pron Pron per|3|evofmv|nom 2 su _ _
|
|
681
|
+
2 had heb V V trans|ovt|1of2of3|ev 0 ROOT _ _
|
|
682
|
+
3 met met Prep Prep voor 8 mod _ _
|
|
683
|
+
4 haar haar Pron Pron bez|3|ev|neut|attr 5 det _ _
|
|
684
|
+
5 moeder moeder N N soort|ev|neut 3 obj1 _ _
|
|
685
|
+
6 kunnen kan V V hulp|ott|1of2of3|mv 2 vc _ _
|
|
686
|
+
7 gaan ga V V hulp|inf 6 vc _ _
|
|
687
|
+
8 winkelen winkel V V intrans|inf 11 cnj _ _
|
|
688
|
+
9 , , Punc Punc komma 8 punct _ _
|
|
689
|
+
10 zwemmen zwem V V intrans|inf 11 cnj _ _
|
|
690
|
+
11 of of Conj Conj neven 7 vc _ _
|
|
691
|
+
12 terrassen terras N N soort|mv|neut 11 cnj _ _
|
|
692
|
+
13 . . Punc Punc punt 12 punct _ _
|
|
693
|
+
|
|
694
|
+
1 Dat dat Pron Pron aanw|neut|attr 2 det _ _
|
|
695
|
+
2 werkwoord werkwoord N N soort|ev|neut 6 obj1 _ _
|
|
696
|
+
3 had heb V V hulp|ovt|1of2of3|ev 0 ROOT _ _
|
|
697
|
+
4 ze ze Pron Pron per|3|evofmv|nom 6 su _ _
|
|
698
|
+
5 zelf zelf Pron Pron aanw|neut|attr|wzelf 3 predm _ _
|
|
699
|
+
6 uitgevonden vind V V trans|verldw|onverv 3 vc _ _
|
|
700
|
+
7 . . Punc Punc punt 6 punct _ _
|
|
701
|
+
|
|
702
|
+
1 Het het Pron Pron onbep|neut|zelfst 2 su _ _
|
|
703
|
+
2 hoorde hoor V V trans|ovt|1of2of3|ev 0 ROOT _ _
|
|
704
|
+
3 bij bij Prep Prep voor 2 ld _ _
|
|
705
|
+
4 de de Art Art bep|zijdofmv|neut 6 det _ _
|
|
706
|
+
5 warme warm Adj Adj attr|stell|vervneut 6 mod _ _
|
|
707
|
+
6 zomerdag zomerdag N N soort|ev|neut 3 obj1 _ _
|
|
708
|
+
7 die die Pron Pron betr|neut|zelfst 6 mod _ _
|
|
709
|
+
8 ze ze Pron Pron per|3|evofmv|nom 12 su _ _
|
|
710
|
+
9 ginds ginds Adv Adv gew|aanw 12 mod _ _
|
|
711
|
+
10 achter achter Adv Adv gew|geenfunc|stell|onverv 12 svp _ _
|
|
712
|
+
11 had heb V V hulp|ovt|1of2of3|ev 7 body _ _
|
|
713
|
+
12 gelaten laat V V trans|verldw|onverv 11 vc _ _
|
|
714
|
+
13 . . Punc Punc punt 12 punct _ _
|
|
715
|
+
|
|
716
|
+
1 Ze ze Pron Pron per|3|evofmv|nom 2 su _ _
|
|
717
|
+
2 hadden heb V V trans|ovt|1of2of3|mv 0 ROOT _ _
|
|
718
|
+
3 languit languit Adv Adv gew|geenfunc|stell|onverv 11 mod _ _
|
|
719
|
+
4 naast naast Prep Prep voor 11 mod _ _
|
|
720
|
+
5 elkaar elkaar Pron Pron rec|neut 4 obj1 _ _
|
|
721
|
+
6 op op Prep Prep voor 11 ld _ _
|
|
722
|
+
7 de de Art Art bep|zijdofmv|neut 8 det _ _
|
|
723
|
+
8 strandstoelen strandstoel N N soort|mv|neut 6 obj1 _ _
|
|
724
|
+
9 kunnen kan V V hulp|inf 2 vc _ _
|
|
725
|
+
10 gaan ga V V hulp|inf 9 vc _ _
|
|
726
|
+
11 liggen lig V V intrans|inf 10 vc _ _
|
|
727
|
+
12 . . Punc Punc punt 11 punct _ _
|
|
728
|
+
|
|
729
|
+
1 Zij zij Pron Pron per|3|evofmv|nom 2 su _ _
|
|
730
|
+
2 zou zal V V hulp|ovt|1of2of3|ev 7 cnj _ _
|
|
731
|
+
3 mams mams N N soort|ev|neut 4 det _ _
|
|
732
|
+
4 rug rug N N soort|ev|neut 5 obj1 _ _
|
|
733
|
+
5 ingewreven wrijf V V trans|verldw|onverv 6 vc _ _
|
|
734
|
+
6 hebben heb V V hulp|inf 2 vc _ _
|
|
735
|
+
7 en en Conj Conj neven 0 ROOT _ _
|
|
736
|
+
8 mam mam V V trans|ovt|1of2of3|ev 7 cnj _ _
|
|
737
|
+
9 de de Art Art bep|zijdofmv|neut 10 det _ _
|
|
738
|
+
10 hare hare Pron Pron bez|3|ev|neut|attr 8 obj1 _ _
|
|
739
|
+
11 . . Punc Punc punt 10 punct _ _
|
|
740
|
+
|
|
741
|
+
1 Of of Conj Conj onder|metfin 0 ROOT _ _
|
|
742
|
+
2 ze ze Pron Pron per|3|evofmv|nom 3 su _ _
|
|
743
|
+
3 had heb V V hulp|ovt|1of2of3|ev 0 ROOT _ _
|
|
744
|
+
4 gewoon gewoon Adj Adj adv|stell|onverv 10 mod _ _
|
|
745
|
+
5 met met Prep Prep voor 10 mod _ _
|
|
746
|
+
6 haar haar Pron Pron bez|3|ev|neut|attr 7 det _ _
|
|
747
|
+
7 vriendinnen vriendin N N soort|mv|neut 5 obj1 _ _
|
|
748
|
+
8 rond rond Adv Adv deelv 10 svp _ _
|
|
749
|
+
9 kunnen kan V V hulp|inf 3 vc _ _
|
|
750
|
+
10 slenteren slenter V V intrans|inf 9 vc _ _
|
|
751
|
+
11 in in Prep Prep voor 10 mod _ _
|
|
752
|
+
12 de de Art Art bep|zijdofmv|neut 13 det _ _
|
|
753
|
+
13 buurt buurt N N soort|ev|neut 11 obj1 _ _
|
|
754
|
+
14 van van Prep Prep voor 13 mod _ _
|
|
755
|
+
15 Trafalgar_Square Trafalgar_Square MWU N_N eigen|ev|neut_eigen|ev|neut 14 obj1 _ _
|
|
756
|
+
16 . . Punc Punc punt 15 punct _ _
|
|
757
|
+
"""
|
|
758
|
+
|
|
759
|
+
if __name__ == '__main__':
|
|
760
|
+
demo()
|