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,556 +1,615 @@
1
- # -*- coding: utf-8 -*-
2
- # Natural Language Toolkit: BLEU Score
3
- #
4
- # Copyright (C) 2001-2015 NLTK Project
5
- # Authors: Chin Yee Lee, Hengfeng Li, Ruxin Hou, Calvin Tanujaya Lim
6
- # Contributors: Dmitrijs Milajevs, Liling Tan
7
- # URL: <http://nltk.org/>
8
- # For license information, see LICENSE.TXT
9
- """BLEU score implementation."""
10
- from __future__ import division
11
-
12
- import math
13
- from fractions import Fraction
14
- from collections import Counter
15
-
16
- from nltk.util import ngrams
17
-
18
-
19
- def sentence_bleu(references, hypothesis, weights=(0.25, 0.25, 0.25, 0.25),
20
- smoothing_function=None):
21
- """
22
- Calculate BLEU score (Bilingual Evaluation Understudy) from
23
- Papineni, Kishore, Salim Roukos, Todd Ward, and Wei-Jing Zhu. 2002.
24
- "BLEU: a method for automatic evaluation of machine translation."
25
- In Proceedings of ACL. http://www.aclweb.org/anthology/P02-1040.pdf
26
-
27
- >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
28
- ... 'ensures', 'that', 'the', 'military', 'always',
29
- ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
30
-
31
- >>> hypothesis2 = ['It', 'is', 'to', 'insure', 'the', 'troops',
32
- ... 'forever', 'hearing', 'the', 'activity', 'guidebook',
33
- ... 'that', 'party', 'direct']
34
-
35
- >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
36
- ... 'ensures', 'that', 'the', 'military', 'will', 'forever',
37
- ... 'heed', 'Party', 'commands']
38
-
39
- >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
40
- ... 'guarantees', 'the', 'military', 'forces', 'always',
41
- ... 'being', 'under', 'the', 'command', 'of', 'the',
42
- ... 'Party']
43
-
44
- >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
45
- ... 'army', 'always', 'to', 'heed', 'the', 'directions',
46
- ... 'of', 'the', 'party']
47
-
48
- >>> sentence_bleu([reference1, reference2, reference3], hypothesis1) # doctest: +ELLIPSIS
49
- 0.5045...
50
-
51
- >>> sentence_bleu([reference1, reference2, reference3], hypothesis2) # doctest: +ELLIPSIS
52
- 0.3969...
53
-
54
- The default BLEU calculates a score for up to 4grams using uniform
55
- weights. To evaluate your translations with higher/lower order ngrams,
56
- use customized weights. E.g. when accounting for up to 6grams with uniform
57
- weights:
58
-
59
- >>> weights = (0.1666, 0.1666, 0.1666, 0.1666, 0.1666)
60
- >>> sentence_bleu([reference1, reference2, reference3], hypothesis1, weights)
61
- 0.45838627164939455
62
-
63
- :param references: reference sentences
64
- :type references: list(list(str))
65
- :param hypothesis: a hypothesis sentence
66
- :type hypothesis: list(str)
67
- :param weights: weights for unigrams, bigrams, trigrams and so on
68
- :type weights: list(float)
69
- :return: The sentence-level BLEU score.
70
- :rtype: float
71
- """
72
- # Calculates the brevity penalty.
73
- # *hyp_len* is referred to as *c* in Papineni et. al. (2002)
74
- hyp_len = len(hypothesis)
75
- # *closest_ref_len* is referred to as *r* variable in Papineni et. al. (2002)
76
- closest_ref_len = _closest_ref_length(references, hyp_len)
77
- bp = _brevity_penalty(closest_ref_len, hyp_len)
78
-
79
- # Calculates the modified precision *p_n* for each order of ngram.
80
- p_n = [_modified_precision(references, hypothesis, i)
81
- for i, _ in enumerate(weights, start=1)]
82
-
83
- # Smoothen the modified precision.
84
- # Note: smooth_precision() converts values into float.
85
- if smoothing_function:
86
- p_n = smoothing_function(p_n, references=references,
87
- hypothesis=hypothesis, hyp_len=hyp_len)
88
-
89
- # Calculates the overall modified precision for all ngrams.
90
- # By sum of the product of the weights and the respective *p_n*
91
- s = (w * math.log(p_i) if p_i else 0
92
- for w, p_i in zip(weights, p_n))
93
- sum_s = math.fsum(s)
94
- if sum_s == 0 and all(p_n) == 0:
95
- return 0
96
- return bp * math.exp(sum_s)
97
-
98
-
99
- def corpus_bleu(list_of_references, hypotheses, weights=(0.25, 0.25, 0.25, 0.25),
100
- smoothing_function=None):
101
- """
102
- Calculate a single corpus-level BLEU score (aka. system-level BLEU) for all
103
- the hypotheses and their respective references.
104
-
105
- Instead of averaging the sentence level BLEU scores (i.e. marco-average
106
- precision), the original BLEU metric (Papineni et al. 2002) accounts for
107
- the micro-average precision (i.e. summing the numerators and denominators
108
- for each hypothesis-reference(s) pairs before the division).
109
-
110
- >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
111
- ... 'ensures', 'that', 'the', 'military', 'always',
112
- ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
113
- >>> ref1a = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
114
- ... 'ensures', 'that', 'the', 'military', 'will', 'forever',
115
- ... 'heed', 'Party', 'commands']
116
- >>> ref1b = ['It', 'is', 'the', 'guiding', 'principle', 'which',
117
- ... 'guarantees', 'the', 'military', 'forces', 'always',
118
- ... 'being', 'under', 'the', 'command', 'of', 'the', 'Party']
119
- >>> ref1c = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
120
- ... 'army', 'always', 'to', 'heed', 'the', 'directions',
121
- ... 'of', 'the', 'party']
122
-
123
- >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
124
- ... 'interested', 'in', 'world', 'history']
125
- >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
126
- ... 'because', 'he', 'read', 'the', 'book']
127
-
128
- >>> list_of_references = [[ref1a, ref1b, ref1c], [ref2a]]
129
- >>> hypotheses = [hyp1, hyp2]
130
- >>> corpus_bleu(list_of_references, hypotheses) # doctest: +ELLIPSIS
131
- 0.5520...
132
-
133
- The example below show that corpus_bleu() is different from averaging
134
- sentence_bleu() for hypotheses
135
-
136
- >>> score1 = sentence_bleu([ref1a, ref1b, ref1c], hyp1)
137
- >>> score2 = sentence_bleu([ref2a], hyp2)
138
- >>> (score1 + score2) / 2 # doctest: +ELLIPSIS
139
- 0.6223...
140
-
141
- :param references: a corpus of lists of reference sentences, w.r.t. hypotheses
142
- :type references: list(list(list(str)))
143
- :param hypotheses: a list of hypothesis sentences
144
- :type hypotheses: list(list(str))
145
- :param weights: weights for unigrams, bigrams, trigrams and so on
146
- :type weights: list(float)
147
- :return: The corpus-level BLEU score.
148
- :rtype: float
149
- """
150
- p_numerators = Counter() # Key = ngram order, and value = no. of ngram matches.
151
- p_denominators = Counter() # Key = ngram order, and value = no. of ngram in ref.
152
- hyp_lengths, ref_lengths = 0, 0
153
-
154
- assert len(list_of_references) == len(hypotheses), "The number of hypotheses and their reference(s) should be the same"
155
-
156
- # Iterate through each hypothesis and their corresponding references.
157
- for references, hypothesis in zip(list_of_references, hypotheses):
158
- # For each order of ngram, calculate the numerator and
159
- # denominator for the corpus-level modified precision.
160
- for i, _ in enumerate(weights, start=1):
161
- p_i = _modified_precision(references, hypothesis, i)
162
- p_numerators[i] += p_i.numerator
163
- p_denominators[i] += p_i.denominator
164
-
165
- # Calculate the hypothesis length and the closest reference length.
166
- # Adds them to the corpus-level hypothesis and reference counts.
167
- hyp_len = len(hypothesis)
168
- hyp_lengths += hyp_len
169
- ref_lengths += _closest_ref_length(references, hyp_len)
170
-
171
- # Calculate corpus-level brevity penalty.
172
- bp = _brevity_penalty(ref_lengths, hyp_lengths)
173
-
174
- # Collects the various precision values for the different ngram orders.
175
- p_n = [Fraction(p_numerators[i], p_denominators[i])
176
- for i, _ in enumerate(weights, start=1)]
177
-
178
- # Smoothen the modified precision.
179
- # Note: smooth_precision() converts values into float.
180
- if smoothing_function:
181
- p_n = smoothing_function(p_n, references=references,
182
- hypothesis=hypothesis, hyp_len=hyp_len)
183
-
184
- # Calculates the overall modified precision for all ngrams.
185
- # By sum of the product of the weights and the respective *p_n*
186
- s = (w * math.log(p_i) if p_i else 0
187
- for w, p_i in zip(weights, p_n))
188
-
189
- return bp * math.exp(math.fsum(s))
190
-
191
-
192
- def _modified_precision(references, hypothesis, n):
193
- """
194
- Calculate modified ngram precision.
195
-
196
- The normal precision method may lead to some wrong translations with
197
- high-precision, e.g., the translation, in which a word of reference
198
- repeats several times, has very high precision.
199
-
200
- This function only returns the Fraction object that contains the numerator
201
- and denominator necessary to calculate the corpus-level precision.
202
- To calculate the modified precision for a single pair of hypothesis and
203
- references, cast the Fraction object into a float.
204
-
205
- The famous "the the the ... " example shows that you can get BLEU precision
206
- by duplicating high frequency words.
207
-
208
- >>> reference1 = 'the cat is on the mat'.split()
209
- >>> reference2 = 'there is a cat on the mat'.split()
210
- >>> hypothesis1 = 'the the the the the the the'.split()
211
- >>> references = [reference1, reference2]
212
- >>> float(_modified_precision(references, hypothesis1, n=1)) # doctest: +ELLIPSIS
213
- 0.2857...
214
-
215
- In the modified n-gram precision, a reference word will be considered
216
- exhausted after a matching hypothesis word is identified, e.g.
217
-
218
- >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
219
- ... 'ensures', 'that', 'the', 'military', 'will',
220
- ... 'forever', 'heed', 'Party', 'commands']
221
- >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
222
- ... 'guarantees', 'the', 'military', 'forces', 'always',
223
- ... 'being', 'under', 'the', 'command', 'of', 'the',
224
- ... 'Party']
225
- >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
226
- ... 'army', 'always', 'to', 'heed', 'the', 'directions',
227
- ... 'of', 'the', 'party']
228
- >>> hypothesis = 'of the'.split()
229
- >>> references = [reference1, reference2, reference3]
230
- >>> float(_modified_precision(references, hypothesis, n=1))
231
- 1.0
232
- >>> float(_modified_precision(references, hypothesis, n=2))
233
- 1.0
234
-
235
- An example of a normal machine translation hypothesis:
236
-
237
- >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
238
- ... 'ensures', 'that', 'the', 'military', 'always',
239
- ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
240
-
241
- >>> hypothesis2 = ['It', 'is', 'to', 'insure', 'the', 'troops',
242
- ... 'forever', 'hearing', 'the', 'activity', 'guidebook',
243
- ... 'that', 'party', 'direct']
244
-
245
- >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
246
- ... 'ensures', 'that', 'the', 'military', 'will',
247
- ... 'forever', 'heed', 'Party', 'commands']
248
-
249
- >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
250
- ... 'guarantees', 'the', 'military', 'forces', 'always',
251
- ... 'being', 'under', 'the', 'command', 'of', 'the',
252
- ... 'Party']
253
-
254
- >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
255
- ... 'army', 'always', 'to', 'heed', 'the', 'directions',
256
- ... 'of', 'the', 'party']
257
- >>> references = [reference1, reference2, reference3]
258
- >>> float(_modified_precision(references, hypothesis1, n=1)) # doctest: +ELLIPSIS
259
- 0.9444...
260
- >>> float(_modified_precision(references, hypothesis2, n=1)) # doctest: +ELLIPSIS
261
- 0.5714...
262
- >>> float(_modified_precision(references, hypothesis1, n=2)) # doctest: +ELLIPSIS
263
- 0.5882352941176471
264
- >>> float(_modified_precision(references, hypothesis2, n=2)) # doctest: +ELLIPSIS
265
- 0.07692...
266
-
267
-
268
- :param references: A list of reference translations.
269
- :type references: list(list(str))
270
- :param hypothesis: A hypothesis translation.
271
- :type hypothesis: list(str)
272
- :param n: The ngram order.
273
- :type n: int
274
- :return: BLEU's modified precision for the nth order ngram.
275
- :rtype: Fraction
276
- """
277
- counts = Counter(ngrams(hypothesis, n))
278
-
279
- if not counts:
280
- return Fraction(0)
281
-
282
- max_counts = {}
283
- for reference in references:
284
- reference_counts = Counter(ngrams(reference, n))
285
- for ngram in counts:
286
- max_counts[ngram] = max(max_counts.get(ngram, 0), reference_counts[ngram])
287
-
288
- clipped_counts = dict((ngram, min(count, max_counts[ngram]))
289
- for ngram, count in counts.items())
290
-
291
- numerator = sum(clipped_counts.values())
292
- denominator = sum(counts.values())
293
-
294
- return Fraction(numerator, denominator)
295
-
296
-
297
- def _closest_ref_length(references, hyp_len):
298
- """
299
- This function finds the reference that is the closest length to the
300
- hypothesis. The closest reference length is referred to as *r* variable
301
- from the brevity penalty formula in Papineni et. al. (2002)
302
-
303
- :param references: A list of reference translations.
304
- :type references: list(list(str))
305
- :param hypothesis: The length of the hypothesis.
306
- :type hypothesis: int
307
- :return: The length of the reference that's closest to the hypothesis.
308
- :rtype: int
309
- """
310
- ref_lens = (len(reference) for reference in references)
311
- closest_ref_len = min(ref_lens, key=lambda ref_len:
312
- (abs(ref_len - hyp_len), ref_len))
313
- return closest_ref_len
314
-
315
- def _brevity_penalty(closest_ref_len, hyp_len):
316
- """
317
- Calculate brevity penalty.
318
-
319
- As the modified n-gram precision still has the problem from the short
320
- length sentence, brevity penalty is used to modify the overall BLEU
321
- score according to length.
322
-
323
- An example from the paper. There are three references with length 12, 15
324
- and 17. And a concise hypothesis of the length 12. The brevity penalty is 1.
325
-
326
- >>> reference1 = list('aaaaaaaaaaaa') # i.e. ['a'] * 12
327
- >>> reference2 = list('aaaaaaaaaaaaaaa') # i.e. ['a'] * 15
328
- >>> reference3 = list('aaaaaaaaaaaaaaaaa') # i.e. ['a'] * 17
329
- >>> hypothesis = list('aaaaaaaaaaaa') # i.e. ['a'] * 12
330
- >>> references = [reference1, reference2, reference3]
331
- >>> hyp_len = len(hypothesis)
332
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
333
- >>> _brevity_penalty(closest_ref_len, hyp_len)
334
- 1.0
335
-
336
- In case a hypothesis translation is shorter than the references, penalty is
337
- applied.
338
-
339
- >>> references = [['a'] * 28, ['a'] * 28]
340
- >>> hypothesis = ['a'] * 12
341
- >>> hyp_len = len(hypothesis)
342
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
343
- >>> _brevity_penalty(closest_ref_len, hyp_len)
344
- 0.2635971381157267
345
-
346
- The length of the closest reference is used to compute the penalty. If the
347
- length of a hypothesis is 12, and the reference lengths are 13 and 2, the
348
- penalty is applied because the hypothesis length (12) is less then the
349
- closest reference length (13).
350
-
351
- >>> references = [['a'] * 13, ['a'] * 2]
352
- >>> hypothesis = ['a'] * 12
353
- >>> hyp_len = len(hypothesis)
354
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
355
- >>> _brevity_penalty(closest_ref_len, hyp_len) # doctest: +ELLIPSIS
356
- 0.9200...
357
-
358
- The brevity penalty doesn't depend on reference order. More importantly,
359
- when two reference sentences are at the same distance, the shortest
360
- reference sentence length is used.
361
-
362
- >>> references = [['a'] * 13, ['a'] * 11]
363
- >>> hypothesis = ['a'] * 12
364
- >>> hyp_len = len(hypothesis)
365
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
366
- >>> bp1 = _brevity_penalty(closest_ref_len, hyp_len)
367
- >>> hyp_len = len(hypothesis)
368
- >>> closest_ref_len = _closest_ref_length(reversed(references), hyp_len)
369
- >>> bp2 = _brevity_penalty(closest_ref_len, hyp_len)
370
- >>> bp1 == bp2 == 1
371
- True
372
-
373
- A test example from mteval-v13a.pl (starting from the line 705):
374
-
375
- >>> references = [['a'] * 11, ['a'] * 8]
376
- >>> hypothesis = ['a'] * 7
377
- >>> hyp_len = len(hypothesis)
378
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
379
- >>> _brevity_penalty(closest_ref_len, hyp_len) # doctest: +ELLIPSIS
380
- 0.8668...
381
-
382
- >>> references = [['a'] * 11, ['a'] * 8, ['a'] * 6, ['a'] * 7]
383
- >>> hypothesis = ['a'] * 7
384
- >>> hyp_len = len(hypothesis)
385
- >>> closest_ref_len = _closest_ref_length(references, hyp_len)
386
- >>> _brevity_penalty(closest_ref_len, hyp_len)
387
- 1.0
388
-
389
- :param hyp_len: The length of the hypothesis for a single sentence OR the
390
- sum of all the hypotheses' lengths for a corpus
391
- :type hyp_len: int
392
- :param closest_ref_len: The length of the closest reference for a single
393
- hypothesis OR the sum of all the closest references for every hypotheses.
394
- :type closest_reference_len: int
395
- :return: BLEU's brevity penalty.
396
- :rtype: float
397
- """
398
- if hyp_len > closest_ref_len:
399
- return 1
400
- else:
401
- return math.exp(1 - closest_ref_len / hyp_len)
402
-
403
-
404
- class SmoothingFunction:
405
- """
406
- This is an implementation of the smoothing techniques
407
- for segment-level BLEU scores that was presented in
408
- Boxing Chen and Collin Cherry (2014) A Systematic Comparison of
409
- Smoothing Techniques for Sentence-Level BLEU. In WMT14.
410
- http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf
411
- """
412
- def __init__(self, epsilon=0.1, alpha=5, k=5):
413
- """
414
- This will initialize the parameters required for the various smoothing
415
- techniques, the default values are set to the numbers used in the
416
- experiments from Chen and Cherry (2014).
417
-
418
- >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which', 'ensures',
419
- ... 'that', 'the', 'military', 'always', 'obeys', 'the',
420
- ... 'commands', 'of', 'the', 'party']
421
- >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that', 'ensures',
422
- ... 'that', 'the', 'military', 'will', 'forever', 'heed',
423
- ... 'Party', 'commands']
424
-
425
- >>> chencherry = SmoothingFunction()
426
- >>> print (sentence_bleu([reference1], hypothesis1)) # doctest: +ELLIPSIS
427
- 0.4118...
428
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method0)) # doctest: +ELLIPSIS
429
- 0.4118...
430
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method1)) # doctest: +ELLIPSIS
431
- 0.4118...
432
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method2)) # doctest: +ELLIPSIS
433
- 0.4576...
434
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method3)) # doctest: +ELLIPSIS
435
- 0.4118...
436
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method4)) # doctest: +ELLIPSIS
437
- 0.4118...
438
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method5)) # doctest: +ELLIPSIS
439
- 0.4905...
440
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method6)) # doctest: +ELLIPSIS
441
- 0.1801...
442
- >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method7)) # doctest: +ELLIPSIS
443
- 0.4905...
444
-
445
- :param epsilon: the epsilon value use in method 1
446
- :type epsilon: float
447
- :param alpha: the alpha value use in method 6
448
- :type alpha: int
449
- :param k: the k value use in method 4
450
- :type k: int
451
- """
452
- self.epsilon = epsilon
453
- self.alpha = alpha
454
- self.k = k
455
-
456
- def method0(self, p_n, *args, **kwargs):
457
- """ No smoothing. """
458
- return p_n
459
-
460
- def method1(self, p_n, *args, **kwargs):
461
- """
462
- Smoothing method 1: Add *epsilon* counts to precision with 0 counts.
463
- """
464
- return [(p_i.numerator + self.epsilon)/ p_i.denominator
465
- if p_i.numerator == 0 else p_i for p_i in p_n]
466
-
467
- def method2(self, p_n, *args, **kwargs):
468
- """
469
- Smoothing method 2: Add 1 to both numerator and denominator from
470
- Chin-Yew Lin and Franz Josef Och (2004) Automatic evaluation of
471
- machine translation quality using longest common subsequence and
472
- skip-bigram statistics. In ACL04.
473
- """
474
- return [Fraction(p_i.numerator + 1, p_i.denominator + 1) for p_i in p_n]
475
-
476
- def method3(self, p_n, *args, **kwargs):
477
- """
478
- Smoothing method 3: NIST geometric sequence smoothing
479
- The smoothing is computed by taking 1 / ( 2^k ), instead of 0, for each
480
- precision score whose matching n-gram count is null.
481
- k is 1 for the first 'n' value for which the n-gram match count is null/
482
- For example, if the text contains:
483
- - one 2-gram match
484
- - and (consequently) two 1-gram matches
485
- the n-gram count for each individual precision score would be:
486
- - n=1 => prec_count = 2 (two unigrams)
487
- - n=2 => prec_count = 1 (one bigram)
488
- - n=3 => prec_count = 1/2 (no trigram, taking 'smoothed' value of 1 / ( 2^k ), with k=1)
489
- - n=4 => prec_count = 1/4 (no fourgram, taking 'smoothed' value of 1 / ( 2^k ), with k=2)
490
- """
491
- incvnt = 1 # From the mteval-v13a.pl, it's referred to as k.
492
- for i, p_i in enumerate(p_n):
493
- if p_i == 0:
494
- p_n[i] = 1 / (2**incvnt * p_i.denominator)
495
- incvnt+=1
496
- return p_n
497
-
498
- def method4(self, p_n, references, hypothesis, hyp_len):
499
- """
500
- Smoothing method 4:
501
- Shorter translations may have inflated precision values due to having
502
- smaller denominators; therefore, we give them proportionally
503
- smaller smoothed counts. Instead of scaling to 1/(2^k), Chen and Cherry
504
- suggests dividing by 1/ln(len(T)), where T is the length of the translation.
505
- """
506
- incvnt = 1
507
- for i, p_i in enumerate(p_n):
508
- if p_i == 0 and hyp_len != 0:
509
- p_n[i] = incvnt * self.k / math.log(hyp_len) # Note that this K is different from the K from NIST.
510
- incvnt+=1
511
- return p_n
512
-
513
-
514
- def method5(self, p_n, references, hypothesis, hyp_len):
515
- """
516
- Smoothing method 5:
517
- The matched counts for similar values of n should be similar. To a
518
- calculate the n-gram matched count, it averages the n−1, n and n+1 gram
519
- matched counts.
520
- """
521
- m = {}
522
- # Requires an precision value for an addition ngram order.
523
- p_n_plus1 = p_n + [_modified_precision(references, hypothesis, 5)]
524
- m[-1] = p_n[0] + 1
525
- for i, p_i in enumerate(p_n):
526
- p_n[i] = (m[i-1] + p_i + p_n_plus1[i+1]) / 3
527
- m[i] = p_n[i]
528
- return p_n
529
-
530
- def method6(self, p_n, references, hypothesis, hyp_len):
531
- """
532
- Smoothing method 6:
533
- Interpolates the maximum likelihood estimate of the precision *p_n* with
534
- a prior estimate *pi0*. The prior is estimated by assuming that the ratio
535
- between pn and pn−1 will be the same as that between pn−1 and pn−2.
536
- """
537
- for i, p_i in enumerate(p_n):
538
- if i in [1,2]: # Skips the first 2 orders of ngrams.
539
- continue
540
- else:
541
- pi0 = 0 if p_n[i-2] == 0 else p_n[i-1]**2 / p_n[i-2]
542
- # No. of ngrams in translation.
543
- l = sum(1 for _ in ngrams(hypothesis, i+1))
544
- p_n[i] = (p_i + self.alpha * pi0) / (l + self.alpha)
545
- return p_n
546
-
547
- def method7(self, p_n, references, hypothesis, hyp_len):
548
- """
549
- Smoothing method 6:
550
- Interpolates the maximum likelihood estimate of the precision *p_n* with
551
- a prior estimate *pi0*. The prior is estimated by assuming that the ratio
552
- between pn and pn−1 will be the same as that between pn−1 and pn−2.
553
- """
554
- p_n = self.method4(p_n, references, hypothesis, hyp_len)
555
- p_n = self.method5(p_n, references, hypothesis, hyp_len)
556
- return p_n
1
+ # -*- coding: utf-8 -*-
2
+ # Natural Language Toolkit: BLEU Score
3
+ #
4
+ # Copyright (C) 2001-2018 NLTK Project
5
+ # Authors: Chin Yee Lee, Hengfeng Li, Ruxin Hou, Calvin Tanujaya Lim
6
+ # Contributors: Björn Mattsson, Dmitrijs Milajevs, Liling Tan
7
+ # URL: <http://nltk.org/>
8
+ # For license information, see LICENSE.TXT
9
+
10
+ """BLEU score implementation."""
11
+ from __future__ import division
12
+
13
+ import math
14
+ import sys
15
+ import fractions
16
+ import warnings
17
+ from collections import Counter
18
+
19
+ from nltk.util import ngrams
20
+
21
+ try:
22
+ fractions.Fraction(0, 1000, _normalize=False)
23
+ from fractions import Fraction
24
+ except TypeError:
25
+ from nltk.compat import Fraction
26
+
27
+
28
+ def sentence_bleu(references, hypothesis, weights=(0.25, 0.25, 0.25, 0.25),
29
+ smoothing_function=None, auto_reweigh=False):
30
+ """
31
+ Calculate BLEU score (Bilingual Evaluation Understudy) from
32
+ Papineni, Kishore, Salim Roukos, Todd Ward, and Wei-Jing Zhu. 2002.
33
+ "BLEU: a method for automatic evaluation of machine translation."
34
+ In Proceedings of ACL. http://www.aclweb.org/anthology/P02-1040.pdf
35
+
36
+ >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
37
+ ... 'ensures', 'that', 'the', 'military', 'always',
38
+ ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
39
+
40
+ >>> hypothesis2 = ['It', 'is', 'to', 'insure', 'the', 'troops',
41
+ ... 'forever', 'hearing', 'the', 'activity', 'guidebook',
42
+ ... 'that', 'party', 'direct']
43
+
44
+ >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
45
+ ... 'ensures', 'that', 'the', 'military', 'will', 'forever',
46
+ ... 'heed', 'Party', 'commands']
47
+
48
+ >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
49
+ ... 'guarantees', 'the', 'military', 'forces', 'always',
50
+ ... 'being', 'under', 'the', 'command', 'of', 'the',
51
+ ... 'Party']
52
+
53
+ >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
54
+ ... 'army', 'always', 'to', 'heed', 'the', 'directions',
55
+ ... 'of', 'the', 'party']
56
+
57
+ >>> sentence_bleu([reference1, reference2, reference3], hypothesis1) # doctest: +ELLIPSIS
58
+ 0.5045...
59
+
60
+ If there is no ngrams overlap for any order of n-grams, BLEU returns the
61
+ value 0. This is because the precision for the order of n-grams without
62
+ overlap is 0, and the geometric mean in the final BLEU score computation
63
+ multiplies the 0 with the precision of other n-grams. This results in 0
64
+ (independently of the precision of the othe n-gram orders). The following
65
+ example has zero 3-gram and 4-gram overlaps:
66
+
67
+ >>> round(sentence_bleu([reference1, reference2, reference3], hypothesis2),4) # doctest: +ELLIPSIS
68
+ 0.0
69
+
70
+ To avoid this harsh behaviour when no ngram overlaps are found a smoothing
71
+ function can be used.
72
+
73
+ >>> chencherry = SmoothingFunction()
74
+ >>> sentence_bleu([reference1, reference2, reference3], hypothesis2,
75
+ ... smoothing_function=chencherry.method1) # doctest: +ELLIPSIS
76
+ 0.0370...
77
+
78
+ The default BLEU calculates a score for up to 4-grams using uniform
79
+ weights (this is called BLEU-4). To evaluate your translations with
80
+ higher/lower order ngrams, use customized weights. E.g. when accounting
81
+ for up to 5-grams with uniform weights (this is called BLEU-5) use:
82
+
83
+ >>> weights = (1./5., 1./5., 1./5., 1./5., 1./5.)
84
+ >>> sentence_bleu([reference1, reference2, reference3], hypothesis1, weights) # doctest: +ELLIPSIS
85
+ 0.3920...
86
+
87
+ :param references: reference sentences
88
+ :type references: list(list(str))
89
+ :param hypothesis: a hypothesis sentence
90
+ :type hypothesis: list(str)
91
+ :param weights: weights for unigrams, bigrams, trigrams and so on
92
+ :type weights: list(float)
93
+ :param smoothing_function:
94
+ :type smoothing_function: SmoothingFunction
95
+ :param auto_reweigh: Option to re-normalize the weights uniformly.
96
+ :type auto_reweigh: bool
97
+ :return: The sentence-level BLEU score.
98
+ :rtype: float
99
+ """
100
+ return corpus_bleu([references], [hypothesis],
101
+ weights, smoothing_function, auto_reweigh)
102
+
103
+
104
+ def corpus_bleu(list_of_references, hypotheses, weights=(0.25, 0.25, 0.25, 0.25),
105
+ smoothing_function=None, auto_reweigh=False):
106
+ """
107
+ Calculate a single corpus-level BLEU score (aka. system-level BLEU) for all
108
+ the hypotheses and their respective references.
109
+
110
+ Instead of averaging the sentence level BLEU scores (i.e. marco-average
111
+ precision), the original BLEU metric (Papineni et al. 2002) accounts for
112
+ the micro-average precision (i.e. summing the numerators and denominators
113
+ for each hypothesis-reference(s) pairs before the division).
114
+
115
+ >>> hyp1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
116
+ ... 'ensures', 'that', 'the', 'military', 'always',
117
+ ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
118
+ >>> ref1a = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
119
+ ... 'ensures', 'that', 'the', 'military', 'will', 'forever',
120
+ ... 'heed', 'Party', 'commands']
121
+ >>> ref1b = ['It', 'is', 'the', 'guiding', 'principle', 'which',
122
+ ... 'guarantees', 'the', 'military', 'forces', 'always',
123
+ ... 'being', 'under', 'the', 'command', 'of', 'the', 'Party']
124
+ >>> ref1c = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
125
+ ... 'army', 'always', 'to', 'heed', 'the', 'directions',
126
+ ... 'of', 'the', 'party']
127
+
128
+ >>> hyp2 = ['he', 'read', 'the', 'book', 'because', 'he', 'was',
129
+ ... 'interested', 'in', 'world', 'history']
130
+ >>> ref2a = ['he', 'was', 'interested', 'in', 'world', 'history',
131
+ ... 'because', 'he', 'read', 'the', 'book']
132
+
133
+ >>> list_of_references = [[ref1a, ref1b, ref1c], [ref2a]]
134
+ >>> hypotheses = [hyp1, hyp2]
135
+ >>> corpus_bleu(list_of_references, hypotheses) # doctest: +ELLIPSIS
136
+ 0.5920...
137
+
138
+ The example below show that corpus_bleu() is different from averaging
139
+ sentence_bleu() for hypotheses
140
+
141
+ >>> score1 = sentence_bleu([ref1a, ref1b, ref1c], hyp1)
142
+ >>> score2 = sentence_bleu([ref2a], hyp2)
143
+ >>> (score1 + score2) / 2 # doctest: +ELLIPSIS
144
+ 0.6223...
145
+
146
+ :param list_of_references: a corpus of lists of reference sentences, w.r.t. hypotheses
147
+ :type list_of_references: list(list(list(str)))
148
+ :param hypotheses: a list of hypothesis sentences
149
+ :type hypotheses: list(list(str))
150
+ :param weights: weights for unigrams, bigrams, trigrams and so on
151
+ :type weights: list(float)
152
+ :param smoothing_function:
153
+ :type smoothing_function: SmoothingFunction
154
+ :param auto_reweigh: Option to re-normalize the weights uniformly.
155
+ :type auto_reweigh: bool
156
+ :return: The corpus-level BLEU score.
157
+ :rtype: float
158
+ """
159
+ # Before proceeding to compute BLEU, perform sanity checks.
160
+
161
+ p_numerators = Counter() # Key = ngram order, and value = no. of ngram matches.
162
+ p_denominators = Counter() # Key = ngram order, and value = no. of ngram in ref.
163
+ hyp_lengths, ref_lengths = 0, 0
164
+
165
+ assert len(list_of_references) == len(hypotheses), "The number of hypotheses and their reference(s) should be the " \
166
+ "same "
167
+
168
+ # Iterate through each hypothesis and their corresponding references.
169
+ for references, hypothesis in zip(list_of_references, hypotheses):
170
+ # For each order of ngram, calculate the numerator and
171
+ # denominator for the corpus-level modified precision.
172
+ for i, _ in enumerate(weights, start=1):
173
+ p_i = modified_precision(references, hypothesis, i)
174
+ p_numerators[i] += p_i.numerator
175
+ p_denominators[i] += p_i.denominator
176
+
177
+ # Calculate the hypothesis length and the closest reference length.
178
+ # Adds them to the corpus-level hypothesis and reference counts.
179
+ hyp_len = len(hypothesis)
180
+ hyp_lengths += hyp_len
181
+ ref_lengths += closest_ref_length(references, hyp_len)
182
+
183
+ # Calculate corpus-level brevity penalty.
184
+ bp = brevity_penalty(ref_lengths, hyp_lengths)
185
+
186
+ # Uniformly re-weighting based on maximum hypothesis lengths if largest
187
+ # order of n-grams < 4 and weights is set at default.
188
+ if auto_reweigh:
189
+ if hyp_lengths < 4 and weights == (0.25, 0.25, 0.25, 0.25):
190
+ weights = (1 / hyp_lengths,) * hyp_lengths
191
+
192
+ # Collects the various precision values for the different ngram orders.
193
+ p_n = [Fraction(p_numerators[i], p_denominators[i], _normalize=False)
194
+ for i, _ in enumerate(weights, start=1)]
195
+
196
+ # Returns 0 if there's no matching n-grams
197
+ # We only need to check for p_numerators[1] == 0, since if there's
198
+ # no unigrams, there won't be any higher order ngrams.
199
+ if p_numerators[1] == 0:
200
+ return 0
201
+
202
+ # If there's no smoothing, set use method0 from SmoothinFunction class.
203
+ if not smoothing_function:
204
+ smoothing_function = SmoothingFunction().method0
205
+ # Smoothen the modified precision.
206
+ # Note: smoothing_function() may convert values into floats;
207
+ # it tries to retain the Fraction object as much as the
208
+ # smoothing method allows.
209
+ p_n = smoothing_function(p_n, references=references, hypothesis=hypothesis,
210
+ hyp_len=hyp_len)
211
+ s = (w_i * math.log(p_i) for w_i, p_i in zip(weights, p_n))
212
+ s = bp * math.exp(math.fsum(s))
213
+ return s
214
+
215
+
216
+ def modified_precision(references, hypothesis, n):
217
+ """
218
+ Calculate modified ngram precision.
219
+
220
+ The normal precision method may lead to some wrong translations with
221
+ high-precision, e.g., the translation, in which a word of reference
222
+ repeats several times, has very high precision.
223
+
224
+ This function only returns the Fraction object that contains the numerator
225
+ and denominator necessary to calculate the corpus-level precision.
226
+ To calculate the modified precision for a single pair of hypothesis and
227
+ references, cast the Fraction object into a float.
228
+
229
+ The famous "the the the ... " example shows that you can get BLEU precision
230
+ by duplicating high frequency words.
231
+
232
+ >>> reference1 = 'the cat is on the mat'.split()
233
+ >>> reference2 = 'there is a cat on the mat'.split()
234
+ >>> hypothesis1 = 'the the the the the the the'.split()
235
+ >>> references = [reference1, reference2]
236
+ >>> float(modified_precision(references, hypothesis1, n=1)) # doctest: +ELLIPSIS
237
+ 0.2857...
238
+
239
+ In the modified n-gram precision, a reference word will be considered
240
+ exhausted after a matching hypothesis word is identified, e.g.
241
+
242
+ >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
243
+ ... 'ensures', 'that', 'the', 'military', 'will',
244
+ ... 'forever', 'heed', 'Party', 'commands']
245
+ >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
246
+ ... 'guarantees', 'the', 'military', 'forces', 'always',
247
+ ... 'being', 'under', 'the', 'command', 'of', 'the',
248
+ ... 'Party']
249
+ >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
250
+ ... 'army', 'always', 'to', 'heed', 'the', 'directions',
251
+ ... 'of', 'the', 'party']
252
+ >>> hypothesis = 'of the'.split()
253
+ >>> references = [reference1, reference2, reference3]
254
+ >>> float(modified_precision(references, hypothesis, n=1))
255
+ 1.0
256
+ >>> float(modified_precision(references, hypothesis, n=2))
257
+ 1.0
258
+
259
+ An example of a normal machine translation hypothesis:
260
+
261
+ >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which',
262
+ ... 'ensures', 'that', 'the', 'military', 'always',
263
+ ... 'obeys', 'the', 'commands', 'of', 'the', 'party']
264
+
265
+ >>> hypothesis2 = ['It', 'is', 'to', 'insure', 'the', 'troops',
266
+ ... 'forever', 'hearing', 'the', 'activity', 'guidebook',
267
+ ... 'that', 'party', 'direct']
268
+
269
+ >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that',
270
+ ... 'ensures', 'that', 'the', 'military', 'will',
271
+ ... 'forever', 'heed', 'Party', 'commands']
272
+
273
+ >>> reference2 = ['It', 'is', 'the', 'guiding', 'principle', 'which',
274
+ ... 'guarantees', 'the', 'military', 'forces', 'always',
275
+ ... 'being', 'under', 'the', 'command', 'of', 'the',
276
+ ... 'Party']
277
+
278
+ >>> reference3 = ['It', 'is', 'the', 'practical', 'guide', 'for', 'the',
279
+ ... 'army', 'always', 'to', 'heed', 'the', 'directions',
280
+ ... 'of', 'the', 'party']
281
+ >>> references = [reference1, reference2, reference3]
282
+ >>> float(modified_precision(references, hypothesis1, n=1)) # doctest: +ELLIPSIS
283
+ 0.9444...
284
+ >>> float(modified_precision(references, hypothesis2, n=1)) # doctest: +ELLIPSIS
285
+ 0.5714...
286
+ >>> float(modified_precision(references, hypothesis1, n=2)) # doctest: +ELLIPSIS
287
+ 0.5882352941176471
288
+ >>> float(modified_precision(references, hypothesis2, n=2)) # doctest: +ELLIPSIS
289
+ 0.07692...
290
+
291
+
292
+ :param references: A list of reference translations.
293
+ :type references: list(list(str))
294
+ :param hypothesis: A hypothesis translation.
295
+ :type hypothesis: list(str)
296
+ :param n: The ngram order.
297
+ :type n: int
298
+ :return: BLEU's modified precision for the nth order ngram.
299
+ :rtype: Fraction
300
+ """
301
+ # Extracts all ngrams in hypothesis
302
+ # Set an empty Counter if hypothesis is empty.
303
+ counts = Counter(ngrams(hypothesis, n)) if len(hypothesis) >= n else Counter()
304
+ # Extract a union of references' counts.
305
+ # max_counts = reduce(or_, [Counter(ngrams(ref, n)) for ref in references])
306
+ max_counts = {}
307
+ for reference in references:
308
+ reference_counts = Counter(ngrams(reference, n)) if len(reference) >= n else Counter()
309
+ for ngram in counts:
310
+ max_counts[ngram] = max(max_counts.get(ngram, 0),
311
+ reference_counts[ngram])
312
+
313
+ # Assigns the intersection between hypothesis and references' counts.
314
+ clipped_counts = {ngram: min(count, max_counts[ngram])
315
+ for ngram, count in counts.items()}
316
+
317
+ numerator = sum(clipped_counts.values())
318
+ # Ensures that denominator is minimum 1 to avoid ZeroDivisionError.
319
+ # Usually this happens when the ngram order is > len(reference).
320
+ denominator = max(1, sum(counts.values()))
321
+
322
+ return Fraction(numerator, denominator, _normalize=False)
323
+
324
+
325
+ def closest_ref_length(references, hyp_len):
326
+ """
327
+ This function finds the reference that is the closest length to the
328
+ hypothesis. The closest reference length is referred to as *r* variable
329
+ from the brevity penalty formula in Papineni et. al. (2002)
330
+
331
+ :param references: A list of reference translations.
332
+ :type references: list(list(str))
333
+ :param hyp_len: The length of the hypothesis.
334
+ :type hyp_len: int
335
+ :return: The length of the reference that's closest to the hypothesis.
336
+ :rtype: int
337
+ """
338
+ ref_lens = (len(reference) for reference in references)
339
+ closest_ref_len = min(ref_lens, key=lambda ref_len:
340
+ (abs(ref_len - hyp_len), ref_len))
341
+ return closest_ref_len
342
+
343
+
344
+ def brevity_penalty(closest_ref_len, hyp_len):
345
+ """
346
+ Calculate brevity penalty.
347
+
348
+ As the modified n-gram precision still has the problem from the short
349
+ length sentence, brevity penalty is used to modify the overall BLEU
350
+ score according to length.
351
+
352
+ An example from the paper. There are three references with length 12, 15
353
+ and 17. And a concise hypothesis of the length 12. The brevity penalty is 1.
354
+
355
+ >>> reference1 = list('aaaaaaaaaaaa') # i.e. ['a'] * 12
356
+ >>> reference2 = list('aaaaaaaaaaaaaaa') # i.e. ['a'] * 15
357
+ >>> reference3 = list('aaaaaaaaaaaaaaaaa') # i.e. ['a'] * 17
358
+ >>> hypothesis = list('aaaaaaaaaaaa') # i.e. ['a'] * 12
359
+ >>> references = [reference1, reference2, reference3]
360
+ >>> hyp_len = len(hypothesis)
361
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
362
+ >>> brevity_penalty(closest_ref_len, hyp_len)
363
+ 1.0
364
+
365
+ In case a hypothesis translation is shorter than the references, penalty is
366
+ applied.
367
+
368
+ >>> references = [['a'] * 28, ['a'] * 28]
369
+ >>> hypothesis = ['a'] * 12
370
+ >>> hyp_len = len(hypothesis)
371
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
372
+ >>> brevity_penalty(closest_ref_len, hyp_len)
373
+ 0.2635971381157267
374
+
375
+ The length of the closest reference is used to compute the penalty. If the
376
+ length of a hypothesis is 12, and the reference lengths are 13 and 2, the
377
+ penalty is applied because the hypothesis length (12) is less then the
378
+ closest reference length (13).
379
+
380
+ >>> references = [['a'] * 13, ['a'] * 2]
381
+ >>> hypothesis = ['a'] * 12
382
+ >>> hyp_len = len(hypothesis)
383
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
384
+ >>> brevity_penalty(closest_ref_len, hyp_len) # doctest: +ELLIPSIS
385
+ 0.9200...
386
+
387
+ The brevity penalty doesn't depend on reference order. More importantly,
388
+ when two reference sentences are at the same distance, the shortest
389
+ reference sentence length is used.
390
+
391
+ >>> references = [['a'] * 13, ['a'] * 11]
392
+ >>> hypothesis = ['a'] * 12
393
+ >>> hyp_len = len(hypothesis)
394
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
395
+ >>> bp1 = brevity_penalty(closest_ref_len, hyp_len)
396
+ >>> hyp_len = len(hypothesis)
397
+ >>> closest_ref_len = closest_ref_length(reversed(references), hyp_len)
398
+ >>> bp2 = brevity_penalty(closest_ref_len, hyp_len)
399
+ >>> bp1 == bp2 == 1
400
+ True
401
+
402
+ A test example from mteval-v13a.pl (starting from the line 705):
403
+
404
+ >>> references = [['a'] * 11, ['a'] * 8]
405
+ >>> hypothesis = ['a'] * 7
406
+ >>> hyp_len = len(hypothesis)
407
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
408
+ >>> brevity_penalty(closest_ref_len, hyp_len) # doctest: +ELLIPSIS
409
+ 0.8668...
410
+
411
+ >>> references = [['a'] * 11, ['a'] * 8, ['a'] * 6, ['a'] * 7]
412
+ >>> hypothesis = ['a'] * 7
413
+ >>> hyp_len = len(hypothesis)
414
+ >>> closest_ref_len = closest_ref_length(references, hyp_len)
415
+ >>> brevity_penalty(closest_ref_len, hyp_len)
416
+ 1.0
417
+
418
+ :param hyp_len: The length of the hypothesis for a single sentence OR the
419
+ sum of all the hypotheses' lengths for a corpus
420
+ :type hyp_len: int
421
+ :param closest_ref_len: The length of the closest reference for a single
422
+ hypothesis OR the sum of all the closest references for every hypotheses.
423
+ :type closest_ref_len: int
424
+ :return: BLEU's brevity penalty.
425
+ :rtype: float
426
+ """
427
+ if hyp_len > closest_ref_len:
428
+ return 1
429
+ # If hypothesis is empty, brevity penalty = 0 should result in BLEU = 0.0
430
+ elif hyp_len == 0:
431
+ return 0
432
+ else:
433
+ return math.exp(1 - closest_ref_len / hyp_len)
434
+
435
+
436
+ class SmoothingFunction:
437
+ """
438
+ This is an implementation of the smoothing techniques
439
+ for segment-level BLEU scores that was presented in
440
+ Boxing Chen and Collin Cherry (2014) A Systematic Comparison of
441
+ Smoothing Techniques for Sentence-Level BLEU. In WMT14.
442
+ http://acl2014.org/acl2014/W14-33/pdf/W14-3346.pdf
443
+ """
444
+
445
+ def __init__(self, epsilon=0.1, alpha=5, k=5):
446
+ """
447
+ This will initialize the parameters required for the various smoothing
448
+ techniques, the default values are set to the numbers used in the
449
+ experiments from Chen and Cherry (2014).
450
+
451
+ >>> hypothesis1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'which', 'ensures',
452
+ ... 'that', 'the', 'military', 'always', 'obeys', 'the',
453
+ ... 'commands', 'of', 'the', 'party']
454
+ >>> reference1 = ['It', 'is', 'a', 'guide', 'to', 'action', 'that', 'ensures',
455
+ ... 'that', 'the', 'military', 'will', 'forever', 'heed',
456
+ ... 'Party', 'commands']
457
+
458
+ >>> chencherry = SmoothingFunction()
459
+ >>> print (sentence_bleu([reference1], hypothesis1)) # doctest: +ELLIPSIS
460
+ 0.4118...
461
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method0)) # doctest: +ELLIPSIS
462
+ 0.4118...
463
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method1)) # doctest: +ELLIPSIS
464
+ 0.4118...
465
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method2)) # doctest: +ELLIPSIS
466
+ 0.4489...
467
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method3)) # doctest: +ELLIPSIS
468
+ 0.4118...
469
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method4)) # doctest: +ELLIPSIS
470
+ 0.4118...
471
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method5)) # doctest: +ELLIPSIS
472
+ 0.4905...
473
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method6)) # doctest: +ELLIPSIS
474
+ 0.4135...
475
+ >>> print (sentence_bleu([reference1], hypothesis1, smoothing_function=chencherry.method7)) # doctest: +ELLIPSIS
476
+ 0.4905...
477
+
478
+ :param epsilon: the epsilon value use in method 1
479
+ :type epsilon: float
480
+ :param alpha: the alpha value use in method 6
481
+ :type alpha: int
482
+ :param k: the k value use in method 4
483
+ :type k: int
484
+ """
485
+ self.epsilon = epsilon
486
+ self.alpha = alpha
487
+ self.k = k
488
+
489
+ def method0(self, p_n, *args, **kwargs):
490
+ """
491
+ No smoothing.
492
+ """
493
+ p_n_new = []
494
+ for i, p_i in enumerate(p_n):
495
+ if p_i.numerator != 0:
496
+ p_n_new.append(p_i)
497
+ else:
498
+ _msg = str("\nThe hypothesis contains 0 counts of {}-gram overlaps.\n"
499
+ "Therefore the BLEU score evaluates to 0, independently of\n"
500
+ "how many N-gram overlaps of lower order it contains.\n"
501
+ "Consider using lower n-gram order or use "
502
+ "SmoothingFunction()").format(i+1)
503
+ warnings.warn(_msg)
504
+ # When numerator==0 where denonminator==0 or !=0, the result
505
+ # for the precision score should be equal to 0 or undefined.
506
+ # Due to BLEU geometric mean computation in logarithm space,
507
+ # we we need to take the return sys.float_info.min such that
508
+ # math.log(sys.float_info.min) returns a 0 precision score.
509
+ p_n_new.append(sys.float_info.min)
510
+ return p_n_new
511
+
512
+ def method1(self, p_n, *args, **kwargs):
513
+ """
514
+ Smoothing method 1: Add *epsilon* counts to precision with 0 counts.
515
+ """
516
+ return [(p_i.numerator + self.epsilon) / p_i.denominator
517
+ if p_i.numerator == 0 else p_i for p_i in p_n]
518
+
519
+ def method2(self, p_n, *args, **kwargs):
520
+ """
521
+ Smoothing method 2: Add 1 to both numerator and denominator from
522
+ Chin-Yew Lin and Franz Josef Och (2004) Automatic evaluation of
523
+ machine translation quality using longest common subsequence and
524
+ skip-bigram statistics. In ACL04.
525
+ """
526
+ return [Fraction(p_i.numerator + 1, p_i.denominator + 1, _normalize=False) for p_i in p_n]
527
+
528
+ def method3(self, p_n, *args, **kwargs):
529
+ """
530
+ Smoothing method 3: NIST geometric sequence smoothing
531
+ The smoothing is computed by taking 1 / ( 2^k ), instead of 0, for each
532
+ precision score whose matching n-gram count is null.
533
+ k is 1 for the first 'n' value for which the n-gram match count is null/
534
+ For example, if the text contains:
535
+ - one 2-gram match
536
+ - and (consequently) two 1-gram matches
537
+ the n-gram count for each individual precision score would be:
538
+ - n=1 => prec_count = 2 (two unigrams)
539
+ - n=2 => prec_count = 1 (one bigram)
540
+ - n=3 => prec_count = 1/2 (no trigram, taking 'smoothed' value of 1 / ( 2^k ), with k=1)
541
+ - n=4 => prec_count = 1/4 (no fourgram, taking 'smoothed' value of 1 / ( 2^k ), with k=2)
542
+ """
543
+ incvnt = 1 # From the mteval-v13a.pl, it's referred to as k.
544
+ for i, p_i in enumerate(p_n):
545
+ if p_i.numerator == 0:
546
+ p_n[i] = 1 / (2 ** incvnt * p_i.denominator)
547
+ incvnt += 1
548
+ return p_n
549
+
550
+ def method4(self, p_n, references, hypothesis, hyp_len, *args, **kwargs):
551
+ """
552
+ Smoothing method 4:
553
+ Shorter translations may have inflated precision values due to having
554
+ smaller denominators; therefore, we give them proportionally
555
+ smaller smoothed counts. Instead of scaling to 1/(2^k), Chen and Cherry
556
+ suggests dividing by 1/ln(len(T)), where T is the length of the translation.
557
+ """
558
+ for i, p_i in enumerate(p_n):
559
+ if p_i.numerator == 0 and hyp_len != 0:
560
+ incvnt = i + 1 * self.k / math.log(hyp_len) # Note that this K is different from the K from NIST.
561
+ p_n[i] = 1 / incvnt
562
+ return p_n
563
+
564
+ def method5(self, p_n, references, hypothesis, hyp_len, *args, **kwargs):
565
+ """
566
+ Smoothing method 5:
567
+ The matched counts for similar values of n should be similar. To a
568
+ calculate the n-gram matched count, it averages the n−1, n and n+1 gram
569
+ matched counts.
570
+ """
571
+ m = {}
572
+ # Requires an precision value for an addition ngram order.
573
+ p_n_plus1 = p_n + [modified_precision(references, hypothesis, 5)]
574
+ m[-1] = p_n[0] + 1
575
+ for i, p_i in enumerate(p_n):
576
+ p_n[i] = (m[i - 1] + p_i + p_n_plus1[i + 1]) / 3
577
+ m[i] = p_n[i]
578
+ return p_n
579
+
580
+ def method6(self, p_n, references, hypothesis, hyp_len, *args, **kwargs):
581
+ """
582
+ Smoothing method 6:
583
+ Interpolates the maximum likelihood estimate of the precision *p_n* with
584
+ a prior estimate *pi0*. The prior is estimated by assuming that the ratio
585
+ between pn and pn−1 will be the same as that between pn−1 and pn−2; from
586
+ Gao and He (2013) Training MRF-Based Phrase Translation Models using
587
+ Gradient Ascent. In NAACL.
588
+ """
589
+ # This smoothing only works when p_1 and p_2 is non-zero.
590
+ # Raise an error with an appropriate message when the input is too short
591
+ # to use this smoothing technique.
592
+ assert p_n[2], "This smoothing method requires non-zero precision for bigrams."
593
+ for i, p_i in enumerate(p_n):
594
+ if i in [0, 1]: # Skips the first 2 orders of ngrams.
595
+ continue
596
+ else:
597
+ pi0 = 0 if p_n[i - 2] == 0 else p_n[i - 1] ** 2 / p_n[i - 2]
598
+ # No. of ngrams in translation that matches the reference.
599
+ m = p_i.numerator
600
+ # No. of ngrams in translation.
601
+ l = sum(1 for _ in ngrams(hypothesis, i + 1))
602
+ # Calculates the interpolated precision.
603
+ p_n[i] = (m + self.alpha * pi0) / (l + self.alpha)
604
+ return p_n
605
+
606
+ def method7(self, p_n, references, hypothesis, hyp_len, *args, **kwargs):
607
+ """
608
+ Smoothing method 6:
609
+ Interpolates the maximum likelihood estimate of the precision *p_n* with
610
+ a prior estimate *pi0*. The prior is estimated by assuming that the ratio
611
+ between pn and pn−1 will be the same as that between pn−1 and pn−2.
612
+ """
613
+ p_n = self.method4(p_n, references, hypothesis, hyp_len)
614
+ p_n = self.method5(p_n, references, hypothesis, hyp_len)
615
+ return p_n