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,221 +1,221 @@
|
|
|
1
|
-
# Natural Language Toolkit: K-Means Clusterer
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2001-
|
|
4
|
-
# Author: Trevor Cohn <tacohn@cs.mu.oz.au>
|
|
5
|
-
# URL: <http://nltk.org/>
|
|
6
|
-
# For license information, see LICENSE.TXT
|
|
7
|
-
from __future__ import print_function, unicode_literals, division
|
|
8
|
-
|
|
9
|
-
import copy
|
|
10
|
-
import random
|
|
11
|
-
import sys
|
|
12
|
-
|
|
13
|
-
try:
|
|
14
|
-
import numpy
|
|
15
|
-
except ImportError:
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
from nltk.cluster.util import VectorSpaceClusterer
|
|
20
|
-
from nltk.compat import python_2_unicode_compatible
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@python_2_unicode_compatible
|
|
24
|
-
class KMeansClusterer(VectorSpaceClusterer):
|
|
25
|
-
"""
|
|
26
|
-
The K-means clusterer starts with k arbitrary chosen means then allocates
|
|
27
|
-
each vector to the cluster with the closest mean. It then recalculates the
|
|
28
|
-
means of each cluster as the centroid of the vectors in the cluster. This
|
|
29
|
-
process repeats until the cluster memberships stabilise. This is a
|
|
30
|
-
hill-climbing algorithm which may converge to a local maximum. Hence the
|
|
31
|
-
clustering is often repeated with random initial means and the most
|
|
32
|
-
commonly occurring output means are chosen.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self, num_means, distance, repeats=1,
|
|
36
|
-
conv_test=1e-6, initial_means=None,
|
|
37
|
-
normalise=False, svd_dimensions=None,
|
|
38
|
-
rng=None, avoid_empty_clusters=False):
|
|
39
|
-
|
|
40
|
-
"""
|
|
41
|
-
:param num_means: the number of means to use (may use fewer)
|
|
42
|
-
:type num_means: int
|
|
43
|
-
:param distance: measure of distance between two vectors
|
|
44
|
-
:type distance: function taking two vectors and returing a float
|
|
45
|
-
:param repeats: number of randomised clustering trials to use
|
|
46
|
-
:type repeats: int
|
|
47
|
-
:param conv_test: maximum variation in mean differences before
|
|
48
|
-
deemed convergent
|
|
49
|
-
:type conv_test: number
|
|
50
|
-
:param initial_means: set of k initial means
|
|
51
|
-
:type initial_means: sequence of vectors
|
|
52
|
-
:param normalise: should vectors be normalised to length 1
|
|
53
|
-
:type normalise: boolean
|
|
54
|
-
:param svd_dimensions: number of dimensions to use in reducing vector
|
|
55
|
-
dimensionsionality with SVD
|
|
56
|
-
:type svd_dimensions: int
|
|
57
|
-
:param rng: random number generator (or None)
|
|
58
|
-
:type rng: Random
|
|
59
|
-
:param avoid_empty_clusters: include current centroid in computation
|
|
60
|
-
of next one; avoids undefined behavior
|
|
61
|
-
when clusters become empty
|
|
62
|
-
:type avoid_empty_clusters: boolean
|
|
63
|
-
"""
|
|
64
|
-
VectorSpaceClusterer.__init__(self, normalise, svd_dimensions)
|
|
65
|
-
self._num_means = num_means
|
|
66
|
-
self._distance = distance
|
|
67
|
-
self._max_difference = conv_test
|
|
68
|
-
assert not initial_means or len(initial_means) == num_means
|
|
69
|
-
self._means = initial_means
|
|
70
|
-
assert repeats >= 1
|
|
71
|
-
assert not (initial_means and repeats > 1)
|
|
72
|
-
self._repeats = repeats
|
|
73
|
-
self._rng = (rng if rng else random.Random())
|
|
74
|
-
self._avoid_empty_clusters = avoid_empty_clusters
|
|
75
|
-
|
|
76
|
-
def cluster_vectorspace(self, vectors, trace=False):
|
|
77
|
-
if self._means and self._repeats > 1:
|
|
78
|
-
print('Warning: means will be discarded for subsequent trials')
|
|
79
|
-
|
|
80
|
-
meanss = []
|
|
81
|
-
for trial in range(self._repeats):
|
|
82
|
-
if trace: print('k-means trial', trial)
|
|
83
|
-
if not self._means or trial > 1:
|
|
84
|
-
self._means = self._rng.sample(list(vectors), self._num_means)
|
|
85
|
-
self._cluster_vectorspace(vectors, trace)
|
|
86
|
-
meanss.append(self._means)
|
|
87
|
-
|
|
88
|
-
if len(meanss) > 1:
|
|
89
|
-
# sort the means first (so that different cluster numbering won't
|
|
90
|
-
# effect the distance comparison)
|
|
91
|
-
for means in meanss:
|
|
92
|
-
means.sort(key=sum)
|
|
93
|
-
|
|
94
|
-
# find the set of means that's minimally different from the others
|
|
95
|
-
min_difference = min_means = None
|
|
96
|
-
for i in range(len(meanss)):
|
|
97
|
-
d = 0
|
|
98
|
-
for j in range(len(meanss)):
|
|
99
|
-
if i != j:
|
|
100
|
-
d += self._sum_distances(meanss[i], meanss[j])
|
|
101
|
-
if min_difference is None or d < min_difference:
|
|
102
|
-
min_difference, min_means = d, meanss[i]
|
|
103
|
-
|
|
104
|
-
# use the best means
|
|
105
|
-
self._means = min_means
|
|
106
|
-
|
|
107
|
-
def _cluster_vectorspace(self, vectors, trace=False):
|
|
108
|
-
if self._num_means < len(vectors):
|
|
109
|
-
# perform k-means clustering
|
|
110
|
-
converged = False
|
|
111
|
-
while not converged:
|
|
112
|
-
# assign the tokens to clusters based on minimum distance to
|
|
113
|
-
# the cluster means
|
|
114
|
-
clusters = [[] for m in range(self._num_means)]
|
|
115
|
-
for vector in vectors:
|
|
116
|
-
index = self.classify_vectorspace(vector)
|
|
117
|
-
clusters[index].append(vector)
|
|
118
|
-
|
|
119
|
-
if trace: print('iteration')
|
|
120
|
-
#for i in range(self._num_means):
|
|
121
|
-
#print ' mean', i, 'allocated', len(clusters[i]), 'vectors'
|
|
122
|
-
|
|
123
|
-
# recalculate cluster means by computing the centroid of each cluster
|
|
124
|
-
new_means = list(map(self._centroid, clusters, self._means))
|
|
125
|
-
|
|
126
|
-
# measure the degree of change from the previous step for convergence
|
|
127
|
-
difference = self._sum_distances(self._means, new_means)
|
|
128
|
-
if difference < self._max_difference:
|
|
129
|
-
converged = True
|
|
130
|
-
|
|
131
|
-
# remember the new means
|
|
132
|
-
self._means = new_means
|
|
133
|
-
|
|
134
|
-
def classify_vectorspace(self, vector):
|
|
135
|
-
# finds the closest cluster centroid
|
|
136
|
-
# returns that cluster's index
|
|
137
|
-
best_distance = best_index = None
|
|
138
|
-
for index in range(len(self._means)):
|
|
139
|
-
mean = self._means[index]
|
|
140
|
-
dist = self._distance(vector, mean)
|
|
141
|
-
if best_distance is None or dist < best_distance:
|
|
142
|
-
best_index, best_distance = index, dist
|
|
143
|
-
return best_index
|
|
144
|
-
|
|
145
|
-
def num_clusters(self):
|
|
146
|
-
if self._means:
|
|
147
|
-
return len(self._means)
|
|
148
|
-
else:
|
|
149
|
-
return self._num_means
|
|
150
|
-
|
|
151
|
-
def means(self):
|
|
152
|
-
"""
|
|
153
|
-
The means used for clustering.
|
|
154
|
-
"""
|
|
155
|
-
return self._means
|
|
156
|
-
|
|
157
|
-
def _sum_distances(self, vectors1, vectors2):
|
|
158
|
-
difference = 0.0
|
|
159
|
-
for u, v in zip(vectors1, vectors2):
|
|
160
|
-
difference += self._distance(u, v)
|
|
161
|
-
return difference
|
|
162
|
-
|
|
163
|
-
def _centroid(self, cluster, mean):
|
|
164
|
-
if self._avoid_empty_clusters:
|
|
165
|
-
centroid = copy.copy(mean)
|
|
166
|
-
for vector in cluster:
|
|
167
|
-
centroid += vector
|
|
168
|
-
return centroid / (1+len(cluster))
|
|
169
|
-
else:
|
|
170
|
-
if not len(cluster):
|
|
171
|
-
sys.stderr.write('Error: no centroid defined for empty cluster.\n')
|
|
172
|
-
sys.stderr.write('Try setting argument \'avoid_empty_clusters\' to True\n')
|
|
173
|
-
assert(False)
|
|
174
|
-
centroid = copy.copy(cluster[0])
|
|
175
|
-
for vector in cluster[1:]:
|
|
176
|
-
centroid += vector
|
|
177
|
-
return centroid / len(cluster)
|
|
178
|
-
|
|
179
|
-
def __repr__(self):
|
|
180
|
-
return '<KMeansClusterer means=%s repeats=%d>' % \
|
|
181
|
-
(self._means, self._repeats)
|
|
182
|
-
|
|
183
|
-
#################################################################################
|
|
184
|
-
|
|
185
|
-
def demo():
|
|
186
|
-
# example from figure 14.9, page 517, Manning and Schutze
|
|
187
|
-
|
|
188
|
-
from nltk.cluster import KMeansClusterer, euclidean_distance
|
|
189
|
-
|
|
190
|
-
vectors = [numpy.array(f) for f in [[2, 1], [1, 3], [4, 7], [6, 7]]]
|
|
191
|
-
means = [[4, 3], [5, 5]]
|
|
192
|
-
|
|
193
|
-
clusterer = KMeansClusterer(2, euclidean_distance, initial_means=means)
|
|
194
|
-
clusters = clusterer.cluster(vectors, True, trace=True)
|
|
195
|
-
|
|
196
|
-
print('Clustered:', vectors)
|
|
197
|
-
print('As:', clusters)
|
|
198
|
-
print('Means:', clusterer.means())
|
|
199
|
-
print()
|
|
200
|
-
|
|
201
|
-
vectors = [numpy.array(f) for f in [[3, 3], [1, 2], [4, 2], [4, 0], [2, 3], [3, 1]]]
|
|
202
|
-
|
|
203
|
-
# test k-means using the euclidean distance metric, 2 means and repeat
|
|
204
|
-
# clustering 10 times with random seeds
|
|
205
|
-
|
|
206
|
-
clusterer = KMeansClusterer(2, euclidean_distance, repeats=10)
|
|
207
|
-
clusters = clusterer.cluster(vectors, True)
|
|
208
|
-
print('Clustered:', vectors)
|
|
209
|
-
print('As:', clusters)
|
|
210
|
-
print('Means:', clusterer.means())
|
|
211
|
-
print()
|
|
212
|
-
|
|
213
|
-
# classify a new vector
|
|
214
|
-
vector = numpy.array([3, 3])
|
|
215
|
-
print('classify(%s):' % vector, end=' ')
|
|
216
|
-
print(clusterer.classify(vector))
|
|
217
|
-
print()
|
|
218
|
-
|
|
219
|
-
if __name__ == '__main__':
|
|
220
|
-
demo()
|
|
221
|
-
|
|
1
|
+
# Natural Language Toolkit: K-Means Clusterer
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2001-2018 NLTK Project
|
|
4
|
+
# Author: Trevor Cohn <tacohn@cs.mu.oz.au>
|
|
5
|
+
# URL: <http://nltk.org/>
|
|
6
|
+
# For license information, see LICENSE.TXT
|
|
7
|
+
from __future__ import print_function, unicode_literals, division
|
|
8
|
+
|
|
9
|
+
import copy
|
|
10
|
+
import random
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import numpy
|
|
15
|
+
except ImportError:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from nltk.cluster.util import VectorSpaceClusterer
|
|
20
|
+
from nltk.compat import python_2_unicode_compatible
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@python_2_unicode_compatible
|
|
24
|
+
class KMeansClusterer(VectorSpaceClusterer):
|
|
25
|
+
"""
|
|
26
|
+
The K-means clusterer starts with k arbitrary chosen means then allocates
|
|
27
|
+
each vector to the cluster with the closest mean. It then recalculates the
|
|
28
|
+
means of each cluster as the centroid of the vectors in the cluster. This
|
|
29
|
+
process repeats until the cluster memberships stabilise. This is a
|
|
30
|
+
hill-climbing algorithm which may converge to a local maximum. Hence the
|
|
31
|
+
clustering is often repeated with random initial means and the most
|
|
32
|
+
commonly occurring output means are chosen.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, num_means, distance, repeats=1,
|
|
36
|
+
conv_test=1e-6, initial_means=None,
|
|
37
|
+
normalise=False, svd_dimensions=None,
|
|
38
|
+
rng=None, avoid_empty_clusters=False):
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
:param num_means: the number of means to use (may use fewer)
|
|
42
|
+
:type num_means: int
|
|
43
|
+
:param distance: measure of distance between two vectors
|
|
44
|
+
:type distance: function taking two vectors and returing a float
|
|
45
|
+
:param repeats: number of randomised clustering trials to use
|
|
46
|
+
:type repeats: int
|
|
47
|
+
:param conv_test: maximum variation in mean differences before
|
|
48
|
+
deemed convergent
|
|
49
|
+
:type conv_test: number
|
|
50
|
+
:param initial_means: set of k initial means
|
|
51
|
+
:type initial_means: sequence of vectors
|
|
52
|
+
:param normalise: should vectors be normalised to length 1
|
|
53
|
+
:type normalise: boolean
|
|
54
|
+
:param svd_dimensions: number of dimensions to use in reducing vector
|
|
55
|
+
dimensionsionality with SVD
|
|
56
|
+
:type svd_dimensions: int
|
|
57
|
+
:param rng: random number generator (or None)
|
|
58
|
+
:type rng: Random
|
|
59
|
+
:param avoid_empty_clusters: include current centroid in computation
|
|
60
|
+
of next one; avoids undefined behavior
|
|
61
|
+
when clusters become empty
|
|
62
|
+
:type avoid_empty_clusters: boolean
|
|
63
|
+
"""
|
|
64
|
+
VectorSpaceClusterer.__init__(self, normalise, svd_dimensions)
|
|
65
|
+
self._num_means = num_means
|
|
66
|
+
self._distance = distance
|
|
67
|
+
self._max_difference = conv_test
|
|
68
|
+
assert not initial_means or len(initial_means) == num_means
|
|
69
|
+
self._means = initial_means
|
|
70
|
+
assert repeats >= 1
|
|
71
|
+
assert not (initial_means and repeats > 1)
|
|
72
|
+
self._repeats = repeats
|
|
73
|
+
self._rng = (rng if rng else random.Random())
|
|
74
|
+
self._avoid_empty_clusters = avoid_empty_clusters
|
|
75
|
+
|
|
76
|
+
def cluster_vectorspace(self, vectors, trace=False):
|
|
77
|
+
if self._means and self._repeats > 1:
|
|
78
|
+
print('Warning: means will be discarded for subsequent trials')
|
|
79
|
+
|
|
80
|
+
meanss = []
|
|
81
|
+
for trial in range(self._repeats):
|
|
82
|
+
if trace: print('k-means trial', trial)
|
|
83
|
+
if not self._means or trial > 1:
|
|
84
|
+
self._means = self._rng.sample(list(vectors), self._num_means)
|
|
85
|
+
self._cluster_vectorspace(vectors, trace)
|
|
86
|
+
meanss.append(self._means)
|
|
87
|
+
|
|
88
|
+
if len(meanss) > 1:
|
|
89
|
+
# sort the means first (so that different cluster numbering won't
|
|
90
|
+
# effect the distance comparison)
|
|
91
|
+
for means in meanss:
|
|
92
|
+
means.sort(key=sum)
|
|
93
|
+
|
|
94
|
+
# find the set of means that's minimally different from the others
|
|
95
|
+
min_difference = min_means = None
|
|
96
|
+
for i in range(len(meanss)):
|
|
97
|
+
d = 0
|
|
98
|
+
for j in range(len(meanss)):
|
|
99
|
+
if i != j:
|
|
100
|
+
d += self._sum_distances(meanss[i], meanss[j])
|
|
101
|
+
if min_difference is None or d < min_difference:
|
|
102
|
+
min_difference, min_means = d, meanss[i]
|
|
103
|
+
|
|
104
|
+
# use the best means
|
|
105
|
+
self._means = min_means
|
|
106
|
+
|
|
107
|
+
def _cluster_vectorspace(self, vectors, trace=False):
|
|
108
|
+
if self._num_means < len(vectors):
|
|
109
|
+
# perform k-means clustering
|
|
110
|
+
converged = False
|
|
111
|
+
while not converged:
|
|
112
|
+
# assign the tokens to clusters based on minimum distance to
|
|
113
|
+
# the cluster means
|
|
114
|
+
clusters = [[] for m in range(self._num_means)]
|
|
115
|
+
for vector in vectors:
|
|
116
|
+
index = self.classify_vectorspace(vector)
|
|
117
|
+
clusters[index].append(vector)
|
|
118
|
+
|
|
119
|
+
if trace: print('iteration')
|
|
120
|
+
#for i in range(self._num_means):
|
|
121
|
+
#print ' mean', i, 'allocated', len(clusters[i]), 'vectors'
|
|
122
|
+
|
|
123
|
+
# recalculate cluster means by computing the centroid of each cluster
|
|
124
|
+
new_means = list(map(self._centroid, clusters, self._means))
|
|
125
|
+
|
|
126
|
+
# measure the degree of change from the previous step for convergence
|
|
127
|
+
difference = self._sum_distances(self._means, new_means)
|
|
128
|
+
if difference < self._max_difference:
|
|
129
|
+
converged = True
|
|
130
|
+
|
|
131
|
+
# remember the new means
|
|
132
|
+
self._means = new_means
|
|
133
|
+
|
|
134
|
+
def classify_vectorspace(self, vector):
|
|
135
|
+
# finds the closest cluster centroid
|
|
136
|
+
# returns that cluster's index
|
|
137
|
+
best_distance = best_index = None
|
|
138
|
+
for index in range(len(self._means)):
|
|
139
|
+
mean = self._means[index]
|
|
140
|
+
dist = self._distance(vector, mean)
|
|
141
|
+
if best_distance is None or dist < best_distance:
|
|
142
|
+
best_index, best_distance = index, dist
|
|
143
|
+
return best_index
|
|
144
|
+
|
|
145
|
+
def num_clusters(self):
|
|
146
|
+
if self._means:
|
|
147
|
+
return len(self._means)
|
|
148
|
+
else:
|
|
149
|
+
return self._num_means
|
|
150
|
+
|
|
151
|
+
def means(self):
|
|
152
|
+
"""
|
|
153
|
+
The means used for clustering.
|
|
154
|
+
"""
|
|
155
|
+
return self._means
|
|
156
|
+
|
|
157
|
+
def _sum_distances(self, vectors1, vectors2):
|
|
158
|
+
difference = 0.0
|
|
159
|
+
for u, v in zip(vectors1, vectors2):
|
|
160
|
+
difference += self._distance(u, v)
|
|
161
|
+
return difference
|
|
162
|
+
|
|
163
|
+
def _centroid(self, cluster, mean):
|
|
164
|
+
if self._avoid_empty_clusters:
|
|
165
|
+
centroid = copy.copy(mean)
|
|
166
|
+
for vector in cluster:
|
|
167
|
+
centroid += vector
|
|
168
|
+
return centroid / (1+len(cluster))
|
|
169
|
+
else:
|
|
170
|
+
if not len(cluster):
|
|
171
|
+
sys.stderr.write('Error: no centroid defined for empty cluster.\n')
|
|
172
|
+
sys.stderr.write('Try setting argument \'avoid_empty_clusters\' to True\n')
|
|
173
|
+
assert(False)
|
|
174
|
+
centroid = copy.copy(cluster[0])
|
|
175
|
+
for vector in cluster[1:]:
|
|
176
|
+
centroid += vector
|
|
177
|
+
return centroid / len(cluster)
|
|
178
|
+
|
|
179
|
+
def __repr__(self):
|
|
180
|
+
return '<KMeansClusterer means=%s repeats=%d>' % \
|
|
181
|
+
(self._means, self._repeats)
|
|
182
|
+
|
|
183
|
+
#################################################################################
|
|
184
|
+
|
|
185
|
+
def demo():
|
|
186
|
+
# example from figure 14.9, page 517, Manning and Schutze
|
|
187
|
+
|
|
188
|
+
from nltk.cluster import KMeansClusterer, euclidean_distance
|
|
189
|
+
|
|
190
|
+
vectors = [numpy.array(f) for f in [[2, 1], [1, 3], [4, 7], [6, 7]]]
|
|
191
|
+
means = [[4, 3], [5, 5]]
|
|
192
|
+
|
|
193
|
+
clusterer = KMeansClusterer(2, euclidean_distance, initial_means=means)
|
|
194
|
+
clusters = clusterer.cluster(vectors, True, trace=True)
|
|
195
|
+
|
|
196
|
+
print('Clustered:', vectors)
|
|
197
|
+
print('As:', clusters)
|
|
198
|
+
print('Means:', clusterer.means())
|
|
199
|
+
print()
|
|
200
|
+
|
|
201
|
+
vectors = [numpy.array(f) for f in [[3, 3], [1, 2], [4, 2], [4, 0], [2, 3], [3, 1]]]
|
|
202
|
+
|
|
203
|
+
# test k-means using the euclidean distance metric, 2 means and repeat
|
|
204
|
+
# clustering 10 times with random seeds
|
|
205
|
+
|
|
206
|
+
clusterer = KMeansClusterer(2, euclidean_distance, repeats=10)
|
|
207
|
+
clusters = clusterer.cluster(vectors, True)
|
|
208
|
+
print('Clustered:', vectors)
|
|
209
|
+
print('As:', clusters)
|
|
210
|
+
print('Means:', clusterer.means())
|
|
211
|
+
print()
|
|
212
|
+
|
|
213
|
+
# classify a new vector
|
|
214
|
+
vector = numpy.array([3, 3])
|
|
215
|
+
print('classify(%s):' % vector, end=' ')
|
|
216
|
+
print(clusterer.classify(vector))
|
|
217
|
+
print()
|
|
218
|
+
|
|
219
|
+
if __name__ == '__main__':
|
|
220
|
+
demo()
|
|
221
|
+
|