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,445 +1,443 @@
1
- # coding: utf-8
2
- # Natural Language Toolkit: vader
3
- #
4
- # Copyright (C) 2001-2015 NLTK Project
5
- # Author: C.J. Hutto <Clayton.Hutto@gtri.gatech.edu>
6
- # Ewan Klein <ewan@inf.ed.ac.uk> (modifications)
7
- # Pierpaolo Pantone <24alsecondo@gmail.com> (modifications)
8
- # URL: <http://nltk.org/>
9
- # For license information, see LICENSE.TXT
10
- #
11
- # Modifications to the original VADER code have been made in order to
12
- # integrate it into NLTK. These have involved changes to
13
- # ensure Python 3 compatibility, and refactoring to achieve greater modularity.
14
-
15
- """
16
- If you use the VADER sentiment analysis tools, please cite:
17
-
18
- Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for
19
- Sentiment Analysis of Social Media Text. Eighth International Conference on
20
- Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
21
- """
22
-
23
- import codecs
24
- import math
25
- import os
26
- import re
27
- import string
28
-
29
- ##Constants##
30
-
31
- # (empirically derived mean sentiment intensity rating increase for booster words)
32
- B_INCR = 0.293
33
- B_DECR = -0.293
34
-
35
- # (empirically derived mean sentiment intensity rating increase for using
36
- # ALLCAPs to emphasize a word)
37
- C_INCR = 0.733
38
-
39
- N_SCALAR = -0.74
40
-
41
- # for removing punctuation
42
- REGEX_REMOVE_PUNCTUATION = re.compile('[%s]' % re.escape(string.punctuation))
43
-
44
- PUNC_LIST = [".", "!", "?", ",", ";", ":", "-", "'", "\"",
45
- "!!", "!!!", "??", "???", "?!?", "!?!", "?!?!", "!?!?"]
46
- NEGATE = \
47
- ["aint", "arent", "cannot", "cant", "couldnt", "darent", "didnt", "doesnt",
48
- "ain't", "aren't", "can't", "couldn't", "daren't", "didn't", "doesn't",
49
- "dont", "hadnt", "hasnt", "havent", "isnt", "mightnt", "mustnt", "neither",
50
- "don't", "hadn't", "hasn't", "haven't", "isn't", "mightn't", "mustn't",
51
- "neednt", "needn't", "never", "none", "nope", "nor", "not", "nothing", "nowhere",
52
- "oughtnt", "shant", "shouldnt", "uhuh", "wasnt", "werent",
53
- "oughtn't", "shan't", "shouldn't", "uh-uh", "wasn't", "weren't",
54
- "without", "wont", "wouldnt", "won't", "wouldn't", "rarely", "seldom", "despite"]
55
-
56
- # booster/dampener 'intensifiers' or 'degree adverbs'
57
- # http://en.wiktionary.org/wiki/Category:English_degree_adverbs
58
-
59
- BOOSTER_DICT = \
60
- {"absolutely": B_INCR, "amazingly": B_INCR, "awfully": B_INCR, "completely": B_INCR, "considerably": B_INCR,
61
- "decidedly": B_INCR, "deeply": B_INCR, "effing": B_INCR, "enormously": B_INCR,
62
- "entirely": B_INCR, "especially": B_INCR, "exceptionally": B_INCR, "extremely": B_INCR,
63
- "fabulously": B_INCR, "flipping": B_INCR, "flippin": B_INCR,
64
- "fricking": B_INCR, "frickin": B_INCR, "frigging": B_INCR, "friggin": B_INCR, "fully": B_INCR, "fucking": B_INCR,
65
- "greatly": B_INCR, "hella": B_INCR, "highly": B_INCR, "hugely": B_INCR, "incredibly": B_INCR,
66
- "intensely": B_INCR, "majorly": B_INCR, "more": B_INCR, "most": B_INCR, "particularly": B_INCR,
67
- "purely": B_INCR, "quite": B_INCR, "really": B_INCR, "remarkably": B_INCR,
68
- "so": B_INCR, "substantially": B_INCR,
69
- "thoroughly": B_INCR, "totally": B_INCR, "tremendously": B_INCR,
70
- "uber": B_INCR, "unbelievably": B_INCR, "unusually": B_INCR, "utterly": B_INCR,
71
- "very": B_INCR,
72
- "almost": B_DECR, "barely": B_DECR, "hardly": B_DECR, "just enough": B_DECR,
73
- "kind of": B_DECR, "kinda": B_DECR, "kindof": B_DECR, "kind-of": B_DECR,
74
- "less": B_DECR, "little": B_DECR, "marginally": B_DECR, "occasionally": B_DECR, "partly": B_DECR,
75
- "scarcely": B_DECR, "slightly": B_DECR, "somewhat": B_DECR,
76
- "sort of": B_DECR, "sorta": B_DECR, "sortof": B_DECR, "sort-of": B_DECR}
77
-
78
- # check for special case idioms using a sentiment-laden keyword known to SAGE
79
- SPECIAL_CASE_IDIOMS = {"the shit": 3, "the bomb": 3, "bad ass": 1.5, "yeah right": -2,
80
- "cut the mustard": 2, "kiss of death": -1.5, "hand to mouth": -2}
81
-
82
-
83
- ##Static methods##
84
-
85
- def negated(input_words, include_nt=True):
86
- """
87
- Determine if input contains negation words
88
- """
89
- neg_words = []
90
- neg_words.extend(NEGATE)
91
- for word in neg_words:
92
- if word in input_words:
93
- return True
94
- if include_nt:
95
- for word in input_words:
96
- if "n't" in word:
97
- return True
98
- if "least" in input_words:
99
- i = input_words.index("least")
100
- if i > 0 and input_words[i-1] != "at":
101
- return True
102
- return False
103
-
104
-
105
- def normalize(score, alpha=15):
106
- """
107
- Normalize the score to be between -1 and 1 using an alpha that
108
- approximates the max expected value
109
- """
110
- norm_score = score/math.sqrt((score*score) + alpha)
111
- return norm_score
112
-
113
-
114
- def allcap_differential(words):
115
- """
116
- Check whether just some words in the input are ALL CAPS
117
-
118
- :param list words: The words to inspect
119
- :returns: `True` if some but not all items in `words` are ALL CAPS
120
- """
121
- is_different = False
122
- allcap_words = 0
123
- for word in words:
124
- if word.isupper():
125
- allcap_words += 1
126
- cap_differential = len(words) - allcap_words
127
- if cap_differential > 0 and cap_differential < len(words):
128
- is_different = True
129
- return is_different
130
-
131
-
132
- def scalar_inc_dec(word, valence, is_cap_diff):
133
- """
134
- Check if the preceding words increase, decrease, or negate/nullify the
135
- valence
136
- """
137
- scalar = 0.0
138
- word_lower = word.lower()
139
- if word_lower in BOOSTER_DICT:
140
- scalar = BOOSTER_DICT[word_lower]
141
- if valence < 0:
142
- scalar *= -1
143
- #check if booster/dampener word is in ALLCAPS (while others aren't)
144
- if word.isupper() and is_cap_diff:
145
- if valence > 0:
146
- scalar += C_INCR
147
- else: scalar -= C_INCR
148
- return scalar
149
-
150
- class SentiText(object):
151
- """
152
- Identify sentiment-relevant string-level properties of input text.
153
- """
154
- def __init__(self, text):
155
- if not isinstance(text, str):
156
- text = str(text.encode('utf-8'))
157
- self.text = text
158
- self.words_and_emoticons = self._words_and_emoticons()
159
- # doesn't separate words from\
160
- # adjacent punctuation (keeps emoticons & contractions)
161
- self.is_cap_diff = allcap_differential(self.words_and_emoticons)
162
-
163
- def _words_only(self):
164
- text_mod = REGEX_REMOVE_PUNCTUATION.sub('', self.text)
165
- # removes punctuation (but loses emoticons & contractions)
166
- words_only = text_mod.split()
167
- # get rid of empty items or single letter "words" like 'a' and 'I'
168
- words_only = [word for word in words_only if len(word) > 1]
169
- return words_only
170
-
171
- def _words_and_emoticons(self):
172
- wes = self.text.split()
173
-
174
- # get rid of residual empty items or single letter words
175
- wes = [we for we in wes if len(we) > 1]
176
-
177
- for word in self._words_only():
178
- for punct in PUNC_LIST:
179
- pword = punct + word
180
- x1 = wes.count(pword)
181
- while x1 > 0:
182
- i = wes.index(pword)
183
- wes.remove(pword)
184
- wes.insert(i, word)
185
- x1 = wes.count(pword)
186
-
187
- wordp = word + punct
188
- x2 = wes.count(wordp)
189
- while x2 > 0:
190
- i = wes.index(wordp)
191
- wes.remove(wordp)
192
- wes.insert(i, word)
193
- x2 = wes.count(wordp)
194
- return wes
195
-
196
- class SentimentIntensityAnalyzer(object):
197
- """
198
- Give a sentiment intensity score to sentences.
199
- """
200
- def __init__(self, lexicon_file="vader_lexicon.txt"):
201
- self.lexicon_file = os.path.join(os.path.dirname(__file__), lexicon_file)
202
- self.lexicon = self.make_lex_dict()
203
-
204
- def make_lex_dict(self):
205
- """
206
- Convert lexicon file to a dictionary
207
- """
208
- lex_dict = {}
209
- with codecs.open(self.lexicon_file, encoding='utf8') as infile:
210
- for line in infile:
211
- (word, measure) = line.strip().split('\t')[0:2]
212
- lex_dict[word] = float(measure)
213
- return lex_dict
214
-
215
- def polarity_scores(self, text):
216
- """
217
- Return a float for sentiment strength based on the input text.
218
- Positive values are positive valence, negative value are negative
219
- valence.
220
- """
221
- sentitext = SentiText(text)
222
- #text, words_and_emoticons, is_cap_diff = self.preprocess(text)
223
-
224
- sentiments = []
225
- words_and_emoticons = sentitext.words_and_emoticons
226
- for item in words_and_emoticons:
227
- valence = 0
228
- i = words_and_emoticons.index(item)
229
- if (i < len(words_and_emoticons) - 1 and item.lower() == "kind" and \
230
- words_and_emoticons[i+1].lower() == "of") or \
231
- item.lower() in BOOSTER_DICT:
232
- sentiments.append(valence)
233
- continue
234
-
235
- sentiments = self.sentiment_valence(valence, sentitext, item, i, sentiments)
236
-
237
- sentiments = self._but_check(words_and_emoticons, sentiments)
238
-
239
- return self.score_valence(sentiments, text)
240
-
241
- def sentiment_valence(self, valence, sentitext, item, i, sentiments):
242
- is_cap_diff = sentitext.is_cap_diff
243
- words_and_emoticons = sentitext.words_and_emoticons
244
- item_lowercase = item.lower()
245
- if item_lowercase in self.lexicon:
246
- #get the sentiment valence
247
- valence = self.lexicon[item_lowercase]
248
-
249
- #check if sentiment laden word is in ALL CAPS (while others aren't)
250
- if item.isupper() and is_cap_diff:
251
- if valence > 0:
252
- valence += C_INCR
253
- else:
254
- valence -= C_INCR
255
-
256
- for start_i in range(0,3):
257
- if i > start_i and words_and_emoticons[i-(start_i+1)].lower() not in self.lexicon:
258
- # dampen the scalar modifier of preceding words and emoticons
259
- # (excluding the ones that immediately preceed the item) based
260
- # on their distance from the current item.
261
- s = scalar_inc_dec(words_and_emoticons[i-(start_i+1)], valence, is_cap_diff)
262
- if start_i == 1 and s != 0:
263
- s = s*0.95
264
- if start_i == 2 and s != 0:
265
- s = s*0.9
266
- valence = valence+s
267
- valence = self._never_check(valence, words_and_emoticons, start_i, i)
268
- if start_i == 2:
269
- valence = self._idioms_check(valence, words_and_emoticons, i)
270
-
271
- # future work: consider other sentiment-laden idioms
272
- # other_idioms =
273
- # {"back handed": -2, "blow smoke": -2, "blowing smoke": -2,
274
- # "upper hand": 1, "break a leg": 2,
275
- # "cooking with gas": 2, "in the black": 2, "in the red": -2,
276
- # "on the ball": 2,"under the weather": -2}
277
-
278
- valence = self._least_check(valence, words_and_emoticons, i)
279
-
280
- sentiments.append(valence)
281
- return sentiments
282
-
283
- def _least_check(self, valence, words_and_emoticons, i):
284
- # check for negation case using "least"
285
- if i > 1 and words_and_emoticons[i-1].lower() not in self.lexicon \
286
- and words_and_emoticons[i-1].lower() == "least":
287
- if words_and_emoticons[i-2].lower() != "at" and words_and_emoticons[i-2].lower() != "very":
288
- valence = valence*N_SCALAR
289
- elif i > 0 and words_and_emoticons[i-1].lower() not in self.lexicon \
290
- and words_and_emoticons[i-1].lower() == "least":
291
- valence = valence*N_SCALAR
292
- return valence
293
-
294
- def _but_check(self, words_and_emoticons, sentiments):
295
- # check for modification in sentiment due to contrastive conjunction 'but'
296
- if 'but' in words_and_emoticons or 'BUT' in words_and_emoticons:
297
- try:
298
- bi = words_and_emoticons.index('but')
299
- except ValueError:
300
- bi = words_and_emoticons.index('BUT')
301
- for sentiment in sentiments:
302
- si = sentiments.index(sentiment)
303
- if si < bi:
304
- sentiments.pop(si)
305
- sentiments.insert(si, sentiment*0.5)
306
- elif si > bi:
307
- sentiments.pop(si)
308
- sentiments.insert(si, sentiment*1.5)
309
- return sentiments
310
-
311
- def _idioms_check(self, valence, words_and_emoticons, i):
312
- onezero = "{0} {1}".format(words_and_emoticons[i-1], words_and_emoticons[i])
313
-
314
- twoonezero = "{0} {1} {2}".format(words_and_emoticons[i-2],
315
- words_and_emoticons[i-1], words_and_emoticons[i])
316
-
317
- twoone = "{0} {1}".format(words_and_emoticons[i-2], words_and_emoticons[i-1])
318
-
319
- threetwoone = "{0} {1} {2}".format(words_and_emoticons[i-3],
320
- words_and_emoticons[i-2], words_and_emoticons[i-1])
321
-
322
- threetwo = "{0} {1}".format(words_and_emoticons[i-3], words_and_emoticons[i-2])
323
-
324
- sequences = [onezero, twoonezero, twoone, threetwoone, threetwo]
325
-
326
- for seq in sequences:
327
- if seq in SPECIAL_CASE_IDIOMS:
328
- valence = SPECIAL_CASE_IDIOMS[seq]
329
- break
330
-
331
- if len(words_and_emoticons)-1 > i:
332
- zeroone = "{0} {1}".format(words_and_emoticons[i], words_and_emoticons[i+1])
333
- if zeroone in SPECIAL_CASE_IDIOMS:
334
- valence = SPECIAL_CASE_IDIOMS[zeroone]
335
- if len(words_and_emoticons)-1 > i+1:
336
- zeroonetwo = "{0} {1} {2}".format(words_and_emoticons[i], words_and_emoticons[i+1], words_and_emoticons[i+2])
337
- if zeroonetwo in SPECIAL_CASE_IDIOMS:
338
- valence = SPECIAL_CASE_IDIOMS[zeroonetwo]
339
-
340
- # check for booster/dampener bi-grams such as 'sort of' or 'kind of'
341
- if threetwo in BOOSTER_DICT or twoone in BOOSTER_DICT:
342
- valence = valence+B_DECR
343
- return valence
344
-
345
- def _never_check(self, valence, words_and_emoticons, start_i, i):
346
- if start_i == 0:
347
- if negated([words_and_emoticons[i-1]]):
348
- valence = valence*N_SCALAR
349
- if start_i == 1:
350
- if words_and_emoticons[i-2] == "never" and\
351
- (words_and_emoticons[i-1] == "so" or
352
- words_and_emoticons[i-1] == "this"):
353
- valence = valence*1.5
354
- elif negated([words_and_emoticons[i-(start_i+1)]]):
355
- valence = valence*N_SCALAR
356
- if start_i == 2:
357
- if words_and_emoticons[i-3] == "never" and \
358
- (words_and_emoticons[i-2] == "so" or words_and_emoticons[i-2] == "this") or \
359
- (words_and_emoticons[i-1] == "so" or words_and_emoticons[i-1] == "this"):
360
- valence = valence*1.25
361
- elif negated([words_and_emoticons[i-(start_i+1)]]):
362
- valence = valence*N_SCALAR
363
- return valence
364
-
365
- def _punctuation_emphasis(self, sum_s, text):
366
- # add emphasis from exclamation points and question marks
367
- ep_amplifier = self._amplify_ep(text)
368
- qm_amplifier = self._amplify_qm(text)
369
- punct_emph_amplifier = ep_amplifier+qm_amplifier
370
- return punct_emph_amplifier
371
-
372
- def _amplify_ep(self, text):
373
- # check for added emphasis resulting from exclamation points (up to 4 of them)
374
- ep_count = text.count("!")
375
- if ep_count > 4:
376
- ep_count = 4
377
- # (empirically derived mean sentiment intensity rating increase for
378
- # exclamation points)
379
- ep_amplifier = ep_count*0.292
380
- return ep_amplifier
381
-
382
- def _amplify_qm(self, text):
383
- # check for added emphasis resulting from question marks (2 or 3+)
384
- qm_count = text.count("?")
385
- qm_amplifier = 0
386
- if qm_count > 1:
387
- if qm_count <= 3:
388
- # (empirically derived mean sentiment intensity rating increase for
389
- # question marks)
390
- qm_amplifier = qm_count*0.18
391
- else:
392
- qm_amplifier = 0.96
393
- return qm_amplifier
394
-
395
- def _sift_sentiment_scores(self, sentiments):
396
- # want separate positive versus negative sentiment scores
397
- pos_sum = 0.0
398
- neg_sum = 0.0
399
- neu_count = 0
400
- for sentiment_score in sentiments:
401
- if sentiment_score > 0:
402
- pos_sum += (float(sentiment_score) +1) # compensates for neutral words that are counted as 1
403
- if sentiment_score < 0:
404
- neg_sum += (float(sentiment_score) -1) # when used with math.fabs(), compensates for neutrals
405
- if sentiment_score == 0:
406
- neu_count += 1
407
- return pos_sum, neg_sum, neu_count
408
-
409
- def score_valence(self, sentiments, text):
410
- if sentiments:
411
- sum_s = float(sum(sentiments))
412
- # compute and add emphasis from punctuation in text
413
- punct_emph_amplifier = self._punctuation_emphasis(sum_s, text)
414
- if sum_s > 0:
415
- sum_s += punct_emph_amplifier
416
- elif sum_s < 0:
417
- sum_s -= punct_emph_amplifier
418
-
419
- compound = normalize(sum_s)
420
- # discriminate between positive, negative and neutral sentiment scores
421
- pos_sum, neg_sum, neu_count = self._sift_sentiment_scores(sentiments)
422
-
423
- if pos_sum > math.fabs(neg_sum):
424
- pos_sum += (punct_emph_amplifier)
425
- elif pos_sum < math.fabs(neg_sum):
426
- neg_sum -= (punct_emph_amplifier)
427
-
428
- total = pos_sum + math.fabs(neg_sum) + neu_count
429
- pos = math.fabs(pos_sum / total)
430
- neg = math.fabs(neg_sum / total)
431
- neu = math.fabs(neu_count / total)
432
-
433
- else:
434
- compound = 0.0
435
- pos = 0.0
436
- neg = 0.0
437
- neu = 0.0
438
-
439
- sentiment_dict = \
440
- {"neg" : round(neg, 3),
441
- "neu" : round(neu, 3),
442
- "pos" : round(pos, 3),
443
- "compound" : round(compound, 4)}
444
-
445
- return sentiment_dict
1
+ # coding: utf-8
2
+ # Natural Language Toolkit: vader
3
+ #
4
+ # Copyright (C) 2001-2018 NLTK Project
5
+ # Author: C.J. Hutto <Clayton.Hutto@gtri.gatech.edu>
6
+ # Ewan Klein <ewan@inf.ed.ac.uk> (modifications)
7
+ # Pierpaolo Pantone <24alsecondo@gmail.com> (modifications)
8
+ # George Berry <geb97@cornell.edu> (modifications)
9
+ # URL: <http://nltk.org/>
10
+ # For license information, see LICENSE.TXT
11
+ #
12
+ # Modifications to the original VADER code have been made in order to
13
+ # integrate it into NLTK. These have involved changes to
14
+ # ensure Python 3 compatibility, and refactoring to achieve greater modularity.
15
+
16
+ """
17
+ If you use the VADER sentiment analysis tools, please cite:
18
+
19
+ Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for
20
+ Sentiment Analysis of Social Media Text. Eighth International Conference on
21
+ Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
22
+ """
23
+
24
+ import codecs
25
+ import math
26
+ import re
27
+ import string
28
+ from itertools import product
29
+ import nltk.data
30
+ from .util import pairwise
31
+
32
+ ##Constants##
33
+
34
+ # (empirically derived mean sentiment intensity rating increase for booster words)
35
+ B_INCR = 0.293
36
+ B_DECR = -0.293
37
+
38
+ # (empirically derived mean sentiment intensity rating increase for using
39
+ # ALLCAPs to emphasize a word)
40
+ C_INCR = 0.733
41
+
42
+ N_SCALAR = -0.74
43
+
44
+ # for removing punctuation
45
+ REGEX_REMOVE_PUNCTUATION = re.compile('[{0}]'.format(re.escape(string.punctuation)))
46
+
47
+ PUNC_LIST = [".", "!", "?", ",", ";", ":", "-", "'", "\"",
48
+ "!!", "!!!", "??", "???", "?!?", "!?!", "?!?!", "!?!?"]
49
+ NEGATE = {"aint", "arent", "cannot", "cant", "couldnt", "darent", "didnt", "doesnt",
50
+ "ain't", "aren't", "can't", "couldn't", "daren't", "didn't", "doesn't",
51
+ "dont", "hadnt", "hasnt", "havent", "isnt", "mightnt", "mustnt", "neither",
52
+ "don't", "hadn't", "hasn't", "haven't", "isn't", "mightn't", "mustn't",
53
+ "neednt", "needn't", "never", "none", "nope", "nor", "not", "nothing", "nowhere",
54
+ "oughtnt", "shant", "shouldnt", "uhuh", "wasnt", "werent",
55
+ "oughtn't", "shan't", "shouldn't", "uh-uh", "wasn't", "weren't",
56
+ "without", "wont", "wouldnt", "won't", "wouldn't", "rarely", "seldom", "despite"}
57
+
58
+ # booster/dampener 'intensifiers' or 'degree adverbs'
59
+ # http://en.wiktionary.org/wiki/Category:English_degree_adverbs
60
+
61
+ BOOSTER_DICT = \
62
+ {"absolutely": B_INCR, "amazingly": B_INCR, "awfully": B_INCR, "completely": B_INCR, "considerably": B_INCR,
63
+ "decidedly": B_INCR, "deeply": B_INCR, "effing": B_INCR, "enormously": B_INCR,
64
+ "entirely": B_INCR, "especially": B_INCR, "exceptionally": B_INCR, "extremely": B_INCR,
65
+ "fabulously": B_INCR, "flipping": B_INCR, "flippin": B_INCR,
66
+ "fricking": B_INCR, "frickin": B_INCR, "frigging": B_INCR, "friggin": B_INCR, "fully": B_INCR, "fucking": B_INCR,
67
+ "greatly": B_INCR, "hella": B_INCR, "highly": B_INCR, "hugely": B_INCR, "incredibly": B_INCR,
68
+ "intensely": B_INCR, "majorly": B_INCR, "more": B_INCR, "most": B_INCR, "particularly": B_INCR,
69
+ "purely": B_INCR, "quite": B_INCR, "really": B_INCR, "remarkably": B_INCR,
70
+ "so": B_INCR, "substantially": B_INCR,
71
+ "thoroughly": B_INCR, "totally": B_INCR, "tremendously": B_INCR,
72
+ "uber": B_INCR, "unbelievably": B_INCR, "unusually": B_INCR, "utterly": B_INCR,
73
+ "very": B_INCR,
74
+ "almost": B_DECR, "barely": B_DECR, "hardly": B_DECR, "just enough": B_DECR,
75
+ "kind of": B_DECR, "kinda": B_DECR, "kindof": B_DECR, "kind-of": B_DECR,
76
+ "less": B_DECR, "little": B_DECR, "marginally": B_DECR, "occasionally": B_DECR, "partly": B_DECR,
77
+ "scarcely": B_DECR, "slightly": B_DECR, "somewhat": B_DECR,
78
+ "sort of": B_DECR, "sorta": B_DECR, "sortof": B_DECR, "sort-of": B_DECR}
79
+
80
+ # check for special case idioms using a sentiment-laden keyword known to SAGE
81
+ SPECIAL_CASE_IDIOMS = {"the shit": 3, "the bomb": 3, "bad ass": 1.5, "yeah right": -2,
82
+ "cut the mustard": 2, "kiss of death": -1.5, "hand to mouth": -2}
83
+
84
+
85
+ ##Static methods##
86
+
87
+ def negated(input_words, include_nt=True):
88
+ """
89
+ Determine if input contains negation words
90
+ """
91
+ neg_words = NEGATE
92
+ if any(word.lower() in neg_words for word in input_words):
93
+ return True
94
+ if include_nt:
95
+ if any("n't" in word.lower() for word in input_words):
96
+ return True
97
+ for first, second in pairwise(input_words):
98
+ if second.lower() == "least" and first.lower() != 'at':
99
+ return True
100
+ return False
101
+
102
+
103
+ def normalize(score, alpha=15):
104
+ """
105
+ Normalize the score to be between -1 and 1 using an alpha that
106
+ approximates the max expected value
107
+ """
108
+ norm_score = score/math.sqrt((score*score) + alpha)
109
+ return norm_score
110
+
111
+
112
+ def allcap_differential(words):
113
+ """
114
+ Check whether just some words in the input are ALL CAPS
115
+
116
+ :param list words: The words to inspect
117
+ :returns: `True` if some but not all items in `words` are ALL CAPS
118
+ """
119
+ is_different = False
120
+ allcap_words = 0
121
+ for word in words:
122
+ if word.isupper():
123
+ allcap_words += 1
124
+ cap_differential = len(words) - allcap_words
125
+ if cap_differential > 0 and cap_differential < len(words):
126
+ is_different = True
127
+ return is_different
128
+
129
+
130
+ def scalar_inc_dec(word, valence, is_cap_diff):
131
+ """
132
+ Check if the preceding words increase, decrease, or negate/nullify the
133
+ valence
134
+ """
135
+ scalar = 0.0
136
+ word_lower = word.lower()
137
+ if word_lower in BOOSTER_DICT:
138
+ scalar = BOOSTER_DICT[word_lower]
139
+ if valence < 0:
140
+ scalar *= -1
141
+ #check if booster/dampener word is in ALLCAPS (while others aren't)
142
+ if word.isupper() and is_cap_diff:
143
+ if valence > 0:
144
+ scalar += C_INCR
145
+ else: scalar -= C_INCR
146
+ return scalar
147
+
148
+ class SentiText(object):
149
+ """
150
+ Identify sentiment-relevant string-level properties of input text.
151
+ """
152
+ def __init__(self, text):
153
+ if not isinstance(text, str):
154
+ text = str(text.encode('utf-8'))
155
+ self.text = text
156
+ self.words_and_emoticons = self._words_and_emoticons()
157
+ # doesn't separate words from\
158
+ # adjacent punctuation (keeps emoticons & contractions)
159
+ self.is_cap_diff = allcap_differential(self.words_and_emoticons)
160
+
161
+ def _words_plus_punc(self):
162
+ """
163
+ Returns mapping of form:
164
+ {
165
+ 'cat,': 'cat',
166
+ ',cat': 'cat',
167
+ }
168
+ """
169
+ no_punc_text = REGEX_REMOVE_PUNCTUATION.sub('', self.text)
170
+ # removes punctuation (but loses emoticons & contractions)
171
+ words_only = no_punc_text.split()
172
+ # remove singletons
173
+ words_only = set( w for w in words_only if len(w) > 1 )
174
+ # the product gives ('cat', ',') and (',', 'cat')
175
+ punc_before = {''.join(p): p[1] for p in product(PUNC_LIST, words_only)}
176
+ punc_after = {''.join(p): p[0] for p in product(words_only, PUNC_LIST)}
177
+ words_punc_dict = punc_before
178
+ words_punc_dict.update(punc_after)
179
+ return words_punc_dict
180
+
181
+ def _words_and_emoticons(self):
182
+ """
183
+ Removes leading and trailing puncutation
184
+ Leaves contractions and most emoticons
185
+ Does not preserve punc-plus-letter emoticons (e.g. :D)
186
+ """
187
+ wes = self.text.split()
188
+ words_punc_dict = self._words_plus_punc()
189
+ wes = [we for we in wes if len(we) > 1]
190
+ for i, we in enumerate(wes):
191
+ if we in words_punc_dict:
192
+ wes[i] = words_punc_dict[we]
193
+ return wes
194
+
195
+ class SentimentIntensityAnalyzer(object):
196
+ """
197
+ Give a sentiment intensity score to sentences.
198
+ """
199
+ def __init__(self, lexicon_file="sentiment/vader_lexicon.zip/vader_lexicon/vader_lexicon.txt"):
200
+ self.lexicon_file = nltk.data.load(lexicon_file)
201
+ self.lexicon = self.make_lex_dict()
202
+
203
+ def make_lex_dict(self):
204
+ """
205
+ Convert lexicon file to a dictionary
206
+ """
207
+ lex_dict = {}
208
+ for line in self.lexicon_file.split('\n'):
209
+ (word, measure) = line.strip().split('\t')[0:2]
210
+ lex_dict[word] = float(measure)
211
+ return lex_dict
212
+
213
+ def polarity_scores(self, text):
214
+ """
215
+ Return a float for sentiment strength based on the input text.
216
+ Positive values are positive valence, negative value are negative
217
+ valence.
218
+ """
219
+ sentitext = SentiText(text)
220
+ #text, words_and_emoticons, is_cap_diff = self.preprocess(text)
221
+
222
+ sentiments = []
223
+ words_and_emoticons = sentitext.words_and_emoticons
224
+ for item in words_and_emoticons:
225
+ valence = 0
226
+ i = words_and_emoticons.index(item)
227
+ if (i < len(words_and_emoticons) - 1 and item.lower() == "kind" and \
228
+ words_and_emoticons[i+1].lower() == "of") or \
229
+ item.lower() in BOOSTER_DICT:
230
+ sentiments.append(valence)
231
+ continue
232
+
233
+ sentiments = self.sentiment_valence(valence, sentitext, item, i, sentiments)
234
+
235
+ sentiments = self._but_check(words_and_emoticons, sentiments)
236
+
237
+ return self.score_valence(sentiments, text)
238
+
239
+ def sentiment_valence(self, valence, sentitext, item, i, sentiments):
240
+ is_cap_diff = sentitext.is_cap_diff
241
+ words_and_emoticons = sentitext.words_and_emoticons
242
+ item_lowercase = item.lower()
243
+ if item_lowercase in self.lexicon:
244
+ #get the sentiment valence
245
+ valence = self.lexicon[item_lowercase]
246
+
247
+ #check if sentiment laden word is in ALL CAPS (while others aren't)
248
+ if item.isupper() and is_cap_diff:
249
+ if valence > 0:
250
+ valence += C_INCR
251
+ else:
252
+ valence -= C_INCR
253
+
254
+ for start_i in range(0,3):
255
+ if i > start_i and words_and_emoticons[i-(start_i+1)].lower() not in self.lexicon:
256
+ # dampen the scalar modifier of preceding words and emoticons
257
+ # (excluding the ones that immediately preceed the item) based
258
+ # on their distance from the current item.
259
+ s = scalar_inc_dec(words_and_emoticons[i-(start_i+1)], valence, is_cap_diff)
260
+ if start_i == 1 and s != 0:
261
+ s = s*0.95
262
+ if start_i == 2 and s != 0:
263
+ s = s*0.9
264
+ valence = valence+s
265
+ valence = self._never_check(valence, words_and_emoticons, start_i, i)
266
+ if start_i == 2:
267
+ valence = self._idioms_check(valence, words_and_emoticons, i)
268
+
269
+ # future work: consider other sentiment-laden idioms
270
+ # other_idioms =
271
+ # {"back handed": -2, "blow smoke": -2, "blowing smoke": -2,
272
+ # "upper hand": 1, "break a leg": 2,
273
+ # "cooking with gas": 2, "in the black": 2, "in the red": -2,
274
+ # "on the ball": 2,"under the weather": -2}
275
+
276
+ valence = self._least_check(valence, words_and_emoticons, i)
277
+
278
+ sentiments.append(valence)
279
+ return sentiments
280
+
281
+ def _least_check(self, valence, words_and_emoticons, i):
282
+ # check for negation case using "least"
283
+ if i > 1 and words_and_emoticons[i-1].lower() not in self.lexicon \
284
+ and words_and_emoticons[i-1].lower() == "least":
285
+ if words_and_emoticons[i-2].lower() != "at" and words_and_emoticons[i-2].lower() != "very":
286
+ valence = valence*N_SCALAR
287
+ elif i > 0 and words_and_emoticons[i-1].lower() not in self.lexicon \
288
+ and words_and_emoticons[i-1].lower() == "least":
289
+ valence = valence*N_SCALAR
290
+ return valence
291
+
292
+ def _but_check(self, words_and_emoticons, sentiments):
293
+ # check for modification in sentiment due to contrastive conjunction 'but'
294
+ if 'but' in words_and_emoticons or 'BUT' in words_and_emoticons:
295
+ try:
296
+ bi = words_and_emoticons.index('but')
297
+ except ValueError:
298
+ bi = words_and_emoticons.index('BUT')
299
+ for sentiment in sentiments:
300
+ si = sentiments.index(sentiment)
301
+ if si < bi:
302
+ sentiments.pop(si)
303
+ sentiments.insert(si, sentiment*0.5)
304
+ elif si > bi:
305
+ sentiments.pop(si)
306
+ sentiments.insert(si, sentiment*1.5)
307
+ return sentiments
308
+
309
+ def _idioms_check(self, valence, words_and_emoticons, i):
310
+ onezero = "{0} {1}".format(words_and_emoticons[i-1], words_and_emoticons[i])
311
+
312
+ twoonezero = "{0} {1} {2}".format(words_and_emoticons[i-2],
313
+ words_and_emoticons[i-1], words_and_emoticons[i])
314
+
315
+ twoone = "{0} {1}".format(words_and_emoticons[i-2], words_and_emoticons[i-1])
316
+
317
+ threetwoone = "{0} {1} {2}".format(words_and_emoticons[i-3],
318
+ words_and_emoticons[i-2], words_and_emoticons[i-1])
319
+
320
+ threetwo = "{0} {1}".format(words_and_emoticons[i-3], words_and_emoticons[i-2])
321
+
322
+ sequences = [onezero, twoonezero, twoone, threetwoone, threetwo]
323
+
324
+ for seq in sequences:
325
+ if seq in SPECIAL_CASE_IDIOMS:
326
+ valence = SPECIAL_CASE_IDIOMS[seq]
327
+ break
328
+
329
+ if len(words_and_emoticons)-1 > i:
330
+ zeroone = "{0} {1}".format(words_and_emoticons[i], words_and_emoticons[i+1])
331
+ if zeroone in SPECIAL_CASE_IDIOMS:
332
+ valence = SPECIAL_CASE_IDIOMS[zeroone]
333
+ if len(words_and_emoticons)-1 > i+1:
334
+ zeroonetwo = "{0} {1} {2}".format(words_and_emoticons[i], words_and_emoticons[i+1], words_and_emoticons[i+2])
335
+ if zeroonetwo in SPECIAL_CASE_IDIOMS:
336
+ valence = SPECIAL_CASE_IDIOMS[zeroonetwo]
337
+
338
+ # check for booster/dampener bi-grams such as 'sort of' or 'kind of'
339
+ if threetwo in BOOSTER_DICT or twoone in BOOSTER_DICT:
340
+ valence = valence+B_DECR
341
+ return valence
342
+
343
+ def _never_check(self, valence, words_and_emoticons, start_i, i):
344
+ if start_i == 0:
345
+ if negated([words_and_emoticons[i-1]]):
346
+ valence = valence*N_SCALAR
347
+ if start_i == 1:
348
+ if words_and_emoticons[i-2] == "never" and\
349
+ (words_and_emoticons[i-1] == "so" or
350
+ words_and_emoticons[i-1] == "this"):
351
+ valence = valence*1.5
352
+ elif negated([words_and_emoticons[i-(start_i+1)]]):
353
+ valence = valence*N_SCALAR
354
+ if start_i == 2:
355
+ if words_and_emoticons[i-3] == "never" and \
356
+ (words_and_emoticons[i-2] == "so" or words_and_emoticons[i-2] == "this") or \
357
+ (words_and_emoticons[i-1] == "so" or words_and_emoticons[i-1] == "this"):
358
+ valence = valence*1.25
359
+ elif negated([words_and_emoticons[i-(start_i+1)]]):
360
+ valence = valence*N_SCALAR
361
+ return valence
362
+
363
+ def _punctuation_emphasis(self, sum_s, text):
364
+ # add emphasis from exclamation points and question marks
365
+ ep_amplifier = self._amplify_ep(text)
366
+ qm_amplifier = self._amplify_qm(text)
367
+ punct_emph_amplifier = ep_amplifier+qm_amplifier
368
+ return punct_emph_amplifier
369
+
370
+ def _amplify_ep(self, text):
371
+ # check for added emphasis resulting from exclamation points (up to 4 of them)
372
+ ep_count = text.count("!")
373
+ if ep_count > 4:
374
+ ep_count = 4
375
+ # (empirically derived mean sentiment intensity rating increase for
376
+ # exclamation points)
377
+ ep_amplifier = ep_count*0.292
378
+ return ep_amplifier
379
+
380
+ def _amplify_qm(self, text):
381
+ # check for added emphasis resulting from question marks (2 or 3+)
382
+ qm_count = text.count("?")
383
+ qm_amplifier = 0
384
+ if qm_count > 1:
385
+ if qm_count <= 3:
386
+ # (empirically derived mean sentiment intensity rating increase for
387
+ # question marks)
388
+ qm_amplifier = qm_count*0.18
389
+ else:
390
+ qm_amplifier = 0.96
391
+ return qm_amplifier
392
+
393
+ def _sift_sentiment_scores(self, sentiments):
394
+ # want separate positive versus negative sentiment scores
395
+ pos_sum = 0.0
396
+ neg_sum = 0.0
397
+ neu_count = 0
398
+ for sentiment_score in sentiments:
399
+ if sentiment_score > 0:
400
+ pos_sum += (float(sentiment_score) +1) # compensates for neutral words that are counted as 1
401
+ if sentiment_score < 0:
402
+ neg_sum += (float(sentiment_score) -1) # when used with math.fabs(), compensates for neutrals
403
+ if sentiment_score == 0:
404
+ neu_count += 1
405
+ return pos_sum, neg_sum, neu_count
406
+
407
+ def score_valence(self, sentiments, text):
408
+ if sentiments:
409
+ sum_s = float(sum(sentiments))
410
+ # compute and add emphasis from punctuation in text
411
+ punct_emph_amplifier = self._punctuation_emphasis(sum_s, text)
412
+ if sum_s > 0:
413
+ sum_s += punct_emph_amplifier
414
+ elif sum_s < 0:
415
+ sum_s -= punct_emph_amplifier
416
+
417
+ compound = normalize(sum_s)
418
+ # discriminate between positive, negative and neutral sentiment scores
419
+ pos_sum, neg_sum, neu_count = self._sift_sentiment_scores(sentiments)
420
+
421
+ if pos_sum > math.fabs(neg_sum):
422
+ pos_sum += (punct_emph_amplifier)
423
+ elif pos_sum < math.fabs(neg_sum):
424
+ neg_sum -= (punct_emph_amplifier)
425
+
426
+ total = pos_sum + math.fabs(neg_sum) + neu_count
427
+ pos = math.fabs(pos_sum / total)
428
+ neg = math.fabs(neg_sum / total)
429
+ neu = math.fabs(neu_count / total)
430
+
431
+ else:
432
+ compound = 0.0
433
+ pos = 0.0
434
+ neg = 0.0
435
+ neu = 0.0
436
+
437
+ sentiment_dict = \
438
+ {"neg" : round(neg, 3),
439
+ "neu" : round(neu, 3),
440
+ "pos" : round(pos, 3),
441
+ "compound" : round(compound, 4)}
442
+
443
+ return sentiment_dict