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,308 +1,308 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Natural Language Toolkit: IBM Model 2
|
|
3
|
-
#
|
|
4
|
-
# Copyright (C) 2001-2013 NLTK Project
|
|
5
|
-
# Authors: Chin Yee Lee, Hengfeng Li, Ruxin Hou, Calvin Tanujaya Lim
|
|
6
|
-
# URL: <http://nltk.org/>
|
|
7
|
-
# For license information, see LICENSE.TXT
|
|
8
|
-
|
|
9
|
-
"""
|
|
10
|
-
Lexical translation model that considers word order.
|
|
11
|
-
|
|
12
|
-
IBM Model 2 improves on Model 1 by accounting for word order.
|
|
13
|
-
An alignment probability is introduced, a(i | j,l,m), which predicts
|
|
14
|
-
a source word position, given its aligned target word's position.
|
|
15
|
-
|
|
16
|
-
The EM algorithm used in Model 2 is:
|
|
17
|
-
E step - In the training data, collect counts, weighted by prior
|
|
18
|
-
probabilities.
|
|
19
|
-
(a) count how many times a source language word is translated
|
|
20
|
-
into a target language word
|
|
21
|
-
(b) count how many times a particular position in the source
|
|
22
|
-
sentence is aligned to a particular position in the target
|
|
23
|
-
sentence
|
|
24
|
-
|
|
25
|
-
M step - Estimate new probabilities based on the counts from the E step
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Notations:
|
|
29
|
-
i: Position in the source sentence
|
|
30
|
-
Valid values are 0 (for NULL), 1, 2, ..., length of source sentence
|
|
31
|
-
j: Position in the target sentence
|
|
32
|
-
Valid values are 1, 2, ..., length of target sentence
|
|
33
|
-
l: Number of words in the source sentence, excluding NULL
|
|
34
|
-
m: Number of words in the target sentence
|
|
35
|
-
s: A word in the source language
|
|
36
|
-
t: A word in the target language
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
References:
|
|
40
|
-
Philipp Koehn. 2010. Statistical Machine Translation.
|
|
41
|
-
Cambridge University Press, New York.
|
|
42
|
-
|
|
43
|
-
Peter E Brown, Stephen A. Della Pietra, Vincent J. Della Pietra, and
|
|
44
|
-
Robert L. Mercer. 1993. The Mathematics of Statistical Machine
|
|
45
|
-
Translation: Parameter Estimation. Computational Linguistics, 19 (2),
|
|
46
|
-
263-311.
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
from __future__ import division
|
|
50
|
-
from collections import defaultdict
|
|
51
|
-
from nltk.translate import AlignedSent
|
|
52
|
-
from nltk.translate import Alignment
|
|
53
|
-
from nltk.translate import IBMModel
|
|
54
|
-
from nltk.translate import IBMModel1
|
|
55
|
-
from nltk.translate.ibm_model import Counts
|
|
56
|
-
import warnings
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class IBMModel2(IBMModel):
|
|
60
|
-
"""
|
|
61
|
-
Lexical translation model that considers word order
|
|
62
|
-
|
|
63
|
-
>>> bitext = []
|
|
64
|
-
>>> bitext.append(AlignedSent(['klein', 'ist', 'das', 'haus'], ['the', 'house', 'is', 'small']))
|
|
65
|
-
>>> bitext.append(AlignedSent(['das', 'haus', 'ist', 'ja', 'groß'], ['the', 'house', 'is', 'big']))
|
|
66
|
-
>>> bitext.append(AlignedSent(['das', 'buch', 'ist', 'ja', 'klein'], ['the', 'book', 'is', 'small']))
|
|
67
|
-
>>> bitext.append(AlignedSent(['das', 'haus'], ['the', 'house']))
|
|
68
|
-
>>> bitext.append(AlignedSent(['das', 'buch'], ['the', 'book']))
|
|
69
|
-
>>> bitext.append(AlignedSent(['ein', 'buch'], ['a', 'book']))
|
|
70
|
-
|
|
71
|
-
>>> ibm2 = IBMModel2(bitext, 5)
|
|
72
|
-
|
|
73
|
-
>>> print(round(ibm2.translation_table['buch']['book'], 3))
|
|
74
|
-
1.0
|
|
75
|
-
>>> print(round(ibm2.translation_table['das']['book'], 3))
|
|
76
|
-
0.0
|
|
77
|
-
>>> print(round(ibm2.translation_table['buch'][None], 3))
|
|
78
|
-
0.0
|
|
79
|
-
>>> print(round(ibm2.translation_table['ja'][None], 3))
|
|
80
|
-
0.0
|
|
81
|
-
|
|
82
|
-
>>> print(ibm2.alignment_table[1][1][2][2])
|
|
83
|
-
0.938...
|
|
84
|
-
>>> print(round(ibm2.alignment_table[1][2][2][2], 3))
|
|
85
|
-
0.0
|
|
86
|
-
>>> print(round(ibm2.alignment_table[2][2][4][5], 3))
|
|
87
|
-
1.0
|
|
88
|
-
|
|
89
|
-
>>> test_sentence = bitext[2]
|
|
90
|
-
>>> test_sentence.words
|
|
91
|
-
['das', 'buch', 'ist', 'ja', 'klein']
|
|
92
|
-
>>> test_sentence.mots
|
|
93
|
-
['the', 'book', 'is', 'small']
|
|
94
|
-
>>> test_sentence.alignment
|
|
95
|
-
Alignment([(0, 0), (1, 1), (2, 2), (3, 2), (4, 3)])
|
|
96
|
-
|
|
97
|
-
"""
|
|
98
|
-
|
|
99
|
-
def __init__(self, sentence_aligned_corpus, iterations,
|
|
100
|
-
probability_tables=None):
|
|
101
|
-
"""
|
|
102
|
-
Train on ``sentence_aligned_corpus`` and create a lexical
|
|
103
|
-
translation model and an alignment model.
|
|
104
|
-
|
|
105
|
-
Translation direction is from ``AlignedSent.mots`` to
|
|
106
|
-
``AlignedSent.words``.
|
|
107
|
-
|
|
108
|
-
:param sentence_aligned_corpus: Sentence-aligned parallel corpus
|
|
109
|
-
:type sentence_aligned_corpus: list(AlignedSent)
|
|
110
|
-
|
|
111
|
-
:param iterations: Number of iterations to run training algorithm
|
|
112
|
-
:type iterations: int
|
|
113
|
-
|
|
114
|
-
:param probability_tables: Optional. Use this to pass in custom
|
|
115
|
-
probability values. If not specified, probabilities will be
|
|
116
|
-
set to a uniform distribution, or some other sensible value.
|
|
117
|
-
If specified, all the following entries must be present:
|
|
118
|
-
``translation_table``, ``alignment_table``.
|
|
119
|
-
See ``IBMModel`` for the type and purpose of these tables.
|
|
120
|
-
:type probability_tables: dict[str]: object
|
|
121
|
-
"""
|
|
122
|
-
super(IBMModel2, self).__init__(sentence_aligned_corpus)
|
|
123
|
-
|
|
124
|
-
if probability_tables is None:
|
|
125
|
-
# Get translation probabilities from IBM Model 1
|
|
126
|
-
# Run more iterations of training for Model 1, since it is
|
|
127
|
-
# faster than Model 2
|
|
128
|
-
ibm1 = IBMModel1(sentence_aligned_corpus, 2 * iterations)
|
|
129
|
-
self.translation_table = ibm1.translation_table
|
|
130
|
-
self.set_uniform_probabilities(sentence_aligned_corpus)
|
|
131
|
-
else:
|
|
132
|
-
# Set user-defined probabilities
|
|
133
|
-
self.translation_table = probability_tables['translation_table']
|
|
134
|
-
self.alignment_table = probability_tables['alignment_table']
|
|
135
|
-
|
|
136
|
-
for n in range(0, iterations):
|
|
137
|
-
self.train(sentence_aligned_corpus)
|
|
138
|
-
|
|
139
|
-
self.
|
|
140
|
-
|
|
141
|
-
def set_uniform_probabilities(self, sentence_aligned_corpus):
|
|
142
|
-
# a(i | j,l,m) = 1 / (l+1) for all i, j, l, m
|
|
143
|
-
l_m_combinations = set()
|
|
144
|
-
for aligned_sentence in sentence_aligned_corpus:
|
|
145
|
-
l = len(aligned_sentence.mots)
|
|
146
|
-
m = len(aligned_sentence.words)
|
|
147
|
-
if (l, m) not in l_m_combinations:
|
|
148
|
-
l_m_combinations.add((l, m))
|
|
149
|
-
initial_prob = 1 / (l + 1)
|
|
150
|
-
if initial_prob < IBMModel.MIN_PROB:
|
|
151
|
-
warnings.warn("A source sentence is too long (" + str(l) +
|
|
152
|
-
" words). Results may be less accurate.")
|
|
153
|
-
|
|
154
|
-
for i in range(0, l + 1):
|
|
155
|
-
for j in range(1, m + 1):
|
|
156
|
-
self.alignment_table[i][j][l][m] = initial_prob
|
|
157
|
-
|
|
158
|
-
def train(self, parallel_corpus):
|
|
159
|
-
counts = Model2Counts()
|
|
160
|
-
for aligned_sentence in parallel_corpus:
|
|
161
|
-
src_sentence = [None] + aligned_sentence.mots
|
|
162
|
-
trg_sentence = ['UNUSED'] + aligned_sentence.words # 1-indexed
|
|
163
|
-
l = len(aligned_sentence.mots)
|
|
164
|
-
m = len(aligned_sentence.words)
|
|
165
|
-
|
|
166
|
-
# E step (a): Compute normalization factors to weigh counts
|
|
167
|
-
total_count = self.prob_all_alignments(src_sentence, trg_sentence)
|
|
168
|
-
|
|
169
|
-
# E step (b): Collect counts
|
|
170
|
-
for j in range(1, m + 1):
|
|
171
|
-
t = trg_sentence[j]
|
|
172
|
-
for i in range(0, l + 1):
|
|
173
|
-
s = src_sentence[i]
|
|
174
|
-
count = self.prob_alignment_point(
|
|
175
|
-
i, j, src_sentence, trg_sentence)
|
|
176
|
-
normalized_count = count / total_count[t]
|
|
177
|
-
|
|
178
|
-
counts.update_lexical_translation(normalized_count, s, t)
|
|
179
|
-
counts.update_alignment(normalized_count, i, j, l, m)
|
|
180
|
-
|
|
181
|
-
# M step: Update probabilities with maximum likelihood estimates
|
|
182
|
-
self.maximize_lexical_translation_probabilities(counts)
|
|
183
|
-
self.maximize_alignment_probabilities(counts)
|
|
184
|
-
|
|
185
|
-
def maximize_alignment_probabilities(self, counts):
|
|
186
|
-
MIN_PROB = IBMModel.MIN_PROB
|
|
187
|
-
for i, j_s in counts.alignment.items():
|
|
188
|
-
for j, src_sentence_lengths in j_s.items():
|
|
189
|
-
for l, trg_sentence_lengths in src_sentence_lengths.items():
|
|
190
|
-
for m in trg_sentence_lengths:
|
|
191
|
-
estimate = (counts.alignment[i][j][l][m] /
|
|
192
|
-
counts.alignment_for_any_i[j][l][m])
|
|
193
|
-
self.alignment_table[i][j][l][m] = max(estimate,
|
|
194
|
-
MIN_PROB)
|
|
195
|
-
|
|
196
|
-
def prob_all_alignments(self, src_sentence, trg_sentence):
|
|
197
|
-
"""
|
|
198
|
-
Computes the probability of all possible word alignments,
|
|
199
|
-
expressed as a marginal distribution over target words t
|
|
200
|
-
|
|
201
|
-
Each entry in the return value represents the contribution to
|
|
202
|
-
the total alignment probability by the target word t.
|
|
203
|
-
|
|
204
|
-
To obtain probability(alignment | src_sentence, trg_sentence),
|
|
205
|
-
simply sum the entries in the return value.
|
|
206
|
-
|
|
207
|
-
:return: Probability of t for all s in ``src_sentence``
|
|
208
|
-
:rtype: dict(str): float
|
|
209
|
-
"""
|
|
210
|
-
alignment_prob_for_t = defaultdict(lambda: 0.0)
|
|
211
|
-
for j in range(1, len(trg_sentence)):
|
|
212
|
-
t = trg_sentence[j]
|
|
213
|
-
for i in range(0, len(src_sentence)):
|
|
214
|
-
alignment_prob_for_t[t] += self.prob_alignment_point(
|
|
215
|
-
i, j, src_sentence, trg_sentence)
|
|
216
|
-
return alignment_prob_for_t
|
|
217
|
-
|
|
218
|
-
def prob_alignment_point(self, i, j, src_sentence, trg_sentence):
|
|
219
|
-
"""
|
|
220
|
-
Probability that position j in ``trg_sentence`` is aligned to
|
|
221
|
-
position i in the ``src_sentence``
|
|
222
|
-
"""
|
|
223
|
-
l = len(src_sentence) - 1
|
|
224
|
-
m = len(trg_sentence) - 1
|
|
225
|
-
s = src_sentence[i]
|
|
226
|
-
t = trg_sentence[j]
|
|
227
|
-
return self.translation_table[t][s] * self.alignment_table[i][j][l][m]
|
|
228
|
-
|
|
229
|
-
def prob_t_a_given_s(self, alignment_info):
|
|
230
|
-
"""
|
|
231
|
-
Probability of target sentence and an alignment given the
|
|
232
|
-
source sentence
|
|
233
|
-
"""
|
|
234
|
-
prob = 1.0
|
|
235
|
-
l = len(alignment_info.src_sentence) - 1
|
|
236
|
-
m = len(alignment_info.trg_sentence) - 1
|
|
237
|
-
|
|
238
|
-
for j, i in enumerate(alignment_info.alignment):
|
|
239
|
-
if j == 0:
|
|
240
|
-
continue # skip the dummy zeroeth element
|
|
241
|
-
trg_word = alignment_info.trg_sentence[j]
|
|
242
|
-
src_word = alignment_info.src_sentence[i]
|
|
243
|
-
prob *= (self.translation_table[trg_word][src_word] *
|
|
244
|
-
self.alignment_table[i][j][l][m])
|
|
245
|
-
|
|
246
|
-
return max(prob, IBMModel.MIN_PROB)
|
|
247
|
-
|
|
248
|
-
def
|
|
249
|
-
for sentence_pair in parallel_corpus:
|
|
250
|
-
self.
|
|
251
|
-
|
|
252
|
-
def
|
|
253
|
-
"""
|
|
254
|
-
Determines the best word alignment for one sentence pair from
|
|
255
|
-
the corpus that the model was trained on.
|
|
256
|
-
|
|
257
|
-
The best alignment will be set in ``sentence_pair`` when the
|
|
258
|
-
method returns. In contrast with the internal implementation of
|
|
259
|
-
IBM models, the word indices in the ``Alignment`` are zero-
|
|
260
|
-
indexed, not one-indexed.
|
|
261
|
-
|
|
262
|
-
:param sentence_pair: A sentence in the source language and its
|
|
263
|
-
counterpart sentence in the target language
|
|
264
|
-
:type sentence_pair: AlignedSent
|
|
265
|
-
"""
|
|
266
|
-
best_alignment = []
|
|
267
|
-
|
|
268
|
-
l = len(sentence_pair.mots)
|
|
269
|
-
m = len(sentence_pair.words)
|
|
270
|
-
|
|
271
|
-
for j, trg_word in enumerate(sentence_pair.words):
|
|
272
|
-
# Initialize trg_word to align with the NULL token
|
|
273
|
-
best_prob = (self.translation_table[trg_word][None] *
|
|
274
|
-
self.alignment_table[0][j + 1][l][m])
|
|
275
|
-
best_prob = max(best_prob, IBMModel.MIN_PROB)
|
|
276
|
-
best_alignment_point = None
|
|
277
|
-
for i, src_word in enumerate(sentence_pair.mots):
|
|
278
|
-
align_prob = (self.translation_table[trg_word][src_word] *
|
|
279
|
-
self.alignment_table[i + 1][j + 1][l][m])
|
|
280
|
-
if align_prob >= best_prob:
|
|
281
|
-
best_prob = align_prob
|
|
282
|
-
best_alignment_point = i
|
|
283
|
-
|
|
284
|
-
best_alignment.append((j, best_alignment_point))
|
|
285
|
-
|
|
286
|
-
sentence_pair.alignment = Alignment(best_alignment)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
class Model2Counts(Counts):
|
|
290
|
-
"""
|
|
291
|
-
Data object to store counts of various parameters during training.
|
|
292
|
-
Includes counts for alignment.
|
|
293
|
-
"""
|
|
294
|
-
def __init__(self):
|
|
295
|
-
super(Model2Counts, self).__init__()
|
|
296
|
-
self.alignment = defaultdict(
|
|
297
|
-
lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(
|
|
298
|
-
lambda: 0.0))))
|
|
299
|
-
self.alignment_for_any_i = defaultdict(
|
|
300
|
-
lambda: defaultdict(lambda: defaultdict(lambda: 0.0)))
|
|
301
|
-
|
|
302
|
-
def update_lexical_translation(self, count, s, t):
|
|
303
|
-
self.t_given_s[t][s] += count
|
|
304
|
-
self.any_t_given_s[s] += count
|
|
305
|
-
|
|
306
|
-
def update_alignment(self, count, i, j, l, m):
|
|
307
|
-
self.alignment[i][j][l][m] += count
|
|
308
|
-
self.alignment_for_any_i[j][l][m] += count
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Natural Language Toolkit: IBM Model 2
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2001-2013 NLTK Project
|
|
5
|
+
# Authors: Chin Yee Lee, Hengfeng Li, Ruxin Hou, Calvin Tanujaya Lim
|
|
6
|
+
# URL: <http://nltk.org/>
|
|
7
|
+
# For license information, see LICENSE.TXT
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
Lexical translation model that considers word order.
|
|
11
|
+
|
|
12
|
+
IBM Model 2 improves on Model 1 by accounting for word order.
|
|
13
|
+
An alignment probability is introduced, a(i | j,l,m), which predicts
|
|
14
|
+
a source word position, given its aligned target word's position.
|
|
15
|
+
|
|
16
|
+
The EM algorithm used in Model 2 is:
|
|
17
|
+
E step - In the training data, collect counts, weighted by prior
|
|
18
|
+
probabilities.
|
|
19
|
+
(a) count how many times a source language word is translated
|
|
20
|
+
into a target language word
|
|
21
|
+
(b) count how many times a particular position in the source
|
|
22
|
+
sentence is aligned to a particular position in the target
|
|
23
|
+
sentence
|
|
24
|
+
|
|
25
|
+
M step - Estimate new probabilities based on the counts from the E step
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Notations:
|
|
29
|
+
i: Position in the source sentence
|
|
30
|
+
Valid values are 0 (for NULL), 1, 2, ..., length of source sentence
|
|
31
|
+
j: Position in the target sentence
|
|
32
|
+
Valid values are 1, 2, ..., length of target sentence
|
|
33
|
+
l: Number of words in the source sentence, excluding NULL
|
|
34
|
+
m: Number of words in the target sentence
|
|
35
|
+
s: A word in the source language
|
|
36
|
+
t: A word in the target language
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
References:
|
|
40
|
+
Philipp Koehn. 2010. Statistical Machine Translation.
|
|
41
|
+
Cambridge University Press, New York.
|
|
42
|
+
|
|
43
|
+
Peter E Brown, Stephen A. Della Pietra, Vincent J. Della Pietra, and
|
|
44
|
+
Robert L. Mercer. 1993. The Mathematics of Statistical Machine
|
|
45
|
+
Translation: Parameter Estimation. Computational Linguistics, 19 (2),
|
|
46
|
+
263-311.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from __future__ import division
|
|
50
|
+
from collections import defaultdict
|
|
51
|
+
from nltk.translate import AlignedSent
|
|
52
|
+
from nltk.translate import Alignment
|
|
53
|
+
from nltk.translate import IBMModel
|
|
54
|
+
from nltk.translate import IBMModel1
|
|
55
|
+
from nltk.translate.ibm_model import Counts
|
|
56
|
+
import warnings
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class IBMModel2(IBMModel):
|
|
60
|
+
"""
|
|
61
|
+
Lexical translation model that considers word order
|
|
62
|
+
|
|
63
|
+
>>> bitext = []
|
|
64
|
+
>>> bitext.append(AlignedSent(['klein', 'ist', 'das', 'haus'], ['the', 'house', 'is', 'small']))
|
|
65
|
+
>>> bitext.append(AlignedSent(['das', 'haus', 'ist', 'ja', 'groß'], ['the', 'house', 'is', 'big']))
|
|
66
|
+
>>> bitext.append(AlignedSent(['das', 'buch', 'ist', 'ja', 'klein'], ['the', 'book', 'is', 'small']))
|
|
67
|
+
>>> bitext.append(AlignedSent(['das', 'haus'], ['the', 'house']))
|
|
68
|
+
>>> bitext.append(AlignedSent(['das', 'buch'], ['the', 'book']))
|
|
69
|
+
>>> bitext.append(AlignedSent(['ein', 'buch'], ['a', 'book']))
|
|
70
|
+
|
|
71
|
+
>>> ibm2 = IBMModel2(bitext, 5)
|
|
72
|
+
|
|
73
|
+
>>> print(round(ibm2.translation_table['buch']['book'], 3))
|
|
74
|
+
1.0
|
|
75
|
+
>>> print(round(ibm2.translation_table['das']['book'], 3))
|
|
76
|
+
0.0
|
|
77
|
+
>>> print(round(ibm2.translation_table['buch'][None], 3))
|
|
78
|
+
0.0
|
|
79
|
+
>>> print(round(ibm2.translation_table['ja'][None], 3))
|
|
80
|
+
0.0
|
|
81
|
+
|
|
82
|
+
>>> print(ibm2.alignment_table[1][1][2][2])
|
|
83
|
+
0.938...
|
|
84
|
+
>>> print(round(ibm2.alignment_table[1][2][2][2], 3))
|
|
85
|
+
0.0
|
|
86
|
+
>>> print(round(ibm2.alignment_table[2][2][4][5], 3))
|
|
87
|
+
1.0
|
|
88
|
+
|
|
89
|
+
>>> test_sentence = bitext[2]
|
|
90
|
+
>>> test_sentence.words
|
|
91
|
+
['das', 'buch', 'ist', 'ja', 'klein']
|
|
92
|
+
>>> test_sentence.mots
|
|
93
|
+
['the', 'book', 'is', 'small']
|
|
94
|
+
>>> test_sentence.alignment
|
|
95
|
+
Alignment([(0, 0), (1, 1), (2, 2), (3, 2), (4, 3)])
|
|
96
|
+
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
def __init__(self, sentence_aligned_corpus, iterations,
|
|
100
|
+
probability_tables=None):
|
|
101
|
+
"""
|
|
102
|
+
Train on ``sentence_aligned_corpus`` and create a lexical
|
|
103
|
+
translation model and an alignment model.
|
|
104
|
+
|
|
105
|
+
Translation direction is from ``AlignedSent.mots`` to
|
|
106
|
+
``AlignedSent.words``.
|
|
107
|
+
|
|
108
|
+
:param sentence_aligned_corpus: Sentence-aligned parallel corpus
|
|
109
|
+
:type sentence_aligned_corpus: list(AlignedSent)
|
|
110
|
+
|
|
111
|
+
:param iterations: Number of iterations to run training algorithm
|
|
112
|
+
:type iterations: int
|
|
113
|
+
|
|
114
|
+
:param probability_tables: Optional. Use this to pass in custom
|
|
115
|
+
probability values. If not specified, probabilities will be
|
|
116
|
+
set to a uniform distribution, or some other sensible value.
|
|
117
|
+
If specified, all the following entries must be present:
|
|
118
|
+
``translation_table``, ``alignment_table``.
|
|
119
|
+
See ``IBMModel`` for the type and purpose of these tables.
|
|
120
|
+
:type probability_tables: dict[str]: object
|
|
121
|
+
"""
|
|
122
|
+
super(IBMModel2, self).__init__(sentence_aligned_corpus)
|
|
123
|
+
|
|
124
|
+
if probability_tables is None:
|
|
125
|
+
# Get translation probabilities from IBM Model 1
|
|
126
|
+
# Run more iterations of training for Model 1, since it is
|
|
127
|
+
# faster than Model 2
|
|
128
|
+
ibm1 = IBMModel1(sentence_aligned_corpus, 2 * iterations)
|
|
129
|
+
self.translation_table = ibm1.translation_table
|
|
130
|
+
self.set_uniform_probabilities(sentence_aligned_corpus)
|
|
131
|
+
else:
|
|
132
|
+
# Set user-defined probabilities
|
|
133
|
+
self.translation_table = probability_tables['translation_table']
|
|
134
|
+
self.alignment_table = probability_tables['alignment_table']
|
|
135
|
+
|
|
136
|
+
for n in range(0, iterations):
|
|
137
|
+
self.train(sentence_aligned_corpus)
|
|
138
|
+
|
|
139
|
+
self.align_all(sentence_aligned_corpus)
|
|
140
|
+
|
|
141
|
+
def set_uniform_probabilities(self, sentence_aligned_corpus):
|
|
142
|
+
# a(i | j,l,m) = 1 / (l+1) for all i, j, l, m
|
|
143
|
+
l_m_combinations = set()
|
|
144
|
+
for aligned_sentence in sentence_aligned_corpus:
|
|
145
|
+
l = len(aligned_sentence.mots)
|
|
146
|
+
m = len(aligned_sentence.words)
|
|
147
|
+
if (l, m) not in l_m_combinations:
|
|
148
|
+
l_m_combinations.add((l, m))
|
|
149
|
+
initial_prob = 1 / (l + 1)
|
|
150
|
+
if initial_prob < IBMModel.MIN_PROB:
|
|
151
|
+
warnings.warn("A source sentence is too long (" + str(l) +
|
|
152
|
+
" words). Results may be less accurate.")
|
|
153
|
+
|
|
154
|
+
for i in range(0, l + 1):
|
|
155
|
+
for j in range(1, m + 1):
|
|
156
|
+
self.alignment_table[i][j][l][m] = initial_prob
|
|
157
|
+
|
|
158
|
+
def train(self, parallel_corpus):
|
|
159
|
+
counts = Model2Counts()
|
|
160
|
+
for aligned_sentence in parallel_corpus:
|
|
161
|
+
src_sentence = [None] + aligned_sentence.mots
|
|
162
|
+
trg_sentence = ['UNUSED'] + aligned_sentence.words # 1-indexed
|
|
163
|
+
l = len(aligned_sentence.mots)
|
|
164
|
+
m = len(aligned_sentence.words)
|
|
165
|
+
|
|
166
|
+
# E step (a): Compute normalization factors to weigh counts
|
|
167
|
+
total_count = self.prob_all_alignments(src_sentence, trg_sentence)
|
|
168
|
+
|
|
169
|
+
# E step (b): Collect counts
|
|
170
|
+
for j in range(1, m + 1):
|
|
171
|
+
t = trg_sentence[j]
|
|
172
|
+
for i in range(0, l + 1):
|
|
173
|
+
s = src_sentence[i]
|
|
174
|
+
count = self.prob_alignment_point(
|
|
175
|
+
i, j, src_sentence, trg_sentence)
|
|
176
|
+
normalized_count = count / total_count[t]
|
|
177
|
+
|
|
178
|
+
counts.update_lexical_translation(normalized_count, s, t)
|
|
179
|
+
counts.update_alignment(normalized_count, i, j, l, m)
|
|
180
|
+
|
|
181
|
+
# M step: Update probabilities with maximum likelihood estimates
|
|
182
|
+
self.maximize_lexical_translation_probabilities(counts)
|
|
183
|
+
self.maximize_alignment_probabilities(counts)
|
|
184
|
+
|
|
185
|
+
def maximize_alignment_probabilities(self, counts):
|
|
186
|
+
MIN_PROB = IBMModel.MIN_PROB
|
|
187
|
+
for i, j_s in counts.alignment.items():
|
|
188
|
+
for j, src_sentence_lengths in j_s.items():
|
|
189
|
+
for l, trg_sentence_lengths in src_sentence_lengths.items():
|
|
190
|
+
for m in trg_sentence_lengths:
|
|
191
|
+
estimate = (counts.alignment[i][j][l][m] /
|
|
192
|
+
counts.alignment_for_any_i[j][l][m])
|
|
193
|
+
self.alignment_table[i][j][l][m] = max(estimate,
|
|
194
|
+
MIN_PROB)
|
|
195
|
+
|
|
196
|
+
def prob_all_alignments(self, src_sentence, trg_sentence):
|
|
197
|
+
"""
|
|
198
|
+
Computes the probability of all possible word alignments,
|
|
199
|
+
expressed as a marginal distribution over target words t
|
|
200
|
+
|
|
201
|
+
Each entry in the return value represents the contribution to
|
|
202
|
+
the total alignment probability by the target word t.
|
|
203
|
+
|
|
204
|
+
To obtain probability(alignment | src_sentence, trg_sentence),
|
|
205
|
+
simply sum the entries in the return value.
|
|
206
|
+
|
|
207
|
+
:return: Probability of t for all s in ``src_sentence``
|
|
208
|
+
:rtype: dict(str): float
|
|
209
|
+
"""
|
|
210
|
+
alignment_prob_for_t = defaultdict(lambda: 0.0)
|
|
211
|
+
for j in range(1, len(trg_sentence)):
|
|
212
|
+
t = trg_sentence[j]
|
|
213
|
+
for i in range(0, len(src_sentence)):
|
|
214
|
+
alignment_prob_for_t[t] += self.prob_alignment_point(
|
|
215
|
+
i, j, src_sentence, trg_sentence)
|
|
216
|
+
return alignment_prob_for_t
|
|
217
|
+
|
|
218
|
+
def prob_alignment_point(self, i, j, src_sentence, trg_sentence):
|
|
219
|
+
"""
|
|
220
|
+
Probability that position j in ``trg_sentence`` is aligned to
|
|
221
|
+
position i in the ``src_sentence``
|
|
222
|
+
"""
|
|
223
|
+
l = len(src_sentence) - 1
|
|
224
|
+
m = len(trg_sentence) - 1
|
|
225
|
+
s = src_sentence[i]
|
|
226
|
+
t = trg_sentence[j]
|
|
227
|
+
return self.translation_table[t][s] * self.alignment_table[i][j][l][m]
|
|
228
|
+
|
|
229
|
+
def prob_t_a_given_s(self, alignment_info):
|
|
230
|
+
"""
|
|
231
|
+
Probability of target sentence and an alignment given the
|
|
232
|
+
source sentence
|
|
233
|
+
"""
|
|
234
|
+
prob = 1.0
|
|
235
|
+
l = len(alignment_info.src_sentence) - 1
|
|
236
|
+
m = len(alignment_info.trg_sentence) - 1
|
|
237
|
+
|
|
238
|
+
for j, i in enumerate(alignment_info.alignment):
|
|
239
|
+
if j == 0:
|
|
240
|
+
continue # skip the dummy zeroeth element
|
|
241
|
+
trg_word = alignment_info.trg_sentence[j]
|
|
242
|
+
src_word = alignment_info.src_sentence[i]
|
|
243
|
+
prob *= (self.translation_table[trg_word][src_word] *
|
|
244
|
+
self.alignment_table[i][j][l][m])
|
|
245
|
+
|
|
246
|
+
return max(prob, IBMModel.MIN_PROB)
|
|
247
|
+
|
|
248
|
+
def align_all(self, parallel_corpus):
|
|
249
|
+
for sentence_pair in parallel_corpus:
|
|
250
|
+
self.align(sentence_pair)
|
|
251
|
+
|
|
252
|
+
def align(self, sentence_pair):
|
|
253
|
+
"""
|
|
254
|
+
Determines the best word alignment for one sentence pair from
|
|
255
|
+
the corpus that the model was trained on.
|
|
256
|
+
|
|
257
|
+
The best alignment will be set in ``sentence_pair`` when the
|
|
258
|
+
method returns. In contrast with the internal implementation of
|
|
259
|
+
IBM models, the word indices in the ``Alignment`` are zero-
|
|
260
|
+
indexed, not one-indexed.
|
|
261
|
+
|
|
262
|
+
:param sentence_pair: A sentence in the source language and its
|
|
263
|
+
counterpart sentence in the target language
|
|
264
|
+
:type sentence_pair: AlignedSent
|
|
265
|
+
"""
|
|
266
|
+
best_alignment = []
|
|
267
|
+
|
|
268
|
+
l = len(sentence_pair.mots)
|
|
269
|
+
m = len(sentence_pair.words)
|
|
270
|
+
|
|
271
|
+
for j, trg_word in enumerate(sentence_pair.words):
|
|
272
|
+
# Initialize trg_word to align with the NULL token
|
|
273
|
+
best_prob = (self.translation_table[trg_word][None] *
|
|
274
|
+
self.alignment_table[0][j + 1][l][m])
|
|
275
|
+
best_prob = max(best_prob, IBMModel.MIN_PROB)
|
|
276
|
+
best_alignment_point = None
|
|
277
|
+
for i, src_word in enumerate(sentence_pair.mots):
|
|
278
|
+
align_prob = (self.translation_table[trg_word][src_word] *
|
|
279
|
+
self.alignment_table[i + 1][j + 1][l][m])
|
|
280
|
+
if align_prob >= best_prob:
|
|
281
|
+
best_prob = align_prob
|
|
282
|
+
best_alignment_point = i
|
|
283
|
+
|
|
284
|
+
best_alignment.append((j, best_alignment_point))
|
|
285
|
+
|
|
286
|
+
sentence_pair.alignment = Alignment(best_alignment)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class Model2Counts(Counts):
|
|
290
|
+
"""
|
|
291
|
+
Data object to store counts of various parameters during training.
|
|
292
|
+
Includes counts for alignment.
|
|
293
|
+
"""
|
|
294
|
+
def __init__(self):
|
|
295
|
+
super(Model2Counts, self).__init__()
|
|
296
|
+
self.alignment = defaultdict(
|
|
297
|
+
lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(
|
|
298
|
+
lambda: 0.0))))
|
|
299
|
+
self.alignment_for_any_i = defaultdict(
|
|
300
|
+
lambda: defaultdict(lambda: defaultdict(lambda: 0.0)))
|
|
301
|
+
|
|
302
|
+
def update_lexical_translation(self, count, s, t):
|
|
303
|
+
self.t_given_s[t][s] += count
|
|
304
|
+
self.any_t_given_s[s] += count
|
|
305
|
+
|
|
306
|
+
def update_alignment(self, count, i, j, l, m):
|
|
307
|
+
self.alignment[i][j][l][m] += count
|
|
308
|
+
self.alignment_for_any_i[j][l][m] += count
|