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.
Files changed (406) hide show
  1. {nltk-3.2 → nltk-3.3}/INSTALL.txt +6 -6
  2. {nltk-3.2 → nltk-3.3}/LICENSE.txt +13 -13
  3. {nltk-3.2 → nltk-3.3}/MANIFEST.in +6 -6
  4. {nltk-3.2/nltk.egg-info → nltk-3.3}/PKG-INFO +13 -5
  5. nltk-3.2/README.txt → nltk-3.3/README.md +49 -48
  6. nltk-3.3/nltk/VERSION +1 -0
  7. {nltk-3.2 → nltk-3.3}/nltk/__init__.py +185 -185
  8. {nltk-3.2 → nltk-3.3}/nltk/app/__init__.py +52 -53
  9. {nltk-3.2 → nltk-3.3}/nltk/app/chartparser_app.py +2276 -2276
  10. {nltk-3.2 → nltk-3.3}/nltk/app/chunkparser_app.py +1262 -1264
  11. {nltk-3.2 → nltk-3.3}/nltk/app/collocations_app.py +347 -350
  12. {nltk-3.2 → nltk-3.3}/nltk/app/concordance_app.py +568 -570
  13. {nltk-3.2 → nltk-3.3}/nltk/app/nemo_app.py +156 -155
  14. {nltk-3.2 → nltk-3.3}/nltk/app/rdparser_app.py +892 -894
  15. {nltk-3.2 → nltk-3.3}/nltk/app/srparser_app.py +809 -809
  16. {nltk-3.2 → nltk-3.3}/nltk/app/wordfreq_app.py +32 -32
  17. {nltk-3.2 → nltk-3.3}/nltk/app/wordnet_app.py +968 -968
  18. {nltk-3.2 → nltk-3.3}/nltk/book.py +91 -90
  19. {nltk-3.2 → nltk-3.3}/nltk/ccg/__init__.py +22 -22
  20. {nltk-3.2 → nltk-3.3}/nltk/ccg/api.py +359 -335
  21. {nltk-3.2 → nltk-3.3}/nltk/ccg/chart.py +394 -361
  22. {nltk-3.2 → nltk-3.3}/nltk/ccg/combinator.py +343 -312
  23. {nltk-3.2 → nltk-3.3}/nltk/ccg/lexicon.py +328 -290
  24. nltk-3.3/nltk/ccg/logic.py +46 -0
  25. {nltk-3.2 → nltk-3.3}/nltk/chat/__init__.py +49 -49
  26. {nltk-3.2 → nltk-3.3}/nltk/chat/eliza.py +244 -244
  27. {nltk-3.2 → nltk-3.3}/nltk/chat/iesha.py +140 -140
  28. {nltk-3.2 → nltk-3.3}/nltk/chat/rude.py +92 -92
  29. {nltk-3.2 → nltk-3.3}/nltk/chat/suntsu.py +117 -117
  30. {nltk-3.2 → nltk-3.3}/nltk/chat/util.py +122 -120
  31. {nltk-3.2 → nltk-3.3}/nltk/chat/zen.py +282 -282
  32. {nltk-3.2 → nltk-3.3}/nltk/chunk/__init__.py +190 -190
  33. {nltk-3.2 → nltk-3.3}/nltk/chunk/api.py +51 -51
  34. {nltk-3.2 → nltk-3.3}/nltk/chunk/named_entity.py +331 -331
  35. {nltk-3.2 → nltk-3.3}/nltk/chunk/regexp.py +1390 -1384
  36. {nltk-3.2 → nltk-3.3}/nltk/chunk/util.py +600 -600
  37. {nltk-3.2 → nltk-3.3}/nltk/classify/__init__.py +98 -98
  38. {nltk-3.2 → nltk-3.3}/nltk/classify/api.py +193 -193
  39. {nltk-3.2 → nltk-3.3}/nltk/classify/decisiontree.py +295 -295
  40. {nltk-3.2 → nltk-3.3}/nltk/classify/maxent.py +1510 -1492
  41. {nltk-3.2 → nltk-3.3}/nltk/classify/megam.py +179 -178
  42. {nltk-3.2 → nltk-3.3}/nltk/classify/naivebayes.py +245 -242
  43. {nltk-3.2 → nltk-3.3}/nltk/classify/positivenaivebayes.py +170 -170
  44. {nltk-3.2 → nltk-3.3}/nltk/classify/rte_classify.py +160 -191
  45. {nltk-3.2 → nltk-3.3}/nltk/classify/scikitlearn.py +153 -151
  46. {nltk-3.2 → nltk-3.3}/nltk/classify/senna.py +183 -181
  47. {nltk-3.2 → nltk-3.3}/nltk/classify/svm.py +15 -15
  48. {nltk-3.2 → nltk-3.3}/nltk/classify/tadm.py +113 -112
  49. {nltk-3.2 → nltk-3.3}/nltk/classify/textcat.py +193 -193
  50. {nltk-3.2 → nltk-3.3}/nltk/classify/util.py +324 -312
  51. {nltk-3.2 → nltk-3.3}/nltk/classify/weka.py +346 -345
  52. {nltk-3.2 → nltk-3.3}/nltk/cluster/__init__.py +86 -86
  53. {nltk-3.2 → nltk-3.3}/nltk/cluster/api.py +74 -70
  54. {nltk-3.2 → nltk-3.3}/nltk/cluster/em.py +247 -247
  55. {nltk-3.2 → nltk-3.3}/nltk/cluster/gaac.py +168 -168
  56. {nltk-3.2 → nltk-3.3}/nltk/cluster/kmeans.py +221 -221
  57. {nltk-3.2 → nltk-3.3}/nltk/cluster/util.py +304 -289
  58. nltk-3.3/nltk/collections.py +640 -0
  59. {nltk-3.2 → nltk-3.3}/nltk/collocations.py +388 -388
  60. nltk-3.3/nltk/compat.py +365 -0
  61. {nltk-3.2 → nltk-3.3}/nltk/corpus/__init__.py +341 -320
  62. {nltk-3.2 → nltk-3.3}/nltk/corpus/europarl_raw.py +44 -44
  63. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/__init__.py +147 -145
  64. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/aligned.py +115 -114
  65. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/api.py +448 -446
  66. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bnc.py +252 -252
  67. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bracket_parse.py +227 -227
  68. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/categorized_sents.py +179 -178
  69. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chasen.py +140 -139
  70. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/childes.py +522 -494
  71. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chunked.py +212 -212
  72. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/cmudict.py +97 -95
  73. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/comparative_sents.py +280 -278
  74. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/conll.py +528 -521
  75. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/crubadan.py +116 -116
  76. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/dependency.py +101 -101
  77. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/framenet.py +3059 -2093
  78. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ieer.py +112 -111
  79. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/indian.py +85 -86
  80. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ipipan.py +332 -331
  81. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/knbc.py +187 -187
  82. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/lin.py +156 -156
  83. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/mte.py +311 -310
  84. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nkjp.py +429 -428
  85. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nombank.py +421 -421
  86. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nps_chat.py +73 -73
  87. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/opinion_lexicon.py +115 -115
  88. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/panlex_lite.py +165 -165
  89. nltk-3.3/nltk/corpus/reader/pl196x.py +292 -0
  90. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/plaintext.py +232 -233
  91. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ppattach.py +96 -95
  92. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/propbank.py +479 -481
  93. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/pros_cons.py +128 -126
  94. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/reviews.py +330 -328
  95. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/rte.py +144 -146
  96. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/semcor.py +256 -256
  97. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/senseval.py +203 -201
  98. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sentiwordnet.py +137 -137
  99. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sinica_treebank.py +75 -75
  100. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/string_category.py +60 -59
  101. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/switchboard.py +119 -119
  102. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/tagged.py +295 -294
  103. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/timit.py +452 -450
  104. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/toolbox.py +68 -68
  105. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/twitter.py +155 -157
  106. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/udhr.py +80 -80
  107. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/util.py +804 -800
  108. nltk-3.3/nltk/corpus/reader/verbnet.py +595 -0
  109. nltk-3.3/nltk/corpus/reader/wordlist.py +134 -0
  110. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/wordnet.py +2108 -2036
  111. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/xmldocs.py +392 -387
  112. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ycoe.py +243 -242
  113. {nltk-3.2 → nltk-3.3}/nltk/corpus/util.py +144 -127
  114. {nltk-3.2 → nltk-3.3}/nltk/data.py +1487 -1451
  115. {nltk-3.2 → nltk-3.3}/nltk/decorators.py +219 -215
  116. {nltk-3.2 → nltk-3.3}/nltk/downloader.py +2278 -2274
  117. {nltk-3.2 → nltk-3.3}/nltk/draw/__init__.py +27 -27
  118. {nltk-3.2 → nltk-3.3}/nltk/draw/cfg.py +774 -777
  119. {nltk-3.2 → nltk-3.3}/nltk/draw/dispersion.py +58 -58
  120. {nltk-3.2 → nltk-3.3}/nltk/draw/table.py +1098 -1098
  121. {nltk-3.2 → nltk-3.3}/nltk/draw/tree.py +963 -966
  122. {nltk-3.2 → nltk-3.3}/nltk/draw/util.py +2356 -2356
  123. {nltk-3.2 → nltk-3.3}/nltk/featstruct.py +2617 -2500
  124. {nltk-3.2 → nltk-3.3}/nltk/grammar.py +1559 -1516
  125. {nltk-3.2 → nltk-3.3}/nltk/help.py +56 -56
  126. {nltk-3.2 → nltk-3.3}/nltk/inference/__init__.py +20 -20
  127. {nltk-3.2 → nltk-3.3}/nltk/inference/api.py +597 -589
  128. {nltk-3.2 → nltk-3.3}/nltk/inference/discourse.py +612 -608
  129. {nltk-3.2 → nltk-3.3}/nltk/inference/mace.py +311 -311
  130. {nltk-3.2 → nltk-3.3}/nltk/inference/nonmonotonic.py +509 -509
  131. {nltk-3.2 → nltk-3.3}/nltk/inference/prover9.py +431 -431
  132. {nltk-3.2 → nltk-3.3}/nltk/inference/resolution.py +687 -687
  133. {nltk-3.2 → nltk-3.3}/nltk/inference/tableau.py +607 -607
  134. {nltk-3.2 → nltk-3.3}/nltk/internals.py +982 -982
  135. {nltk-3.2 → nltk-3.3}/nltk/jsontags.py +63 -63
  136. {nltk-3.2 → nltk-3.3}/nltk/lazyimport.py +142 -142
  137. {nltk-3.2 → nltk-3.3}/nltk/metrics/__init__.py +30 -29
  138. {nltk-3.2 → nltk-3.3}/nltk/metrics/agreement.py +421 -401
  139. nltk-3.3/nltk/metrics/aline.py +607 -0
  140. {nltk-3.2 → nltk-3.3}/nltk/metrics/association.py +414 -410
  141. {nltk-3.2 → nltk-3.3}/nltk/metrics/confusionmatrix.py +206 -206
  142. {nltk-3.2 → nltk-3.3}/nltk/metrics/distance.py +207 -202
  143. {nltk-3.2 → nltk-3.3}/nltk/metrics/paice.py +381 -381
  144. {nltk-3.2 → nltk-3.3}/nltk/metrics/scores.py +228 -228
  145. {nltk-3.2 → nltk-3.3}/nltk/metrics/segmentation.py +231 -232
  146. {nltk-3.2 → nltk-3.3}/nltk/metrics/spearman.py +69 -69
  147. {nltk-3.2 → nltk-3.3}/nltk/misc/__init__.py +11 -11
  148. {nltk-3.2 → nltk-3.3}/nltk/misc/babelfish.py +10 -10
  149. {nltk-3.2 → nltk-3.3}/nltk/misc/chomsky.py +135 -133
  150. {nltk-3.2 → nltk-3.3}/nltk/misc/minimalset.py +83 -83
  151. {nltk-3.2 → nltk-3.3}/nltk/misc/sort.py +157 -157
  152. {nltk-3.2 → nltk-3.3}/nltk/misc/wordfinder.py +129 -129
  153. {nltk-3.2 → nltk-3.3}/nltk/parse/__init__.py +81 -80
  154. {nltk-3.2 → nltk-3.3}/nltk/parse/api.py +66 -66
  155. {nltk-3.2 → nltk-3.3}/nltk/parse/bllip.py +282 -282
  156. {nltk-3.2 → nltk-3.3}/nltk/parse/chart.py +1682 -1681
  157. nltk-3.3/nltk/parse/corenlp.py +780 -0
  158. {nltk-3.2 → nltk-3.3}/nltk/parse/dependencygraph.py +760 -758
  159. {nltk-3.2 → nltk-3.3}/nltk/parse/earleychart.py +452 -451
  160. {nltk-3.2 → nltk-3.3}/nltk/parse/evaluate.py +129 -129
  161. {nltk-3.2 → nltk-3.3}/nltk/parse/featurechart.py +580 -578
  162. {nltk-3.2 → nltk-3.3}/nltk/parse/generate.py +87 -76
  163. {nltk-3.2 → nltk-3.3}/nltk/parse/malt.py +356 -356
  164. {nltk-3.2 → nltk-3.3}/nltk/parse/nonprojectivedependencyparser.py +783 -783
  165. {nltk-3.2 → nltk-3.3}/nltk/parse/pchart.py +522 -522
  166. {nltk-3.2 → nltk-3.3}/nltk/parse/projectivedependencyparser.py +579 -578
  167. {nltk-3.2 → nltk-3.3}/nltk/parse/recursivedescent.py +655 -656
  168. {nltk-3.2 → nltk-3.3}/nltk/parse/shiftreduce.py +458 -459
  169. {nltk-3.2 → nltk-3.3}/nltk/parse/stanford.py +431 -406
  170. {nltk-3.2 → nltk-3.3}/nltk/parse/transitionparser.py +774 -772
  171. {nltk-3.2 → nltk-3.3}/nltk/parse/util.py +231 -231
  172. {nltk-3.2 → nltk-3.3}/nltk/parse/viterbi.py +401 -401
  173. {nltk-3.2 → nltk-3.3}/nltk/probability.py +2410 -2355
  174. {nltk-3.2 → nltk-3.3}/nltk/sem/__init__.py +61 -61
  175. {nltk-3.2 → nltk-3.3}/nltk/sem/boxer.py +1261 -1261
  176. {nltk-3.2 → nltk-3.3}/nltk/sem/chat80.py +782 -782
  177. {nltk-3.2 → nltk-3.3}/nltk/sem/cooper_storage.py +118 -118
  178. {nltk-3.2 → nltk-3.3}/nltk/sem/drt.py +1258 -1257
  179. {nltk-3.2 → nltk-3.3}/nltk/sem/drt_glue_demo.py +485 -489
  180. {nltk-3.2 → nltk-3.3}/nltk/sem/evaluate.py +790 -784
  181. {nltk-3.2 → nltk-3.3}/nltk/sem/glue.py +696 -694
  182. {nltk-3.2 → nltk-3.3}/nltk/sem/hole.py +386 -384
  183. {nltk-3.2 → nltk-3.3}/nltk/sem/lfg.py +210 -208
  184. {nltk-3.2 → nltk-3.3}/nltk/sem/linearlogic.py +451 -449
  185. {nltk-3.2 → nltk-3.3}/nltk/sem/logic.py +1910 -1910
  186. {nltk-3.2 → nltk-3.3}/nltk/sem/relextract.py +476 -483
  187. {nltk-3.2 → nltk-3.3}/nltk/sem/skolemize.py +101 -101
  188. {nltk-3.2 → nltk-3.3}/nltk/sem/util.py +249 -249
  189. {nltk-3.2 → nltk-3.3}/nltk/sentiment/__init__.py +14 -14
  190. {nltk-3.2 → nltk-3.3}/nltk/sentiment/sentiment_analyzer.py +229 -229
  191. {nltk-3.2 → nltk-3.3}/nltk/sentiment/util.py +762 -752
  192. {nltk-3.2 → nltk-3.3}/nltk/sentiment/vader.py +443 -445
  193. {nltk-3.2 → nltk-3.3}/nltk/stem/__init__.py +31 -33
  194. {nltk-3.2 → nltk-3.3}/nltk/stem/api.py +28 -25
  195. nltk-3.3/nltk/stem/arlstem.py +369 -0
  196. {nltk-3.2 → nltk-3.3}/nltk/stem/isri.py +345 -345
  197. {nltk-3.2 → nltk-3.3}/nltk/stem/lancaster.py +337 -310
  198. nltk-3.3/nltk/stem/porter.py +710 -0
  199. {nltk-3.2 → nltk-3.3}/nltk/stem/regexp.py +61 -61
  200. {nltk-3.2 → nltk-3.3}/nltk/stem/rslp.py +142 -142
  201. {nltk-3.2 → nltk-3.3}/nltk/stem/snowball.py +4236 -3712
  202. {nltk-3.2 → nltk-3.3}/nltk/stem/util.py +22 -12
  203. {nltk-3.2 → nltk-3.3}/nltk/stem/wordnet.py +51 -51
  204. {nltk-3.2 → nltk-3.3}/nltk/tag/__init__.py +152 -127
  205. {nltk-3.2 → nltk-3.3}/nltk/tag/api.py +86 -81
  206. {nltk-3.2 → nltk-3.3}/nltk/tag/brill.py +424 -426
  207. {nltk-3.2 → nltk-3.3}/nltk/tag/brill_trainer.py +608 -608
  208. {nltk-3.2 → nltk-3.3}/nltk/tag/crf.py +204 -200
  209. {nltk-3.2 → nltk-3.3}/nltk/tag/hmm.py +1277 -1277
  210. {nltk-3.2 → nltk-3.3}/nltk/tag/hunpos.py +132 -132
  211. {nltk-3.2 → nltk-3.3}/nltk/tag/mapping.py +101 -101
  212. {nltk-3.2 → nltk-3.3}/nltk/tag/perceptron.py +329 -314
  213. {nltk-3.2 → nltk-3.3}/nltk/tag/senna.py +147 -145
  214. {nltk-3.2 → nltk-3.3}/nltk/tag/sequential.py +740 -736
  215. {nltk-3.2 → nltk-3.3}/nltk/tag/stanford.py +219 -196
  216. {nltk-3.2 → nltk-3.3}/nltk/tag/tnt.py +595 -604
  217. {nltk-3.2 → nltk-3.3}/nltk/tag/util.py +72 -72
  218. {nltk-3.2 → nltk-3.3}/nltk/tbl/__init__.py +28 -28
  219. {nltk-3.2 → nltk-3.3}/nltk/tbl/api.py +1 -1
  220. {nltk-3.2 → nltk-3.3}/nltk/tbl/demo.py +366 -366
  221. {nltk-3.2 → nltk-3.3}/nltk/tbl/erroranalysis.py +39 -39
  222. {nltk-3.2 → nltk-3.3}/nltk/tbl/feature.py +259 -261
  223. {nltk-3.2 → nltk-3.3}/nltk/tbl/rule.py +321 -321
  224. {nltk-3.2 → nltk-3.3}/nltk/tbl/template.py +303 -308
  225. {nltk-3.2 → nltk-3.3}/nltk/test/__init__.py +18 -18
  226. {nltk-3.2 → nltk-3.3}/nltk/test/all.py +24 -23
  227. {nltk-3.2 → nltk-3.3}/nltk/test/bleu.doctest +14 -14
  228. {nltk-3.2 → nltk-3.3}/nltk/test/bnc.doctest +60 -60
  229. {nltk-3.2 → nltk-3.3}/nltk/test/ccg.doctest +376 -395
  230. nltk-3.3/nltk/test/ccg_semantics.doctest +553 -0
  231. {nltk-3.2 → nltk-3.3}/nltk/test/chat80.doctest +234 -234
  232. {nltk-3.2 → nltk-3.3}/nltk/test/childes.doctest +184 -184
  233. {nltk-3.2 → nltk-3.3}/nltk/test/childes_fixt.py +14 -13
  234. {nltk-3.2 → nltk-3.3}/nltk/test/chunk.doctest +373 -373
  235. {nltk-3.2 → nltk-3.3}/nltk/test/classify.doctest +185 -185
  236. {nltk-3.2 → nltk-3.3}/nltk/test/classify_fixt.py +11 -10
  237. nltk-3.3/nltk/test/collections.doctest +20 -0
  238. {nltk-3.2 → nltk-3.3}/nltk/test/collocations.doctest +276 -276
  239. {nltk-3.2 → nltk-3.3}/nltk/test/compat.doctest +134 -138
  240. {nltk-3.2 → nltk-3.3}/nltk/test/compat_fixt.py +9 -8
  241. nltk-3.3/nltk/test/concordance.doctest +55 -0
  242. {nltk-3.2 → nltk-3.3}/nltk/test/corpus.doctest +2200 -2212
  243. {nltk-3.2 → nltk-3.3}/nltk/test/corpus_fixt.py +3 -3
  244. {nltk-3.2 → nltk-3.3}/nltk/test/crubadan.doctest +65 -65
  245. {nltk-3.2 → nltk-3.3}/nltk/test/data.doctest +379 -379
  246. {nltk-3.2 → nltk-3.3}/nltk/test/dependency.doctest +241 -241
  247. {nltk-3.2 → nltk-3.3}/nltk/test/discourse.doctest +546 -546
  248. {nltk-3.2 → nltk-3.3}/nltk/test/discourse_fixt.py +14 -13
  249. {nltk-3.2 → nltk-3.3}/nltk/test/doctest_nose_plugin.py +159 -156
  250. {nltk-3.2 → nltk-3.3}/nltk/test/drt.doctest +517 -517
  251. {nltk-3.2 → nltk-3.3}/nltk/test/featgram.doctest +607 -607
  252. {nltk-3.2 → nltk-3.3}/nltk/test/featstruct.doctest +1229 -1230
  253. {nltk-3.2 → nltk-3.3}/nltk/test/framenet.doctest +288 -239
  254. {nltk-3.2 → nltk-3.3}/nltk/test/generate.doctest +67 -67
  255. {nltk-3.2 → nltk-3.3}/nltk/test/gensim.doctest +140 -141
  256. {nltk-3.2 → nltk-3.3}/nltk/test/gensim_fixt.py +10 -9
  257. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics.doctest +384 -386
  258. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt.doctest +68 -68
  259. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt_fixt.py +12 -11
  260. {nltk-3.2 → nltk-3.3}/nltk/test/grammar.doctest +48 -48
  261. {nltk-3.2 → nltk-3.3}/nltk/test/grammartestsuites.doctest +109 -109
  262. {nltk-3.2 → nltk-3.3}/nltk/test/index.doctest +100 -100
  263. {nltk-3.2 → nltk-3.3}/nltk/test/inference.doctest +534 -534
  264. {nltk-3.2 → nltk-3.3}/nltk/test/inference_fixt.py +12 -11
  265. {nltk-3.2 → nltk-3.3}/nltk/test/internals.doctest +140 -140
  266. {nltk-3.2 → nltk-3.3}/nltk/test/japanese.doctest +48 -48
  267. {nltk-3.2 → nltk-3.3}/nltk/test/logic.doctest +1098 -1098
  268. {nltk-3.2 → nltk-3.3}/nltk/test/metrics.doctest +270 -270
  269. {nltk-3.2 → nltk-3.3}/nltk/test/misc.doctest +118 -118
  270. {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic.doctest +286 -286
  271. {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic_fixt.py +12 -11
  272. {nltk-3.2 → nltk-3.3}/nltk/test/paice.doctest +35 -35
  273. {nltk-3.2 → nltk-3.3}/nltk/test/parse.doctest +884 -884
  274. {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en.doctest +565 -565
  275. {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en_fixt.py +16 -16
  276. {nltk-3.2 → nltk-3.3}/nltk/test/probability.doctest +304 -304
  277. {nltk-3.2 → nltk-3.3}/nltk/test/probability_fixt.py +13 -12
  278. {nltk-3.2 → nltk-3.3}/nltk/test/propbank.doctest +176 -176
  279. {nltk-3.2 → nltk-3.3}/nltk/test/relextract.doctest +263 -263
  280. {nltk-3.2 → nltk-3.3}/nltk/test/resolution.doctest +221 -221
  281. {nltk-3.2 → nltk-3.3}/nltk/test/runtests.py +86 -64
  282. {nltk-3.2 → nltk-3.3}/nltk/test/segmentation_fixt.py +10 -10
  283. {nltk-3.2 → nltk-3.3}/nltk/test/semantics.doctest +665 -665
  284. {nltk-3.2 → nltk-3.3}/nltk/test/semantics_fixt.py +7 -7
  285. {nltk-3.2 → nltk-3.3}/nltk/test/sentiment.doctest +233 -233
  286. {nltk-3.2 → nltk-3.3}/nltk/test/sentiwordnet.doctest +41 -41
  287. {nltk-3.2 → nltk-3.3}/nltk/test/simple.doctest +85 -85
  288. {nltk-3.2 → nltk-3.3}/nltk/test/stem.doctest +78 -78
  289. {nltk-3.2 → nltk-3.3}/nltk/test/tag.doctest +33 -33
  290. {nltk-3.2 → nltk-3.3}/nltk/test/tokenize.doctest +273 -166
  291. {nltk-3.2 → nltk-3.3}/nltk/test/toolbox.doctest +307 -307
  292. {nltk-3.2 → nltk-3.3}/nltk/test/translate.doctest +242 -242
  293. {nltk-3.2 → nltk-3.3}/nltk/test/translate_fixt.py +3 -3
  294. {nltk-3.2 → nltk-3.3}/nltk/test/tree.doctest +1101 -1101
  295. {nltk-3.2 → nltk-3.3}/nltk/test/treeprettyprinter.doctest +127 -127
  296. {nltk-3.2 → nltk-3.3}/nltk/test/treetransforms.doctest +156 -156
  297. nltk-3.3/nltk/test/unit/test_2x_compat.py +63 -0
  298. nltk-3.3/nltk/test/unit/test_aline.py +52 -0
  299. nltk-3.3/nltk/test/unit/test_chunk.py +56 -0
  300. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_classify.py +55 -53
  301. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_collocations.py +88 -79
  302. nltk-3.3/nltk/test/unit/test_concordance.py +98 -0
  303. nltk-3.3/nltk/test/unit/test_corenlp.py +1000 -0
  304. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpora.py +200 -183
  305. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpus_views.py +45 -45
  306. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_hmm.py +88 -88
  307. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_json2csv_corpus.py +188 -187
  308. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_naivebayes.py +26 -26
  309. nltk-3.3/nltk/test/unit/test_rte_classify.py +86 -0
  310. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_seekable_unicode_stream_reader.py +124 -124
  311. nltk-3.3/nltk/test/unit/test_senna.py +74 -0
  312. nltk-3.3/nltk/test/unit/test_stem.py +121 -0
  313. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tag.py +20 -20
  314. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tgrep.py +628 -626
  315. nltk-3.3/nltk/test/unit/test_tokenize.py +168 -0
  316. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_twitter_auth.py +185 -185
  317. nltk-3.3/nltk/test/unit/test_wordnet.py +134 -0
  318. nltk-3.3/nltk/test/unit/translate/test_bleu.py +244 -0
  319. nltk-3.3/nltk/test/unit/translate/test_gdfa.py +57 -0
  320. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm1.py +75 -75
  321. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm2.py +87 -87
  322. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm3.py +105 -105
  323. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm4.py +126 -126
  324. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm5.py +166 -166
  325. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm_model.py +270 -270
  326. nltk-3.3/nltk/test/unit/translate/test_nist.py +37 -0
  327. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_stack_decoder.py +300 -300
  328. {nltk-3.2 → nltk-3.3}/nltk/test/unit/utils.py +41 -41
  329. {nltk-3.2 → nltk-3.3}/nltk/test/util.doctest +48 -48
  330. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet.doctest +595 -581
  331. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_fixt.py +7 -6
  332. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_lch.doctest +53 -53
  333. {nltk-3.2 → nltk-3.3}/nltk/test/wsd.doctest +68 -68
  334. {nltk-3.2 → nltk-3.3}/nltk/text.py +663 -610
  335. {nltk-3.2 → nltk-3.3}/nltk/tgrep.py +938 -937
  336. {nltk-3.2 → nltk-3.3}/nltk/tokenize/__init__.py +130 -107
  337. {nltk-3.2 → nltk-3.3}/nltk/tokenize/api.py +77 -78
  338. {nltk-3.2 → nltk-3.3}/nltk/tokenize/casual.py +343 -342
  339. {nltk-3.2 → nltk-3.3}/nltk/tokenize/mwe.py +120 -120
  340. nltk-3.3/nltk/tokenize/nist.py +173 -0
  341. {nltk-3.2 → nltk-3.3}/nltk/tokenize/punkt.py +1620 -1601
  342. {nltk-3.2 → nltk-3.3}/nltk/tokenize/regexp.py +208 -202
  343. nltk-3.3/nltk/tokenize/repp.py +151 -0
  344. {nltk-3.2 → nltk-3.3}/nltk/tokenize/sexpr.py +140 -142
  345. {nltk-3.2 → nltk-3.3}/nltk/tokenize/simple.py +138 -136
  346. {nltk-3.2 → nltk-3.3}/nltk/tokenize/stanford.py +117 -113
  347. nltk-3.3/nltk/tokenize/stanford_segmenter.py +246 -0
  348. {nltk-3.2 → nltk-3.3}/nltk/tokenize/texttiling.py +458 -460
  349. nltk-3.3/nltk/tokenize/toktok.py +155 -0
  350. nltk-3.3/nltk/tokenize/treebank.py +363 -0
  351. nltk-3.3/nltk/tokenize/util.py +261 -0
  352. {nltk-3.2 → nltk-3.3}/nltk/toolbox.py +499 -497
  353. {nltk-3.2 → nltk-3.3}/nltk/translate/__init__.py +24 -24
  354. {nltk-3.2 → nltk-3.3}/nltk/translate/api.py +331 -321
  355. {nltk-3.2 → nltk-3.3}/nltk/translate/bleu_score.py +615 -556
  356. nltk-3.3/nltk/translate/chrf_score.py +137 -0
  357. {nltk-3.2 → nltk-3.3}/nltk/translate/gale_church.py +248 -235
  358. {nltk-3.2 → nltk-3.3}/nltk/translate/gdfa.py +135 -131
  359. nltk-3.3/nltk/translate/gleu_score.py +193 -0
  360. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm1.py +250 -241
  361. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm2.py +308 -308
  362. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm3.py +337 -337
  363. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm4.py +467 -467
  364. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm5.py +639 -639
  365. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm_model.py +536 -533
  366. {nltk-3.2 → nltk-3.3}/nltk/translate/metrics.py +40 -40
  367. nltk-3.3/nltk/translate/nist_score.py +178 -0
  368. {nltk-3.2 → nltk-3.3}/nltk/translate/phrase_based.py +175 -175
  369. {nltk-3.2 → nltk-3.3}/nltk/translate/ribes_score.py +325 -325
  370. {nltk-3.2 → nltk-3.3}/nltk/translate/stack_decoder.py +499 -495
  371. {nltk-3.2 → nltk-3.3}/nltk/tree.py +1605 -1603
  372. {nltk-3.2 → nltk-3.3}/nltk/treeprettyprinter.py +564 -564
  373. {nltk-3.2 → nltk-3.3}/nltk/treetransforms.py +309 -309
  374. {nltk-3.2 → nltk-3.3}/nltk/twitter/__init__.py +28 -28
  375. {nltk-3.2 → nltk-3.3}/nltk/twitter/api.py +141 -136
  376. {nltk-3.2 → nltk-3.3}/nltk/twitter/common.py +264 -258
  377. {nltk-3.2 → nltk-3.3}/nltk/twitter/twitter_demo.py +288 -288
  378. {nltk-3.2 → nltk-3.3}/nltk/twitter/twitterclient.py +530 -530
  379. {nltk-3.2 → nltk-3.3}/nltk/twitter/util.py +147 -146
  380. nltk-3.3/nltk/util.py +751 -0
  381. {nltk-3.2 → nltk-3.3}/nltk/wsd.py +53 -53
  382. {nltk-3.2 → nltk-3.3/nltk.egg-info}/PKG-INFO +13 -5
  383. {nltk-3.2 → nltk-3.3}/nltk.egg-info/SOURCES.txt +26 -3
  384. nltk-3.3/nltk.egg-info/requires.txt +31 -0
  385. {nltk-3.2 → nltk-3.3}/setup.cfg +0 -1
  386. {nltk-3.2 → nltk-3.3}/setup.py +102 -75
  387. nltk-3.2/nltk/VERSION +0 -1
  388. nltk-3.2/nltk/compat.py +0 -680
  389. nltk-3.2/nltk/corpus/reader/pl196x.py +0 -278
  390. nltk-3.2/nltk/corpus/reader/verbnet.py +0 -408
  391. nltk-3.2/nltk/corpus/reader/wordlist.py +0 -37
  392. nltk-3.2/nltk/sentiment/vader_lexicon.txt +0 -7517
  393. nltk-3.2/nltk/six.py +0 -868
  394. nltk-3.2/nltk/stem/porter.py +0 -692
  395. nltk-3.2/nltk/test/unit/test_2x_compat.py +0 -26
  396. nltk-3.2/nltk/test/unit/test_stem.py +0 -36
  397. nltk-3.2/nltk/test/unit/test_tokenize.py +0 -23
  398. nltk-3.2/nltk/test/unit/translate/test_bleu.py +0 -84
  399. nltk-3.2/nltk/tokenize/treebank.py +0 -124
  400. nltk-3.2/nltk/tokenize/util.py +0 -90
  401. nltk-3.2/nltk/util.py +0 -1364
  402. {nltk-3.2 → nltk-3.3}/nltk/test/unit/__init__.py +0 -0
  403. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/__init__.py +0 -0
  404. {nltk-3.2 → nltk-3.3}/nltk.egg-info/dependency_links.txt +0 -0
  405. {nltk-3.2 → nltk-3.3}/nltk.egg-info/not-zip-safe +0 -0
  406. {nltk-3.2 → nltk-3.3}/nltk.egg-info/top_level.txt +0 -0
@@ -1,381 +1,381 @@
1
- # Natural Language Toolkit: Agreement Metrics
2
- #
3
- # Copyright (C) 2001-2015 NLTK Project
4
- # Author: Lauri Hallila <laurihallila@gmail.com>
5
- # URL: <http://nltk.org/>
6
- # For license information, see LICENSE.TXT
7
- #
8
-
9
- """Counts Paice's performance statistics for evaluating stemming algorithms.
10
-
11
- What is required:
12
- - A dictionary of words grouped by their real lemmas
13
- - A dictionary of words grouped by stems from a stemming algorithm
14
-
15
- When these are given, Understemming Index (UI), Overstemming Index (OI),
16
- Stemming Weight (SW) and Error-rate relative to truncation (ERRT) are counted.
17
-
18
- References:
19
- Chris D. Paice (1994). An evaluation method for stemming algorithms.
20
- In Proceedings of SIGIR, 42--50.
21
- """
22
-
23
- from math import sqrt
24
-
25
-
26
- def get_words_from_dictionary(lemmas):
27
- '''
28
- Get original set of words used for analysis.
29
-
30
- :param lemmas: A dictionary where keys are lemmas and values are sets
31
- or lists of words corresponding to that lemma.
32
- :type lemmas: dict(str): list(str)
33
- :return: Set of words that exist as values in the dictionary
34
- :rtype: set(str)
35
- '''
36
- words = set()
37
- for lemma in lemmas:
38
- words.update(set(lemmas[lemma]))
39
- return words
40
-
41
-
42
- def _truncate(words, cutlength):
43
- '''Group words by stems defined by truncating them at given length.
44
-
45
- :param words: Set of words used for analysis
46
- :param cutlength: Words are stemmed by cutting at this length.
47
- :type words: set(str) or list(str)
48
- :type cutlength: int
49
- :return: Dictionary where keys are stems and values are sets of words
50
- corresponding to that stem.
51
- :rtype: dict(str): set(str)
52
- '''
53
- stems = {}
54
- for word in words:
55
- stem = word[:cutlength]
56
- try:
57
- stems[stem].update([word])
58
- except KeyError:
59
- stems[stem] = set([word])
60
- return stems
61
-
62
-
63
- # Reference: http://en.wikipedia.org/wiki/Line-line_intersection
64
- def _count_intersection(l1, l2):
65
- '''Count intersection between two line segments defined by coordinate pairs.
66
-
67
- :param l1: Tuple of two coordinate pairs defining the first line segment
68
- :param l2: Tuple of two coordinate pairs defining the second line segment
69
- :type l1: tuple(float, float)
70
- :type l2: tuple(float, float)
71
- :return: Coordinates of the intersection
72
- :rtype: tuple(float, float)
73
- '''
74
- x1, y1 = l1[0]
75
- x2, y2 = l1[1]
76
- x3, y3 = l2[0]
77
- x4, y4 = l2[1]
78
-
79
- denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
80
-
81
- if denominator == 0.0: # lines are parallel
82
- if x1 == x2 == x3 == x4 == 0.0:
83
- # When lines are parallel, they must be on the y-axis.
84
- # We can ignore x-axis because we stop counting the
85
- # truncation line when we get there.
86
- # There are no other options as UI (x-axis) grows and
87
- # OI (y-axis) diminishes when we go along the truncation line.
88
- return (0.0, y4)
89
-
90
- x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator
91
- y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator
92
- return (x, y)
93
-
94
-
95
- def _get_derivative(coordinates):
96
- '''Get derivative of the line from (0,0) to given coordinates.
97
-
98
- :param coordinates: A coordinate pair
99
- :type coordinates: tuple(float, float)
100
- :return: Derivative; inf if x is zero
101
- :rtype: float
102
- '''
103
- try:
104
- return coordinates[1] / coordinates[0]
105
- except ZeroDivisionError:
106
- return float('inf')
107
-
108
-
109
- def _calculate_cut(lemmawords, stems):
110
- '''Count understemmed and overstemmed pairs for (lemma, stem) pair with common words.
111
-
112
- :param lemmawords: Set or list of words corresponding to certain lemma.
113
- :param stems: A dictionary where keys are stems and values are sets
114
- or lists of words corresponding to that stem.
115
- :type lemmawords: set(str) or list(str)
116
- :type stems: dict(str): set(str)
117
- :return: Amount of understemmed and overstemmed pairs contributed by words
118
- existing in both lemmawords and stems.
119
- :rtype: tuple(float, float)
120
- '''
121
- umt, wmt = 0.0, 0.0
122
- for stem in stems:
123
- cut = set(lemmawords) & set(stems[stem])
124
- if cut:
125
- cutcount = len(cut)
126
- stemcount = len(stems[stem])
127
- # Unachieved merge total
128
- umt += cutcount * (len(lemmawords) - cutcount)
129
- # Wrongly merged total
130
- wmt += cutcount * (stemcount - cutcount)
131
- return (umt, wmt)
132
-
133
-
134
- def _calculate(lemmas, stems):
135
- '''Calculate actual and maximum possible amounts of understemmed and overstemmed word pairs.
136
-
137
- :param lemmas: A dictionary where keys are lemmas and values are sets
138
- or lists of words corresponding to that lemma.
139
- :param stems: A dictionary where keys are stems and values are sets
140
- or lists of words corresponding to that stem.
141
- :type lemmas: dict(str): list(str)
142
- :type stems: dict(str): set(str)
143
- :return: Global unachieved merge total (gumt),
144
- global desired merge total (gdmt),
145
- global wrongly merged total (gwmt) and
146
- global desired non-merge total (gdnt).
147
- :rtype: tuple(float, float, float, float)
148
- '''
149
-
150
- n = sum(len(lemmas[word]) for word in lemmas)
151
-
152
- gdmt, gdnt, gumt, gwmt = (0.0, 0.0, 0.0, 0.0)
153
-
154
- for lemma in lemmas:
155
- lemmacount = len(lemmas[lemma])
156
-
157
- # Desired merge total
158
- gdmt += lemmacount * (lemmacount - 1)
159
-
160
- # Desired non-merge total
161
- gdnt += lemmacount * (n - lemmacount)
162
-
163
- # For each (lemma, stem) pair with common words, count how many
164
- # pairs are understemmed and overstemmed.
165
- umt, wmt = _calculate_cut(lemmas[lemma], stems)
166
-
167
- # Add to total undesired and wrongly-merged totals
168
- gumt += umt
169
- gwmt += wmt
170
-
171
- # Each object is counted twice, so divide by two
172
- return (gumt / 2, gdmt / 2, gwmt / 2, gdnt / 2)
173
-
174
-
175
- def _indexes(gumt, gdmt, gwmt, gdnt):
176
- '''Count Understemming Index (UI), Overstemming Index (OI) and Stemming Weight (SW).
177
-
178
- :param gumt, gdmt, gwmt, gdnt: Global unachieved merge total (gumt),
179
- global desired merge total (gdmt),
180
- global wrongly merged total (gwmt) and
181
- global desired non-merge total (gdnt).
182
- :type gumt, gdmt, gwmt, gdnt: float
183
- :return: Understemming Index (UI),
184
- Overstemming Index (OI) and
185
- Stemming Weight (SW).
186
- :rtype: tuple(float, float, float)
187
- '''
188
- # Calculate Understemming Index (UI),
189
- # Overstemming Index (OI) and Stemming Weight (SW)
190
- try:
191
- ui = gumt / gdmt
192
- except ZeroDivisionError:
193
- # If GDMT (max merge total) is 0, define UI as 0
194
- ui = 0.0
195
- try:
196
- oi = gwmt / gdnt
197
- except ZeroDivisionError:
198
- # IF GDNT (max non-merge total) is 0, define OI as 0
199
- oi = 0.0
200
- try:
201
- sw = oi / ui
202
- except ZeroDivisionError:
203
- if oi == 0.0:
204
- # OI and UI are 0, define SW as 'not a number'
205
- sw = float('nan')
206
- else:
207
- # UI is 0, define SW as infinity
208
- sw = float('inf')
209
- return (ui, oi, sw)
210
-
211
-
212
- class Paice(object):
213
- '''Class for storing lemmas, stems and evaluation metrics.'''
214
- def __init__(self, lemmas, stems):
215
- '''
216
- :param lemmas: A dictionary where keys are lemmas and values are sets
217
- or lists of words corresponding to that lemma.
218
- :param stems: A dictionary where keys are stems and values are sets
219
- or lists of words corresponding to that stem.
220
- :type lemmas: dict(str): list(str)
221
- :type stems: dict(str): set(str)
222
- '''
223
- self.lemmas = lemmas
224
- self.stems = stems
225
- self.coords = []
226
- self.gumt, self.gdmt, self.gwmt, self.gdnt = (None, None, None, None)
227
- self.ui, self.oi, self.sw = (None, None, None)
228
- self.errt = None
229
- self.update()
230
-
231
- def __str__(self):
232
- text = ['Global Unachieved Merge Total (GUMT): %s\n' % self.gumt]
233
- text.append('Global Desired Merge Total (GDMT): %s\n' % self.gdmt)
234
- text.append('Global Wrongly-Merged Total (GWMT): %s\n' % self.gwmt)
235
- text.append('Global Desired Non-merge Total (GDNT): %s\n' % self.gdnt)
236
- text.append('Understemming Index (GUMT / GDMT): %s\n' % self.ui)
237
- text.append('Overstemming Index (GWMT / GDNT): %s\n' % self.oi)
238
- text.append('Stemming Weight (OI / UI): %s\n' % self.sw)
239
- text.append('Error-Rate Relative to Truncation (ERRT): %s\r\n' % self.errt)
240
- coordinates = ' '.join(['(%s, %s)' % item for item in self.coords])
241
- text.append('Truncation line: %s' % coordinates)
242
- return ''.join(text)
243
-
244
- def _get_truncation_indexes(self, words, cutlength):
245
- '''Count (UI, OI) when stemming is done by truncating words at \'cutlength\'.
246
-
247
- :param words: Words used for the analysis
248
- :param cutlength: Words are stemmed by cutting them at this length
249
- :type words: set(str) or list(str)
250
- :type cutlength: int
251
- :return: Understemming and overstemming indexes
252
- :rtype: tuple(int, int)
253
- '''
254
-
255
- truncated = _truncate(words, cutlength)
256
- gumt, gdmt, gwmt, gdnt = _calculate(self.lemmas, truncated)
257
- ui, oi = _indexes(gumt, gdmt, gwmt, gdnt)[:2]
258
- return (ui, oi)
259
-
260
- def _get_truncation_coordinates(self, cutlength=0):
261
- '''Count (UI, OI) pairs for truncation points until we find the segment where (ui, oi) crosses the truncation line.
262
-
263
- :param cutlength: Optional parameter to start counting from (ui, oi)
264
- coordinates gotten by stemming at this length. Useful for speeding up
265
- the calculations when you know the approximate location of the
266
- intersection.
267
- :type cutlength: int
268
- :return: List of coordinate pairs that define the truncation line
269
- :rtype: list(tuple(float, float))
270
- '''
271
- words = get_words_from_dictionary(self.lemmas)
272
- maxlength = max(len(word) for word in words)
273
-
274
- # Truncate words from different points until (0, 0) - (ui, oi) segment crosses the truncation line
275
- coords = []
276
- while cutlength <= maxlength:
277
- # Get (UI, OI) pair of current truncation point
278
- pair = self._get_truncation_indexes(words, cutlength)
279
-
280
- # Store only new coordinates so we'll have an actual
281
- # line segment when counting the intersection point
282
- if pair not in coords:
283
- coords.append(pair)
284
- if pair == (0.0, 0.0):
285
- # Stop counting if truncation line goes through origo;
286
- # length from origo to truncation line is 0
287
- return coords
288
- if len(coords) >= 2 and pair[0] > 0.0:
289
- derivative1 = _get_derivative(coords[-2])
290
- derivative2 = _get_derivative(coords[-1])
291
- # Derivative of the truncation line is a decreasing value;
292
- # when it passes Stemming Weight, we've found the segment
293
- # of truncation line intersecting with (0, 0) - (ui, oi) segment
294
- if derivative1 >= self.sw >= derivative2:
295
- return coords
296
- cutlength += 1
297
- return coords
298
-
299
- def _errt(self):
300
- '''Count Error-Rate Relative to Truncation (ERRT).
301
-
302
- :return: ERRT, length of the line from origo to (UI, OI) divided by
303
- the length of the line from origo to the point defined by the same
304
- line when extended until the truncation line.
305
- :rtype: float
306
- '''
307
- # Count (UI, OI) pairs for truncation points until we find the segment where (ui, oi) crosses the truncation line
308
- self.coords = self._get_truncation_coordinates()
309
- if (0.0, 0.0) in self.coords:
310
- # Truncation line goes through origo, so ERRT cannot be counted
311
- if (self.ui, self.oi) != (0.0, 0.0):
312
- return float('inf')
313
- else:
314
- return float('nan')
315
- if (self.ui, self.oi) == (0.0, 0.0):
316
- # (ui, oi) is origo; define errt as 0.0
317
- return 0.0
318
- # Count the intersection point
319
- # Note that (self.ui, self.oi) cannot be (0.0, 0.0) and self.coords has different coordinates
320
- # so we have actual line segments instead of a line segment and a point
321
- intersection = _count_intersection(((0, 0), (self.ui, self.oi)),
322
- self.coords[-2:]
323
- )
324
- # Count OP (length of the line from origo to (ui, oi))
325
- op = sqrt(self.ui ** 2 + self.oi ** 2)
326
- # Count OT (length of the line from origo to truncation line that goes through (ui, oi))
327
- ot = sqrt(intersection[0] ** 2 + intersection[1] ** 2)
328
- # OP / OT tells how well the stemming algorithm works compared to just truncating words
329
- return op / ot
330
-
331
- def update(self):
332
- '''Update statistics after lemmas and stems have been set.'''
333
- self.gumt, self.gdmt, self.gwmt, self.gdnt = _calculate(self.lemmas, self.stems)
334
- self.ui, self.oi, self.sw = _indexes(self.gumt, self.gdmt, self.gwmt, self.gdnt)
335
- self.errt = self._errt()
336
-
337
-
338
- def demo():
339
- '''Demonstration of the module.'''
340
- # Some words with their real lemmas
341
- lemmas = {'kneel': ['kneel', 'knelt'],
342
- 'range': ['range', 'ranged'],
343
- 'ring': ['ring', 'rang', 'rung']
344
- }
345
- # Same words with stems from a stemming algorithm
346
- stems = {'kneel': ['kneel'],
347
- 'knelt': ['knelt'],
348
- 'rang': ['rang', 'range', 'ranged'],
349
- 'ring': ['ring'],
350
- 'rung': ['rung']
351
- }
352
- print('Words grouped by their lemmas:')
353
- for lemma in sorted(lemmas):
354
- print('%s => %s' % (lemma, ' '.join(lemmas[lemma])))
355
- print()
356
- print('Same words grouped by a stemming algorithm:')
357
- for stem in sorted(stems):
358
- print('%s => %s' % (stem, ' '.join(stems[stem])))
359
- print()
360
- p = Paice(lemmas, stems)
361
- print(p)
362
- print()
363
- # Let's "change" results from a stemming algorithm
364
- stems = {'kneel': ['kneel'],
365
- 'knelt': ['knelt'],
366
- 'rang': ['rang'],
367
- 'range': ['range', 'ranged'],
368
- 'ring': ['ring'],
369
- 'rung': ['rung']
370
- }
371
- print('Counting stats after changing stemming results:')
372
- for stem in sorted(stems):
373
- print('%s => %s' % (stem, ' '.join(stems[stem])))
374
- print()
375
- p.stems = stems
376
- p.update()
377
- print(p)
378
-
379
-
380
- if __name__ == '__main__':
381
- demo()
1
+ # Natural Language Toolkit: Agreement Metrics
2
+ #
3
+ # Copyright (C) 2001-2018 NLTK Project
4
+ # Author: Lauri Hallila <laurihallila@gmail.com>
5
+ # URL: <http://nltk.org/>
6
+ # For license information, see LICENSE.TXT
7
+ #
8
+
9
+ """Counts Paice's performance statistics for evaluating stemming algorithms.
10
+
11
+ What is required:
12
+ - A dictionary of words grouped by their real lemmas
13
+ - A dictionary of words grouped by stems from a stemming algorithm
14
+
15
+ When these are given, Understemming Index (UI), Overstemming Index (OI),
16
+ Stemming Weight (SW) and Error-rate relative to truncation (ERRT) are counted.
17
+
18
+ References:
19
+ Chris D. Paice (1994). An evaluation method for stemming algorithms.
20
+ In Proceedings of SIGIR, 42--50.
21
+ """
22
+
23
+ from math import sqrt
24
+
25
+
26
+ def get_words_from_dictionary(lemmas):
27
+ '''
28
+ Get original set of words used for analysis.
29
+
30
+ :param lemmas: A dictionary where keys are lemmas and values are sets
31
+ or lists of words corresponding to that lemma.
32
+ :type lemmas: dict(str): list(str)
33
+ :return: Set of words that exist as values in the dictionary
34
+ :rtype: set(str)
35
+ '''
36
+ words = set()
37
+ for lemma in lemmas:
38
+ words.update(set(lemmas[lemma]))
39
+ return words
40
+
41
+
42
+ def _truncate(words, cutlength):
43
+ '''Group words by stems defined by truncating them at given length.
44
+
45
+ :param words: Set of words used for analysis
46
+ :param cutlength: Words are stemmed by cutting at this length.
47
+ :type words: set(str) or list(str)
48
+ :type cutlength: int
49
+ :return: Dictionary where keys are stems and values are sets of words
50
+ corresponding to that stem.
51
+ :rtype: dict(str): set(str)
52
+ '''
53
+ stems = {}
54
+ for word in words:
55
+ stem = word[:cutlength]
56
+ try:
57
+ stems[stem].update([word])
58
+ except KeyError:
59
+ stems[stem] = set([word])
60
+ return stems
61
+
62
+
63
+ # Reference: http://en.wikipedia.org/wiki/Line-line_intersection
64
+ def _count_intersection(l1, l2):
65
+ '''Count intersection between two line segments defined by coordinate pairs.
66
+
67
+ :param l1: Tuple of two coordinate pairs defining the first line segment
68
+ :param l2: Tuple of two coordinate pairs defining the second line segment
69
+ :type l1: tuple(float, float)
70
+ :type l2: tuple(float, float)
71
+ :return: Coordinates of the intersection
72
+ :rtype: tuple(float, float)
73
+ '''
74
+ x1, y1 = l1[0]
75
+ x2, y2 = l1[1]
76
+ x3, y3 = l2[0]
77
+ x4, y4 = l2[1]
78
+
79
+ denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
80
+
81
+ if denominator == 0.0: # lines are parallel
82
+ if x1 == x2 == x3 == x4 == 0.0:
83
+ # When lines are parallel, they must be on the y-axis.
84
+ # We can ignore x-axis because we stop counting the
85
+ # truncation line when we get there.
86
+ # There are no other options as UI (x-axis) grows and
87
+ # OI (y-axis) diminishes when we go along the truncation line.
88
+ return (0.0, y4)
89
+
90
+ x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator
91
+ y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator
92
+ return (x, y)
93
+
94
+
95
+ def _get_derivative(coordinates):
96
+ '''Get derivative of the line from (0,0) to given coordinates.
97
+
98
+ :param coordinates: A coordinate pair
99
+ :type coordinates: tuple(float, float)
100
+ :return: Derivative; inf if x is zero
101
+ :rtype: float
102
+ '''
103
+ try:
104
+ return coordinates[1] / coordinates[0]
105
+ except ZeroDivisionError:
106
+ return float('inf')
107
+
108
+
109
+ def _calculate_cut(lemmawords, stems):
110
+ '''Count understemmed and overstemmed pairs for (lemma, stem) pair with common words.
111
+
112
+ :param lemmawords: Set or list of words corresponding to certain lemma.
113
+ :param stems: A dictionary where keys are stems and values are sets
114
+ or lists of words corresponding to that stem.
115
+ :type lemmawords: set(str) or list(str)
116
+ :type stems: dict(str): set(str)
117
+ :return: Amount of understemmed and overstemmed pairs contributed by words
118
+ existing in both lemmawords and stems.
119
+ :rtype: tuple(float, float)
120
+ '''
121
+ umt, wmt = 0.0, 0.0
122
+ for stem in stems:
123
+ cut = set(lemmawords) & set(stems[stem])
124
+ if cut:
125
+ cutcount = len(cut)
126
+ stemcount = len(stems[stem])
127
+ # Unachieved merge total
128
+ umt += cutcount * (len(lemmawords) - cutcount)
129
+ # Wrongly merged total
130
+ wmt += cutcount * (stemcount - cutcount)
131
+ return (umt, wmt)
132
+
133
+
134
+ def _calculate(lemmas, stems):
135
+ '''Calculate actual and maximum possible amounts of understemmed and overstemmed word pairs.
136
+
137
+ :param lemmas: A dictionary where keys are lemmas and values are sets
138
+ or lists of words corresponding to that lemma.
139
+ :param stems: A dictionary where keys are stems and values are sets
140
+ or lists of words corresponding to that stem.
141
+ :type lemmas: dict(str): list(str)
142
+ :type stems: dict(str): set(str)
143
+ :return: Global unachieved merge total (gumt),
144
+ global desired merge total (gdmt),
145
+ global wrongly merged total (gwmt) and
146
+ global desired non-merge total (gdnt).
147
+ :rtype: tuple(float, float, float, float)
148
+ '''
149
+
150
+ n = sum(len(lemmas[word]) for word in lemmas)
151
+
152
+ gdmt, gdnt, gumt, gwmt = (0.0, 0.0, 0.0, 0.0)
153
+
154
+ for lemma in lemmas:
155
+ lemmacount = len(lemmas[lemma])
156
+
157
+ # Desired merge total
158
+ gdmt += lemmacount * (lemmacount - 1)
159
+
160
+ # Desired non-merge total
161
+ gdnt += lemmacount * (n - lemmacount)
162
+
163
+ # For each (lemma, stem) pair with common words, count how many
164
+ # pairs are understemmed and overstemmed.
165
+ umt, wmt = _calculate_cut(lemmas[lemma], stems)
166
+
167
+ # Add to total undesired and wrongly-merged totals
168
+ gumt += umt
169
+ gwmt += wmt
170
+
171
+ # Each object is counted twice, so divide by two
172
+ return (gumt / 2, gdmt / 2, gwmt / 2, gdnt / 2)
173
+
174
+
175
+ def _indexes(gumt, gdmt, gwmt, gdnt):
176
+ '''Count Understemming Index (UI), Overstemming Index (OI) and Stemming Weight (SW).
177
+
178
+ :param gumt, gdmt, gwmt, gdnt: Global unachieved merge total (gumt),
179
+ global desired merge total (gdmt),
180
+ global wrongly merged total (gwmt) and
181
+ global desired non-merge total (gdnt).
182
+ :type gumt, gdmt, gwmt, gdnt: float
183
+ :return: Understemming Index (UI),
184
+ Overstemming Index (OI) and
185
+ Stemming Weight (SW).
186
+ :rtype: tuple(float, float, float)
187
+ '''
188
+ # Calculate Understemming Index (UI),
189
+ # Overstemming Index (OI) and Stemming Weight (SW)
190
+ try:
191
+ ui = gumt / gdmt
192
+ except ZeroDivisionError:
193
+ # If GDMT (max merge total) is 0, define UI as 0
194
+ ui = 0.0
195
+ try:
196
+ oi = gwmt / gdnt
197
+ except ZeroDivisionError:
198
+ # IF GDNT (max non-merge total) is 0, define OI as 0
199
+ oi = 0.0
200
+ try:
201
+ sw = oi / ui
202
+ except ZeroDivisionError:
203
+ if oi == 0.0:
204
+ # OI and UI are 0, define SW as 'not a number'
205
+ sw = float('nan')
206
+ else:
207
+ # UI is 0, define SW as infinity
208
+ sw = float('inf')
209
+ return (ui, oi, sw)
210
+
211
+
212
+ class Paice(object):
213
+ '''Class for storing lemmas, stems and evaluation metrics.'''
214
+ def __init__(self, lemmas, stems):
215
+ '''
216
+ :param lemmas: A dictionary where keys are lemmas and values are sets
217
+ or lists of words corresponding to that lemma.
218
+ :param stems: A dictionary where keys are stems and values are sets
219
+ or lists of words corresponding to that stem.
220
+ :type lemmas: dict(str): list(str)
221
+ :type stems: dict(str): set(str)
222
+ '''
223
+ self.lemmas = lemmas
224
+ self.stems = stems
225
+ self.coords = []
226
+ self.gumt, self.gdmt, self.gwmt, self.gdnt = (None, None, None, None)
227
+ self.ui, self.oi, self.sw = (None, None, None)
228
+ self.errt = None
229
+ self.update()
230
+
231
+ def __str__(self):
232
+ text = ['Global Unachieved Merge Total (GUMT): %s\n' % self.gumt]
233
+ text.append('Global Desired Merge Total (GDMT): %s\n' % self.gdmt)
234
+ text.append('Global Wrongly-Merged Total (GWMT): %s\n' % self.gwmt)
235
+ text.append('Global Desired Non-merge Total (GDNT): %s\n' % self.gdnt)
236
+ text.append('Understemming Index (GUMT / GDMT): %s\n' % self.ui)
237
+ text.append('Overstemming Index (GWMT / GDNT): %s\n' % self.oi)
238
+ text.append('Stemming Weight (OI / UI): %s\n' % self.sw)
239
+ text.append('Error-Rate Relative to Truncation (ERRT): %s\r\n' % self.errt)
240
+ coordinates = ' '.join(['(%s, %s)' % item for item in self.coords])
241
+ text.append('Truncation line: %s' % coordinates)
242
+ return ''.join(text)
243
+
244
+ def _get_truncation_indexes(self, words, cutlength):
245
+ '''Count (UI, OI) when stemming is done by truncating words at \'cutlength\'.
246
+
247
+ :param words: Words used for the analysis
248
+ :param cutlength: Words are stemmed by cutting them at this length
249
+ :type words: set(str) or list(str)
250
+ :type cutlength: int
251
+ :return: Understemming and overstemming indexes
252
+ :rtype: tuple(int, int)
253
+ '''
254
+
255
+ truncated = _truncate(words, cutlength)
256
+ gumt, gdmt, gwmt, gdnt = _calculate(self.lemmas, truncated)
257
+ ui, oi = _indexes(gumt, gdmt, gwmt, gdnt)[:2]
258
+ return (ui, oi)
259
+
260
+ def _get_truncation_coordinates(self, cutlength=0):
261
+ '''Count (UI, OI) pairs for truncation points until we find the segment where (ui, oi) crosses the truncation line.
262
+
263
+ :param cutlength: Optional parameter to start counting from (ui, oi)
264
+ coordinates gotten by stemming at this length. Useful for speeding up
265
+ the calculations when you know the approximate location of the
266
+ intersection.
267
+ :type cutlength: int
268
+ :return: List of coordinate pairs that define the truncation line
269
+ :rtype: list(tuple(float, float))
270
+ '''
271
+ words = get_words_from_dictionary(self.lemmas)
272
+ maxlength = max(len(word) for word in words)
273
+
274
+ # Truncate words from different points until (0, 0) - (ui, oi) segment crosses the truncation line
275
+ coords = []
276
+ while cutlength <= maxlength:
277
+ # Get (UI, OI) pair of current truncation point
278
+ pair = self._get_truncation_indexes(words, cutlength)
279
+
280
+ # Store only new coordinates so we'll have an actual
281
+ # line segment when counting the intersection point
282
+ if pair not in coords:
283
+ coords.append(pair)
284
+ if pair == (0.0, 0.0):
285
+ # Stop counting if truncation line goes through origo;
286
+ # length from origo to truncation line is 0
287
+ return coords
288
+ if len(coords) >= 2 and pair[0] > 0.0:
289
+ derivative1 = _get_derivative(coords[-2])
290
+ derivative2 = _get_derivative(coords[-1])
291
+ # Derivative of the truncation line is a decreasing value;
292
+ # when it passes Stemming Weight, we've found the segment
293
+ # of truncation line intersecting with (0, 0) - (ui, oi) segment
294
+ if derivative1 >= self.sw >= derivative2:
295
+ return coords
296
+ cutlength += 1
297
+ return coords
298
+
299
+ def _errt(self):
300
+ '''Count Error-Rate Relative to Truncation (ERRT).
301
+
302
+ :return: ERRT, length of the line from origo to (UI, OI) divided by
303
+ the length of the line from origo to the point defined by the same
304
+ line when extended until the truncation line.
305
+ :rtype: float
306
+ '''
307
+ # Count (UI, OI) pairs for truncation points until we find the segment where (ui, oi) crosses the truncation line
308
+ self.coords = self._get_truncation_coordinates()
309
+ if (0.0, 0.0) in self.coords:
310
+ # Truncation line goes through origo, so ERRT cannot be counted
311
+ if (self.ui, self.oi) != (0.0, 0.0):
312
+ return float('inf')
313
+ else:
314
+ return float('nan')
315
+ if (self.ui, self.oi) == (0.0, 0.0):
316
+ # (ui, oi) is origo; define errt as 0.0
317
+ return 0.0
318
+ # Count the intersection point
319
+ # Note that (self.ui, self.oi) cannot be (0.0, 0.0) and self.coords has different coordinates
320
+ # so we have actual line segments instead of a line segment and a point
321
+ intersection = _count_intersection(((0, 0), (self.ui, self.oi)),
322
+ self.coords[-2:]
323
+ )
324
+ # Count OP (length of the line from origo to (ui, oi))
325
+ op = sqrt(self.ui ** 2 + self.oi ** 2)
326
+ # Count OT (length of the line from origo to truncation line that goes through (ui, oi))
327
+ ot = sqrt(intersection[0] ** 2 + intersection[1] ** 2)
328
+ # OP / OT tells how well the stemming algorithm works compared to just truncating words
329
+ return op / ot
330
+
331
+ def update(self):
332
+ '''Update statistics after lemmas and stems have been set.'''
333
+ self.gumt, self.gdmt, self.gwmt, self.gdnt = _calculate(self.lemmas, self.stems)
334
+ self.ui, self.oi, self.sw = _indexes(self.gumt, self.gdmt, self.gwmt, self.gdnt)
335
+ self.errt = self._errt()
336
+
337
+
338
+ def demo():
339
+ '''Demonstration of the module.'''
340
+ # Some words with their real lemmas
341
+ lemmas = {'kneel': ['kneel', 'knelt'],
342
+ 'range': ['range', 'ranged'],
343
+ 'ring': ['ring', 'rang', 'rung']
344
+ }
345
+ # Same words with stems from a stemming algorithm
346
+ stems = {'kneel': ['kneel'],
347
+ 'knelt': ['knelt'],
348
+ 'rang': ['rang', 'range', 'ranged'],
349
+ 'ring': ['ring'],
350
+ 'rung': ['rung']
351
+ }
352
+ print('Words grouped by their lemmas:')
353
+ for lemma in sorted(lemmas):
354
+ print('%s => %s' % (lemma, ' '.join(lemmas[lemma])))
355
+ print()
356
+ print('Same words grouped by a stemming algorithm:')
357
+ for stem in sorted(stems):
358
+ print('%s => %s' % (stem, ' '.join(stems[stem])))
359
+ print()
360
+ p = Paice(lemmas, stems)
361
+ print(p)
362
+ print()
363
+ # Let's "change" results from a stemming algorithm
364
+ stems = {'kneel': ['kneel'],
365
+ 'knelt': ['knelt'],
366
+ 'rang': ['rang'],
367
+ 'range': ['range', 'ranged'],
368
+ 'ring': ['ring'],
369
+ 'rung': ['rung']
370
+ }
371
+ print('Counting stats after changing stemming results:')
372
+ for stem in sorted(stems):
373
+ print('%s => %s' % (stem, ' '.join(stems[stem])))
374
+ print()
375
+ p.stems = stems
376
+ p.update()
377
+ print(p)
378
+
379
+
380
+ if __name__ == '__main__':
381
+ demo()