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,2212 +1,2200 @@
1
- .. Copyright (C) 2001-2015 NLTK Project
2
- .. For license information, see LICENSE.TXT
3
-
4
- ================
5
- Corpus Readers
6
- ================
7
-
8
- The `nltk.corpus` package defines a collection of *corpus reader*
9
- classes, which can be used to access the contents of a diverse set of
10
- corpora. The list of available corpora is given at:
11
-
12
- http://www.nltk.org/nltk_data/
13
-
14
- Each corpus reader class is specialized to handle a specific
15
- corpus format. In addition, the `nltk.corpus` package automatically
16
- creates a set of corpus reader instances that can be used to access
17
- the corpora in the NLTK data package.
18
- Section `Corpus Reader Objects`_ ("Corpus Reader Objects") describes
19
- the corpus reader instances that can be used to read the corpora in
20
- the NLTK data package. Section `Corpus Reader Classes`_ ("Corpus
21
- Reader Classes") describes the corpus reader classes themselves, and
22
- discusses the issues involved in creating new corpus reader objects
23
- and new corpus reader classes. Section `Regression Tests`_
24
- ("Regression Tests") contains regression tests for the corpus readers
25
- and associated functions and classes.
26
-
27
- .. contents:: **Table of Contents**
28
- :depth: 2
29
- :backlinks: none
30
-
31
- ---------------------
32
- Corpus Reader Objects
33
- ---------------------
34
-
35
- Overview
36
- ========
37
-
38
- NLTK includes a diverse set of corpora which can be
39
- read using the ``nltk.corpus`` package. Each corpus is accessed by
40
- means of a "corpus reader" object from ``nltk.corpus``:
41
-
42
- >>> import nltk.corpus
43
- >>> # The Brown corpus:
44
- >>> print(str(nltk.corpus.brown).replace('\\\\','/'))
45
- <CategorizedTaggedCorpusReader in '.../corpora/brown'...>
46
- >>> # The Penn Treebank Corpus:
47
- >>> print(str(nltk.corpus.treebank).replace('\\\\','/'))
48
- <BracketParseCorpusReader in '.../corpora/treebank/combined'...>
49
- >>> # The Name Genders Corpus:
50
- >>> print(str(nltk.corpus.names).replace('\\\\','/'))
51
- <WordListCorpusReader in '.../corpora/names'...>
52
- >>> # The Inaugural Address Corpus:
53
- >>> print(str(nltk.corpus.inaugural).replace('\\\\','/'))
54
- <PlaintextCorpusReader in '.../corpora/inaugural'...>
55
-
56
- Most corpora consist of a set of files, each containing a document (or
57
- other pieces of text). A list of identifiers for these files is
58
- accessed via the ``fileids()`` method of the corpus reader:
59
-
60
- >>> nltk.corpus.treebank.fileids() # doctest: +ELLIPSIS
61
- ['wsj_0001.mrg', 'wsj_0002.mrg', 'wsj_0003.mrg', 'wsj_0004.mrg', ...]
62
- >>> nltk.corpus.inaugural.fileids() # doctest: +ELLIPSIS
63
- ['1789-Washington.txt', '1793-Washington.txt', '1797-Adams.txt', ...]
64
-
65
- Each corpus reader provides a variety of methods to read data from the
66
- corpus, depending on the format of the corpus. For example, plaintext
67
- corpora support methods to read the corpus as raw text, a list of
68
- words, a list of sentences, or a list of paragraphs.
69
-
70
- >>> from nltk.corpus import inaugural
71
- >>> inaugural.raw('1789-Washington.txt') # doctest: +ELLIPSIS
72
- 'Fellow-Citizens of the Senate ...'
73
- >>> inaugural.words('1789-Washington.txt')
74
- ['Fellow', '-', 'Citizens', 'of', 'the', ...]
75
- >>> inaugural.sents('1789-Washington.txt') # doctest: +ELLIPSIS
76
- [['Fellow', '-', 'Citizens'...], ['Among', 'the', 'vicissitudes'...]...]
77
- >>> inaugural.paras('1789-Washington.txt') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
78
- [[['Fellow', '-', 'Citizens'...]],
79
- [['Among', 'the', 'vicissitudes'...],
80
- ['On', 'the', 'one', 'hand', ',', 'I'...]...]...]
81
-
82
- Each of these reader methods may be given a single document's item
83
- name or a list of document item names. When given a list of document
84
- item names, the reader methods will concatenate together the contents
85
- of the individual documents.
86
-
87
- >>> l1 = len(inaugural.words('1789-Washington.txt'))
88
- >>> l2 = len(inaugural.words('1793-Washington.txt'))
89
- >>> l3 = len(inaugural.words(['1789-Washington.txt', '1793-Washington.txt']))
90
- >>> print('%s+%s == %s' % (l1, l2, l3))
91
- 1538+147 == 1685
92
-
93
- If the reader methods are called without any arguments, they will
94
- typically load all documents in the corpus.
95
-
96
- >>> len(inaugural.words())
97
- 145735
98
-
99
- If a corpus contains a README file, it can be accessed with a ``readme()`` method:
100
-
101
- >>> inaugural.readme()[:32]
102
- 'C-Span Inaugural Address Corpus\n'
103
-
104
- Plaintext Corpora
105
- =================
106
-
107
- Here are the first few words from each of NLTK's plaintext corpora:
108
-
109
- >>> nltk.corpus.abc.words()
110
- ['PM', 'denies', 'knowledge', 'of', 'AWB', ...]
111
- >>> nltk.corpus.genesis.words()
112
- [u'In', u'the', u'beginning', u'God', u'created', ...]
113
- >>> nltk.corpus.gutenberg.words(fileids='austen-emma.txt')
114
- ['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ...]
115
- >>> nltk.corpus.inaugural.words()
116
- ['Fellow', '-', 'Citizens', 'of', 'the', ...]
117
- >>> nltk.corpus.state_union.words()
118
- ['PRESIDENT', 'HARRY', 'S', '.', 'TRUMAN', "'", ...]
119
- >>> nltk.corpus.webtext.words()
120
- ['Cookie', 'Manager', ':', '"', 'Don', "'", 't', ...]
121
-
122
- Tagged Corpora
123
- ==============
124
-
125
- In addition to the plaintext corpora, NLTK's data package also
126
- contains a wide variety of annotated corpora. For example, the Brown
127
- Corpus is annotated with part-of-speech tags, and defines additional
128
- methods ``tagged_*()`` which words as `(word,tag)` tuples, rather
129
- than just bare word strings.
130
-
131
- >>> from nltk.corpus import brown
132
- >>> print(brown.words())
133
- ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
134
- >>> print(brown.tagged_words())
135
- [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
136
- >>> print(brown.sents()) # doctest: +ELLIPSIS
137
- [['The', 'Fulton', 'County'...], ['The', 'jury', 'further'...], ...]
138
- >>> print(brown.tagged_sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
139
- [[('The', 'AT'), ('Fulton', 'NP-TL')...],
140
- [('The', 'AT'), ('jury', 'NN'), ('further', 'RBR')...]...]
141
- >>> print(brown.paras(categories='reviews')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
142
- [[['It', 'is', 'not', 'news', 'that', 'Nathan', 'Milstein'...],
143
- ['Certainly', 'not', 'in', 'Orchestra', 'Hall', 'where'...]],
144
- [['There', 'was', 'about', 'that', 'song', 'something', ...],
145
- ['Not', 'the', 'noblest', 'performance', 'we', 'have', ...], ...], ...]
146
- >>> print(brown.tagged_paras(categories='reviews')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
147
- [[[('It', 'PPS'), ('is', 'BEZ'), ('not', '*'), ...],
148
- [('Certainly', 'RB'), ('not', '*'), ('in', 'IN'), ...]],
149
- [[('There', 'EX'), ('was', 'BEDZ'), ('about', 'IN'), ...],
150
- [('Not', '*'), ('the', 'AT'), ('noblest', 'JJT'), ...], ...], ...]
151
-
152
- Similarly, the Indian Language POS-Tagged Corpus includes samples of
153
- Indian text annotated with part-of-speech tags:
154
-
155
- >>> from nltk.corpus import indian
156
- >>> print(indian.words()) # doctest: +SKIP
157
- ['\xe0\xa6\xae\xe0\xa6\xb9\xe0\xa6\xbf\...',
158
- '\xe0\xa6\xb8\xe0\xa6\xa8\xe0\xa7\x8d\xe0...', ...]
159
- >>> print(indian.tagged_words()) # doctest: +SKIP
160
- [('\xe0\xa6\xae\xe0\xa6\xb9\xe0\xa6\xbf...', 'NN'),
161
- ('\xe0\xa6\xb8\xe0\xa6\xa8\xe0\xa7\x8d\xe0...', 'NN'), ...]
162
-
163
- Several tagged corpora support access to a simplified, universal tagset, e.g. where all nouns
164
- tags are collapsed to a single category ``NOUN``:
165
-
166
- >>> print(brown.tagged_sents(tagset='universal')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
167
- [[('The', 'DET'), ('Fulton', 'NOUN'), ('County', 'NOUN'), ('Grand', 'ADJ'), ('Jury', 'NOUN'), ...],
168
- [('The', 'DET'), ('jury', 'NOUN'), ('further', 'ADV'), ('said', 'VERB'), ('in', 'ADP'), ...]...]
169
- >>> from nltk.corpus import conll2000, switchboard
170
- >>> print(conll2000.tagged_words(tagset='universal')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
171
- [('Confidence', 'NOUN'), ('in', 'ADP'), ...]
172
-
173
- Use ``nltk.app.pos_concordance()`` to access a GUI for searching tagged corpora.
174
-
175
- Chunked Corpora
176
- ===============
177
-
178
- The CoNLL corpora also provide chunk structures, which are encoded as
179
- flat trees. The CoNLL 2000 Corpus includes phrasal chunks; and the
180
- CoNLL 2002 Corpus includes named entity chunks.
181
-
182
- >>> from nltk.corpus import conll2000, conll2002
183
- >>> print(conll2000.sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
184
- [['Confidence', 'in', 'the', 'pound', 'is', 'widely', ...],
185
- ['Chancellor', 'of', 'the', 'Exchequer', ...], ...]
186
- >>> for tree in conll2000.chunked_sents()[:2]:
187
- ... print(tree) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
188
- (S
189
- (NP Confidence/NN)
190
- (PP in/IN)
191
- (NP the/DT pound/NN)
192
- (VP is/VBZ widely/RB expected/VBN to/TO take/VB)
193
- (NP another/DT sharp/JJ dive/NN)
194
- if/IN
195
- ...)
196
- (S
197
- Chancellor/NNP
198
- (PP of/IN)
199
- (NP the/DT Exchequer/NNP)
200
- ...)
201
- >>> print(conll2002.sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
202
- [[u'Sao', u'Paulo', u'(', u'Brasil', u')', u',', ...], [u'-'], ...]
203
- >>> for tree in conll2002.chunked_sents()[:2]:
204
- ... print(tree) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
205
- (S
206
- (LOC Sao/NC Paulo/VMI)
207
- (/Fpa
208
- (LOC Brasil/NC)
209
- )/Fpt
210
- ...)
211
- (S -/Fg)
212
-
213
- .. note:: Since the CONLL corpora do not contain paragraph break
214
- information, these readers do not support the ``para()`` method.)
215
-
216
- .. warning:: if you call the conll corpora reader methods without any
217
- arguments, they will return the contents of the entire corpus,
218
- *including* the 'test' portions of the corpus.)
219
-
220
- SemCor is a subset of the Brown corpus tagged with WordNet senses and
221
- named entities. Both kinds of lexical items include multiword units,
222
- which are encoded as chunks (senses and part-of-speech tags pertain
223
- to the entire chunk).
224
-
225
- >>> from nltk.corpus import semcor
226
- >>> semcor.words()
227
- ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
228
- >>> semcor.chunks()
229
- [['The'], ['Fulton', 'County', 'Grand', 'Jury'], ...]
230
- >>> semcor.sents() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
231
- [['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...],
232
- ['The', 'jury', 'further', 'said', ...], ...]
233
- >>> semcor.chunk_sents() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
234
- [[['The'], ['Fulton', 'County', 'Grand', 'Jury'], ['said'], ...
235
- ['.']], [['The'], ['jury'], ['further'], ['said'], ... ['.']], ...]
236
- >>> list(map(str, semcor.tagged_chunks(tag='both')[:3]))
237
- ['(DT The)', "(Lemma('group.n.01.group') (NE (NNP Fulton County Grand Jury)))", "(Lemma('state.v.01.say') (VB said))"]
238
- >>> [[str(c) for c in s] for s in semcor.tagged_sents(tag='both')[:2]]
239
- [['(DT The)', "(Lemma('group.n.01.group') (NE (NNP Fulton County Grand Jury)))", ...
240
- '(None .)'], ['(DT The)', ... '(None .)']]
241
-
242
-
243
- The IEER corpus is another chunked corpus. This corpus is unusual in
244
- that each corpus item contains multiple documents. (This reflects the
245
- fact that each corpus file contains multiple documents.) The IEER
246
- corpus defines the `parsed_docs` method, which returns the documents
247
- in a given item as `IEERDocument` objects:
248
-
249
- >>> from nltk.corpus import ieer
250
- >>> ieer.fileids() # doctest: +NORMALIZE_WHITESPACE
251
- ['APW_19980314', 'APW_19980424', 'APW_19980429',
252
- 'NYT_19980315', 'NYT_19980403', 'NYT_19980407']
253
- >>> docs = ieer.parsed_docs('APW_19980314')
254
- >>> print(docs[0])
255
- <IEERDocument APW19980314.0391: 'Kenyans protest tax hikes'>
256
- >>> print(docs[0].docno)
257
- APW19980314.0391
258
- >>> print(docs[0].doctype)
259
- NEWS STORY
260
- >>> print(docs[0].date_time)
261
- 03/14/1998 10:36:00
262
- >>> print(docs[0].headline)
263
- (DOCUMENT Kenyans protest tax hikes)
264
- >>> print(docs[0].text) # doctest: +ELLIPSIS
265
- (DOCUMENT
266
- (LOCATION NAIROBI)
267
- ,
268
- (LOCATION Kenya)
269
- (
270
- (ORGANIZATION AP)
271
- )
272
- _
273
- (CARDINAL Thousands)
274
- of
275
- laborers,
276
- ...
277
- on
278
- (DATE Saturday)
279
- ...)
280
-
281
- Parsed Corpora
282
- ==============
283
-
284
- The Treebank corpora provide a syntactic parse for each sentence. The
285
- NLTK data package includes a 10% sample of the Penn Treebank (in
286
- ``treebank``), as well as the Sinica Treebank (in ``sinica_treebank``).
287
-
288
- Reading the Penn Treebank (Wall Street Journal sample):
289
-
290
- >>> from nltk.corpus import treebank
291
- >>> print(treebank.fileids()) # doctest: +ELLIPSIS
292
- ['wsj_0001.mrg', 'wsj_0002.mrg', 'wsj_0003.mrg', 'wsj_0004.mrg', ...]
293
- >>> print(treebank.words('wsj_0003.mrg'))
294
- ['A', 'form', 'of', 'asbestos', 'once', 'used', ...]
295
- >>> print(treebank.tagged_words('wsj_0003.mrg'))
296
- [('A', 'DT'), ('form', 'NN'), ('of', 'IN'), ...]
297
- >>> print(treebank.parsed_sents('wsj_0003.mrg')[0]) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
298
- (S
299
- (S-TPC-1
300
- (NP-SBJ
301
- (NP (NP (DT A) (NN form)) (PP (IN of) (NP (NN asbestos))))
302
- (RRC ...)...)...)
303
- ...
304
- (VP (VBD reported) (SBAR (-NONE- 0) (S (-NONE- *T*-1))))
305
- (. .))
306
-
307
- If you have access to a full installation of the Penn Treebank, NLTK
308
- can be configured to load it as well. Download the ``ptb`` package,
309
- and in the directory ``nltk_data/corpora/ptb`` place the ``BROWN``
310
- and ``WSJ`` directories of the Treebank installation (symlinks work
311
- as well). Then use the ``ptb`` module instead of ``treebank``:
312
-
313
- >>> from nltk.corpus import ptb
314
- >>> print(ptb.fileids()) # doctest: +SKIP
315
- ['BROWN/CF/CF01.MRG', 'BROWN/CF/CF02.MRG', 'BROWN/CF/CF03.MRG', 'BROWN/CF/CF04.MRG', ...]
316
- >>> print(ptb.words('WSJ/00/WSJ_0003.MRG')) # doctest: +SKIP
317
- ['A', 'form', 'of', 'asbestos', 'once', 'used', '*', ...]
318
- >>> print(ptb.tagged_words('WSJ/00/WSJ_0003.MRG')) # doctest: +SKIP
319
- [('A', 'DT'), ('form', 'NN'), ('of', 'IN'), ...]
320
-
321
- ...and so forth, like ``treebank`` but with extended fileids. Categories
322
- specified in ``allcats.txt`` can be used to filter by genre; they consist
323
- of ``news`` (for WSJ articles) and names of the Brown subcategories
324
- (``fiction``, ``humor``, ``romance``, etc.):
325
-
326
- >>> ptb.categories() # doctest: +SKIP
327
- ['adventure', 'belles_lettres', 'fiction', 'humor', 'lore', 'mystery', 'news', 'romance', 'science_fiction']
328
- >>> print(ptb.fileids('news')) # doctest: +SKIP
329
- ['WSJ/00/WSJ_0001.MRG', 'WSJ/00/WSJ_0002.MRG', 'WSJ/00/WSJ_0003.MRG', ...]
330
- >>> print(ptb.words(categories=['humor','fiction'])) # doctest: +SKIP
331
- ['Thirty-three', 'Scotty', 'did', 'not', 'go', 'back', ...]
332
-
333
- As PropBank and NomBank depend on the (WSJ portion of the) Penn Treebank,
334
- the modules ``propbank_ptb`` and ``nombank_ptb`` are provided for access
335
- to a full PTB installation.
336
-
337
- Reading the Sinica Treebank:
338
-
339
- >>> from nltk.corpus import sinica_treebank
340
- >>> print(sinica_treebank.sents()) # doctest: +SKIP
341
- [['\xe4\xb8\x80'], ['\xe5\x8f\x8b\xe6\x83\x85'], ...]
342
- >>> sinica_treebank.parsed_sents()[25] # doctest: +SKIP
343
- Tree('S',
344
- [Tree('NP',
345
- [Tree('Nba', ['\xe5\x98\x89\xe7\x8f\x8d'])]),
346
- Tree('V\xe2\x80\xa7\xe5\x9c\xb0',
347
- [Tree('VA11', ['\xe4\xb8\x8d\xe5\x81\x9c']),
348
- Tree('DE', ['\xe7\x9a\x84'])]),
349
- Tree('VA4', ['\xe5\x93\xad\xe6\xb3\xa3'])])
350
-
351
- Reading the CoNLL 2007 Dependency Treebanks:
352
-
353
- >>> from nltk.corpus import conll2007
354
- >>> conll2007.sents('esp.train')[0] # doctest: +SKIP
355
- ['El', 'aumento', 'del', 'índice', 'de', 'desempleo', ...]
356
- >>> conll2007.parsed_sents('esp.train')[0] # doctest: +SKIP
357
- <DependencyGraph with 38 nodes>
358
- >>> print(conll2007.parsed_sents('esp.train')[0].tree()) # doctest: +SKIP
359
- (fortaleció
360
- (aumento El (del (índice (de (desempleo estadounidense)))))
361
- hoy
362
- considerablemente
363
- (al
364
- (euro
365
- (cotizaba
366
- ,
367
- que
368
- (a (15.35 las GMT))
369
- se
370
- (en (mercado el (de divisas) (de Fráncfort)))
371
- (a 0,9452_dólares)
372
- (frente_a , (0,9349_dólares los (de (mañana esta)))))))
373
- .)
374
-
375
- NLTK also provides a corpus reader for the York-Toronto-Helsinki
376
- Parsed Corpus of Old English Prose (YCOE); but the corpus itself is
377
- not included in the NLTK data package. If you install it yourself,
378
- you can use NLTK to access it:
379
-
380
- >>> from nltk.corpus import ycoe
381
- >>> for tree in ycoe.parsed_sents('cocuraC')[:4]:
382
- ... print(tree) # doctest: +SKIP
383
- (CP-THT
384
- (C +D+atte)
385
- (IP-SUB ...)
386
- ...
387
- (. .))
388
- (IP-MAT
389
- (IP-MAT-0
390
- (PP (P On) (NP (ADJ o+dre) (N wisan)))...)
391
- ...
392
- (. .))
393
- (IP-MAT
394
- (NP-NOM-x-2 *exp*)
395
- (NP-DAT-1 (D^D +D+am) (ADJ^D unge+dyldegum))
396
- ...
397
- (. .))
398
- (IP-MAT
399
- (ADVP (ADV Sw+a))
400
- (NP-NOM-x (PRO^N hit))
401
- (ADVP-TMP (ADV^T oft))
402
- ...
403
- (. .))
404
-
405
- If the YCOE corpus is not available, you will get an error message
406
- when you try to access it:
407
-
408
- >>> from nltk.corpus import ycoe
409
- >>> print(ycoe) # doctest: +SKIP
410
- Traceback (most recent call last):
411
- LookupError:
412
- **********************************************************************
413
- Resource 'corpora/ycoe' not found. For installation
414
- instructions, please see <http://nltk.org/index.php/Installation>.
415
- Searched in:
416
- - ...
417
- **********************************************************************
418
-
419
- Word Lists and Lexicons
420
- =======================
421
-
422
- The NLTK data package also includes a number of lexicons and word
423
- lists. These are accessed just like text corpora. The following
424
- examples illustrate the use of the wordlist corpora:
425
-
426
- >>> from nltk.corpus import names, stopwords, words
427
- >>> words.fileids()
428
- ['en', 'en-basic']
429
- >>> words.words('en') # doctest: +ELLIPSIS
430
- ['A', 'a', 'aa', 'aal', 'aalii', 'aam', 'Aani', 'aardvark', 'aardwolf', ...]
431
-
432
- >>> stopwords.fileids() # doctest: +ELLIPSIS
433
- ['danish', 'dutch', 'english', 'finnish', 'french', 'german', 'hungarian', ...]
434
- >>> stopwords.words('portuguese') # doctest: +ELLIPSIS
435
- ['de', 'a', 'o', 'que', 'e', 'do', 'da', 'em', 'um', 'para', ...]
436
- >>> names.fileids()
437
- ['female.txt', 'male.txt']
438
- >>> names.words('male.txt') # doctest: +ELLIPSIS
439
- ['Aamir', 'Aaron', 'Abbey', 'Abbie', 'Abbot', 'Abbott', ...]
440
- >>> names.words('female.txt') # doctest: +ELLIPSIS
441
- ['Abagael', 'Abagail', 'Abbe', 'Abbey', 'Abbi', 'Abbie', ...]
442
-
443
- The CMU Pronunciation Dictionary corpus contains pronounciation
444
- transcriptions for over 100,000 words. It can be accessed as a list
445
- of entries (where each entry consists of a word, an identifier, and a
446
- transcription) or as a dictionary from words to lists of
447
- transcriptions. Transcriptions are encoded as tuples of phoneme
448
- strings.
449
-
450
- >>> from nltk.corpus import cmudict
451
- >>> print(cmudict.entries()[653:659]) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
452
- [('acetate', ['AE1', 'S', 'AH0', 'T', 'EY2', 'T']),
453
- ('acetic', ['AH0', 'S', 'EH1', 'T', 'IH0', 'K']),
454
- ('acetic', ['AH0', 'S', 'IY1', 'T', 'IH0', 'K']),
455
- ('aceto', ['AA0', 'S', 'EH1', 'T', 'OW0']),
456
- ('acetochlor', ['AA0', 'S', 'EH1', 'T', 'OW0', 'K', 'L', 'AO2', 'R']),
457
- ('acetone', ['AE1', 'S', 'AH0', 'T', 'OW2', 'N'])]
458
- >>> # Load the entire cmudict corpus into a Python dictionary:
459
- >>> transcr = cmudict.dict()
460
- >>> print([transcr[w][0] for w in 'Natural Language Tool Kit'.lower().split()]) # doctest: +NORMALIZE_WHITESPACE
461
- [['N', 'AE1', 'CH', 'ER0', 'AH0', 'L'],
462
- ['L', 'AE1', 'NG', 'G', 'W', 'AH0', 'JH'],
463
- ['T', 'UW1', 'L'],
464
- ['K', 'IH1', 'T']]
465
-
466
-
467
- WordNet
468
- =======
469
-
470
- Please see the separate WordNet howto.
471
-
472
- FrameNet
473
- ========
474
-
475
- Please see the separate FrameNet howto.
476
-
477
- PropBank
478
- ========
479
-
480
- Please see the separate PropBank howto.
481
-
482
- SentiWordNet
483
- ============
484
-
485
- Please see the separate SentiWordNet howto.
486
-
487
- Categorized Corpora
488
- ===================
489
-
490
- Several corpora included with NLTK contain documents that have been categorized for
491
- topic, genre, polarity, etc. In addition to the standard corpus interface, these
492
- corpora provide access to the list of categories and the mapping between the documents
493
- and their categories (in both directions). Access the categories using the ``categories()``
494
- method, e.g.:
495
-
496
- >>> from nltk.corpus import brown, movie_reviews, reuters
497
- >>> brown.categories() # doctest: +NORMALIZE_WHITESPACE
498
- ['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor',
499
- 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']
500
- >>> movie_reviews.categories()
501
- ['neg', 'pos']
502
- >>> reuters.categories() # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
503
- ['acq', 'alum', 'barley', 'bop', 'carcass', 'castor-oil', 'cocoa',
504
- 'coconut', 'coconut-oil', 'coffee', 'copper', 'copra-cake', 'corn',
505
- 'cotton', 'cotton-oil', 'cpi', 'cpu', 'crude', 'dfl', 'dlr', ...]
506
-
507
- This method has an optional argument that specifies a document or a list
508
- of documents, allowing us to map from (one or more) documents to (one or more) categories:
509
-
510
- >>> brown.categories('ca01')
511
- ['news']
512
- >>> brown.categories(['ca01','cb01'])
513
- ['editorial', 'news']
514
- >>> reuters.categories('training/9865')
515
- ['barley', 'corn', 'grain', 'wheat']
516
- >>> reuters.categories(['training/9865', 'training/9880'])
517
- ['barley', 'corn', 'grain', 'money-fx', 'wheat']
518
-
519
- We can go back the other way using the optional argument of the ``fileids()`` method:
520
-
521
- >>> reuters.fileids('barley') # doctest: +ELLIPSIS
522
- ['test/15618', 'test/15649', 'test/15676', 'test/15728', 'test/15871', ...]
523
-
524
- Both the ``categories()`` and ``fileids()`` methods return a sorted list containing
525
- no duplicates.
526
-
527
- In addition to mapping between categories and documents, these corpora permit
528
- direct access to their contents via the categories. Instead of accessing a subset
529
- of a corpus by specifying one or more fileids, we can identify one or more categories, e.g.:
530
-
531
- >>> brown.tagged_words(categories='news')
532
- [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
533
- >>> brown.sents(categories=['editorial','reviews']) # doctest: +NORMALIZE_WHITESPACE
534
- [['Assembly', 'session', 'brought', 'much', 'good'], ['The', 'General',
535
- 'Assembly', ',', 'which', 'adjourns', 'today', ',', 'has', 'performed',
536
- 'in', 'an', 'atmosphere', 'of', 'crisis', 'and', 'struggle', 'from',
537
- 'the', 'day', 'it', 'convened', '.'], ...]
538
-
539
- Note that it is an error to specify both documents and categories.
540
-
541
- In the context of a text categorization system, we can easily test if the
542
- category assigned to a document is correct as follows:
543
-
544
- >>> def classify(doc): return 'news' # Trivial classifier
545
- >>> doc = 'ca01'
546
- >>> classify(doc) in brown.categories(doc)
547
- True
548
-
549
-
550
- Other Corpora
551
- =============
552
-
553
- comparative_sentences
554
- ---------------------
555
- A list of sentences from various sources, especially reviews and articles. Each
556
- line contains one sentence; sentences were separated by using a sentence tokenizer.
557
- Comparative sentences have been annotated with their type, entities, features and
558
- keywords.
559
-
560
- >>> from nltk.corpus import comparative_sentences
561
- >>> comparison = comparative_sentences.comparisons()[0]
562
- >>> comparison.text
563
- ['its', 'fast-forward', 'and', 'rewind', 'work', 'much', 'more', 'smoothly',
564
- 'and', 'consistently', 'than', 'those', 'of', 'other', 'models', 'i', "'ve",
565
- 'had', '.']
566
- >>> comparison.entity_2
567
- 'models'
568
- >>> (comparison.feature, comparison.keyword)
569
- ('rewind', 'more')
570
- >>> len(comparative_sentences.comparisons())
571
- 853
572
-
573
- opinion_lexicon
574
- ---------------
575
- A list of positive and negative opinion words or sentiment words for English.
576
-
577
- >>> from nltk.corpus import opinion_lexicon
578
- >>> opinion_lexicon.words()[:4]
579
- ['2-faced', '2-faces', 'abnormal', 'abolish']
580
-
581
- The OpinionLexiconCorpusReader also provides shortcuts to retrieve positive/negative
582
- words:
583
-
584
- >>> opinion_lexicon.negative()[:4]
585
- ['2-faced', '2-faces', 'abnormal', 'abolish']
586
-
587
- Note that words from `words()` method in opinion_lexicon are sorted by file id,
588
- not alphabetically:
589
-
590
- >>> opinion_lexicon.words()[0:10]
591
- ['2-faced', '2-faces', 'abnormal', 'abolish', 'abominable', 'abominably',
592
- 'abominate', 'abomination', 'abort', 'aborted']
593
- >>> sorted(opinion_lexicon.words())[0:10]
594
- ['2-faced', '2-faces', 'a+', 'abnormal', 'abolish', 'abominable', 'abominably',
595
- 'abominate', 'abomination', 'abort']
596
-
597
- ppattach
598
- --------
599
- The Prepositional Phrase Attachment corpus is a corpus of
600
- prepositional phrase attachment decisions. Each instance in the
601
- corpus is encoded as a ``PPAttachment`` object:
602
-
603
- >>> from nltk.corpus import ppattach
604
- >>> ppattach.attachments('training') # doctest: +NORMALIZE_WHITESPACE
605
- [PPAttachment(sent='0', verb='join', noun1='board',
606
- prep='as', noun2='director', attachment='V'),
607
- PPAttachment(sent='1', verb='is', noun1='chairman',
608
- prep='of', noun2='N.V.', attachment='N'),
609
- ...]
610
- >>> inst = ppattach.attachments('training')[0]
611
- >>> (inst.sent, inst.verb, inst.noun1, inst.prep, inst.noun2)
612
- ('0', 'join', 'board', 'as', 'director')
613
- >>> inst.attachment
614
- 'V'
615
-
616
- product_reviews_1 and product_reviews_2
617
- ---------------------------------------
618
- These two datasets respectively contain annotated customer reviews of 5 and 9
619
- products from amazon.com.
620
-
621
- >>> from nltk.corpus import product_reviews_1
622
- >>> camera_reviews = product_reviews_1.reviews('Canon_G3.txt')
623
- >>> review = camera_reviews[0]
624
- >>> review.sents()[0]
625
- ['i', 'recently', 'purchased', 'the', 'canon', 'powershot', 'g3', 'and', 'am',
626
- 'extremely', 'satisfied', 'with', 'the', 'purchase', '.']
627
- >>> review.features()
628
- [('canon powershot g3', '+3'), ('use', '+2'), ('picture', '+2'),
629
- ('picture quality', '+1'), ('picture quality', '+1'), ('camera', '+2'),
630
- ('use', '+2'), ('feature', '+1'), ('picture quality', '+3'), ('use', '+1'),
631
- ('option', '+1')]
632
-
633
- It is also possible to reach the same information directly from the stream:
634
-
635
- >>> product_reviews_1.features('Canon_G3.txt')
636
- [('canon powershot g3', '+3'), ('use', '+2'), ...]
637
-
638
- We can compute stats for specific product features:
639
-
640
- >>> from __future__ import division
641
- >>> n_reviews = len([(feat,score) for (feat,score) in product_reviews_1.features('Canon_G3.txt') if feat=='picture'])
642
- >>> tot = sum([int(score) for (feat,score) in product_reviews_1.features('Canon_G3.txt') if feat=='picture'])
643
- >>> # We use float for backward compatibility with division in Python2.7
644
- >>> mean = tot/n_reviews
645
- >>> print(n_reviews, tot, mean)
646
- 15 24 1.6
647
-
648
- pros_cons
649
- ---------
650
- A list of pros/cons sentences for determining context (aspect) dependent
651
- sentiment words, which are then applied to sentiment analysis of comparative
652
- sentences.
653
-
654
- >>> from nltk.corpus import pros_cons
655
- >>> pros_cons.sents(categories='Cons')
656
- [['East', 'batteries', '!', 'On', '-', 'off', 'switch', 'too', 'easy',
657
- 'to', 'maneuver', '.'], ['Eats', '...', 'no', ',', 'GULPS', 'batteries'],
658
- ...]
659
- >>> pros_cons.words('IntegratedPros.txt')
660
- ['Easy', 'to', 'use', ',', 'economical', '!', ...]
661
-
662
- semcor
663
- ------
664
- The Brown Corpus, annotated with WordNet senses.
665
-
666
- >>> from nltk.corpus import semcor
667
- >>> semcor.words('brown2/tagfiles/br-n12.xml') # doctest: +ELLIPSIS
668
- ['When', 'several', 'minutes', 'had', 'passed', ...]
669
- >>> sent = semcor.xml('brown2/tagfiles/br-n12.xml').findall('context/p/s')[0]
670
- >>> for wordform in sent.getchildren():
671
- ... print(wordform.text, end=' ')
672
- ... for key in sorted(wordform.keys()):
673
- ... print(key + '=' + wordform.get(key), end=' ')
674
- ... print()
675
- ...
676
- When cmd=ignore pos=WRB
677
- several cmd=done lemma=several lexsn=5:00:00:some(a):00 pos=JJ wnsn=1
678
- minutes cmd=done lemma=minute lexsn=1:28:00:: pos=NN wnsn=1
679
- had cmd=done ot=notag pos=VBD
680
- passed cmd=done lemma=pass lexsn=2:38:03:: pos=VB wnsn=4
681
- and cmd=ignore pos=CC
682
- Curt cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
683
- had cmd=done ot=notag pos=VBD
684
- n't cmd=done lemma=n't lexsn=4:02:00:: pos=RB wnsn=0
685
- emerged cmd=done lemma=emerge lexsn=2:30:00:: pos=VB wnsn=1
686
- from cmd=ignore pos=IN
687
- the cmd=ignore pos=DT
688
- livery_stable cmd=done lemma=livery_stable lexsn=1:06:00:: pos=NN wnsn=1
689
- ,
690
- Brenner cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
691
- re-entered cmd=done lemma=re-enter lexsn=2:38:00:: pos=VB wnsn=1
692
- the cmd=ignore pos=DT
693
- hotel cmd=done lemma=hotel lexsn=1:06:00:: pos=NN wnsn=1
694
- and cmd=ignore pos=CC
695
- faced cmd=done lemma=face lexsn=2:42:02:: pos=VB wnsn=4
696
- Summers cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
697
- across cmd=ignore pos=IN
698
- the cmd=ignore pos=DT
699
- counter cmd=done lemma=counter lexsn=1:06:00:: pos=NN wnsn=1
700
- .
701
-
702
- senseval
703
- --------
704
- The Senseval 2 corpus is a word sense disambiguation corpus. Each
705
- item in the corpus corresponds to a single ambiguous word. For each
706
- of these words, the corpus contains a list of instances, corresponding
707
- to occurrences of that word. Each instance provides the word; a list
708
- of word senses that apply to the word occurrence; and the word's
709
- context.
710
-
711
- >>> from nltk.corpus import senseval
712
- >>> senseval.fileids()
713
- ['hard.pos', 'interest.pos', 'line.pos', 'serve.pos']
714
- >>> senseval.instances('hard.pos')
715
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
716
- [SensevalInstance(word='hard-a',
717
- position=20,
718
- context=[('``', '``'), ('he', 'PRP'), ...('hard', 'JJ'), ...],
719
- senses=('HARD1',)),
720
- SensevalInstance(word='hard-a',
721
- position=10,
722
- context=[('clever', 'NNP'), ...('hard', 'JJ'), ('time', 'NN'), ...],
723
- senses=('HARD1',)), ...]
724
-
725
- The following code looks at instances of the word 'interest', and
726
- displays their local context (2 words on each side) and word sense(s):
727
-
728
- >>> for inst in senseval.instances('interest.pos')[:10]:
729
- ... p = inst.position
730
- ... left = ' '.join(w for (w,t) in inst.context[p-2:p])
731
- ... word = ' '.join(w for (w,t) in inst.context[p:p+1])
732
- ... right = ' '.join(w for (w,t) in inst.context[p+1:p+3])
733
- ... senses = ' '.join(inst.senses)
734
- ... print('%20s |%10s | %-15s -> %s' % (left, word, right, senses))
735
- declines in | interest | rates . -> interest_6
736
- indicate declining | interest | rates because -> interest_6
737
- in short-term | interest | rates . -> interest_6
738
- 4 % | interest | in this -> interest_5
739
- company with | interests | in the -> interest_5
740
- , plus | interest | . -> interest_6
741
- set the | interest | rate on -> interest_6
742
- 's own | interest | , prompted -> interest_4
743
- principal and | interest | is the -> interest_6
744
- increase its | interest | to 70 -> interest_5
745
-
746
- sentence_polarity
747
- -----------------
748
- The Sentence Polarity dataset contains 5331 positive and 5331 negative processed
749
- sentences.
750
-
751
- >>> from nltk.corpus import sentence_polarity
752
- >>> sentence_polarity.sents()
753
- [['simplistic', ',', 'silly', 'and', 'tedious', '.'], ["it's", 'so', 'laddish',
754
- 'and', 'juvenile', ',', 'only', 'teenage', 'boys', 'could', 'possibly', 'find',
755
- 'it', 'funny', '.'], ...]
756
- >>> sentence_polarity.categories()
757
- ['neg', 'pos']
758
- >>> sentence_polarity.sents()[1]
759
- ["it's", 'so', 'laddish', 'and', 'juvenile', ',', 'only', 'teenage', 'boys',
760
- 'could', 'possibly', 'find', 'it', 'funny', '.']
761
-
762
- shakespeare
763
- -----------
764
- The Shakespeare corpus contains a set of Shakespeare plays, formatted
765
- as XML files. These corpora are returned as ElementTree objects:
766
-
767
- >>> from nltk.corpus import shakespeare
768
- >>> from xml.etree import ElementTree
769
- >>> shakespeare.fileids() # doctest: +ELLIPSIS
770
- ['a_and_c.xml', 'dream.xml', 'hamlet.xml', 'j_caesar.xml', ...]
771
- >>> play = shakespeare.xml('dream.xml')
772
- >>> print(play) # doctest: +ELLIPSIS
773
- <Element 'PLAY' at ...>
774
- >>> print('%s: %s' % (play[0].tag, play[0].text))
775
- TITLE: A Midsummer Night's Dream
776
- >>> personae = [persona.text for persona in
777
- ... play.findall('PERSONAE/PERSONA')]
778
- >>> print(personae) # doctest: +ELLIPSIS
779
- ['THESEUS, Duke of Athens.', 'EGEUS, father to Hermia.', ...]
780
- >>> # Find and print speakers not listed as personae
781
- >>> names = [persona.split(',')[0] for persona in personae]
782
- >>> speakers = set(speaker.text for speaker in
783
- ... play.findall('*/*/*/SPEAKER'))
784
- >>> print(sorted(speakers.difference(names))) # doctest: +NORMALIZE_WHITESPACE
785
- ['ALL', 'COBWEB', 'DEMETRIUS', 'Fairy', 'HERNIA', 'LYSANDER',
786
- 'Lion', 'MOTH', 'MUSTARDSEED', 'Moonshine', 'PEASEBLOSSOM',
787
- 'Prologue', 'Pyramus', 'Thisbe', 'Wall']
788
-
789
- subjectivity
790
- -----------
791
- The Subjectivity Dataset contains 5000 subjective and 5000 objective processed
792
- sentences.
793
-
794
- >>> from nltk.corpus import subjectivity
795
- >>> subjectivity.categories()
796
- ['obj', 'subj']
797
- >>> subjectivity.sents()[23]
798
- ['television', 'made', 'him', 'famous', ',', 'but', 'his', 'biggest', 'hits',
799
- 'happened', 'off', 'screen', '.']
800
- >>> subjectivity.words(categories='subj')
801
- ['smart', 'and', 'alert', ',', 'thirteen', ...]
802
-
803
- toolbox
804
- -------
805
- The Toolbox corpus distributed with NLTK contains a sample lexicon and
806
- several sample texts from the Rotokas language. The Toolbox corpus
807
- reader returns Toolbox files as XML ElementTree objects. The
808
- following example loads the Rotokas dictionary, and figures out the
809
- distribution of part-of-speech tags for reduplicated words.
810
-
811
- .. doctest: +SKIP
812
-
813
- >>> from nltk.corpus import toolbox
814
- >>> from nltk.probability import FreqDist
815
- >>> from xml.etree import ElementTree
816
- >>> import re
817
- >>> rotokas = toolbox.xml('rotokas.dic')
818
- >>> redup_pos_freqdist = FreqDist()
819
- >>> # Note: we skip over the first record, which is actually
820
- >>> # the header.
821
- >>> for record in rotokas[1:]:
822
- ... lexeme = record.find('lx').text
823
- ... if re.match(r'(.*)\1$', lexeme):
824
- ... redup_pos_freqdist[record.find('ps').text] += 1
825
- >>> for item, count in redup_pos_freqdist.most_common():
826
- ... print(item, count)
827
- V 41
828
- N 14
829
- ??? 4
830
-
831
- This example displays some records from a Rotokas text:
832
-
833
- .. doctest: +SKIP
834
-
835
- >>> river = toolbox.xml('rotokas/river.txt', key='ref')
836
- >>> for record in river.findall('record')[:3]:
837
- ... for piece in record:
838
- ... if len(piece.text) > 60:
839
- ... print('%-6s %s...' % (piece.tag, piece.text[:57]))
840
- ... else:
841
- ... print('%-6s %s' % (piece.tag, piece.text))
842
- ref Paragraph 1
843
- t ``Viapau oisio ra ovaupasi ...
844
- m viapau oisio ra ovau -pa -si ...
845
- g NEG this way/like this and forget -PROG -2/3.DL...
846
- p NEG ??? CONJ V.I -SUFF.V.3 -SUFF.V...
847
- f ``No ken lus tingting wanema samting papa i bin tok,'' Na...
848
- fe ``Don't forget what Dad said,'' yelled Naomi.
849
- ref 2
850
- t Osa Ira ora Reviti viapau uvupasiva.
851
- m osa Ira ora Reviti viapau uvu -pa -si ...
852
- g as/like name and name NEG hear/smell -PROG -2/3...
853
- p CONJ N.PN CONJ N.PN NEG V.T -SUFF.V.3 -SUF...
854
- f Tasol Ila na David no bin harim toktok.
855
- fe But Ila and David took no notice.
856
- ref 3
857
- t Ikaupaoro rokosiva ...
858
- m ikau -pa -oro roko -si -va ...
859
- g run/hurry -PROG -SIM go down -2/3.DL.M -RP ...
860
- p V.T -SUFF.V.3 -SUFF.V.4 ADV -SUFF.V.4 -SUFF.VT....
861
- f Tupela i bin hariap i go long wara .
862
- fe They raced to the river.
863
-
864
- timit
865
- -----
866
- The NLTK data package includes a fragment of the TIMIT
867
- Acoustic-Phonetic Continuous Speech Corpus. This corpus is broken
868
- down into small speech samples, each of which is available as a wave
869
- file, a phonetic transcription, and a tokenized word list.
870
-
871
- >>> from nltk.corpus import timit
872
- >>> print(timit.utteranceids()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
873
- ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466',
874
- 'dr1-fvmh0/si2096', 'dr1-fvmh0/si836', 'dr1-fvmh0/sx116',
875
- 'dr1-fvmh0/sx206', 'dr1-fvmh0/sx26', 'dr1-fvmh0/sx296', ...]
876
-
877
- >>> item = timit.utteranceids()[5]
878
- >>> print(timit.phones(item)) # doctest: +NORMALIZE_WHITESPACE
879
- ['h#', 'k', 'l', 'ae', 's', 'pcl', 'p', 'dh', 'ax',
880
- 's', 'kcl', 'k', 'r', 'ux', 'ix', 'nx', 'y', 'ax',
881
- 'l', 'eh', 'f', 'tcl', 't', 'hh', 'ae', 'n', 'dcl',
882
- 'd', 'h#']
883
- >>> print(timit.words(item))
884
- ['clasp', 'the', 'screw', 'in', 'your', 'left', 'hand']
885
- >>> timit.play(item) # doctest: +SKIP
886
-
887
- The corpus reader can combine the word segmentation information with
888
- the phonemes to produce a single tree structure:
889
-
890
- >>> for tree in timit.phone_trees(item):
891
- ... print(tree)
892
- (S
893
- h#
894
- (clasp k l ae s pcl p)
895
- (the dh ax)
896
- (screw s kcl k r ux)
897
- (in ix nx)
898
- (your y ax)
899
- (left l eh f tcl t)
900
- (hand hh ae n dcl d)
901
- h#)
902
-
903
- The start time and stop time of each phoneme, word, and sentence are
904
- also available:
905
-
906
- >>> print(timit.phone_times(item)) # doctest: +ELLIPSIS
907
- [('h#', 0, 2190), ('k', 2190, 3430), ('l', 3430, 4326), ...]
908
- >>> print(timit.word_times(item)) # doctest: +ELLIPSIS
909
- [('clasp', 2190, 8804), ('the', 8804, 9734), ...]
910
- >>> print(timit.sent_times(item))
911
- [('Clasp the screw in your left hand.', 0, 32154)]
912
-
913
- We can use these times to play selected pieces of a speech sample:
914
-
915
- >>> timit.play(item, 2190, 8804) # 'clasp' # doctest: +SKIP
916
-
917
- The corpus reader can also be queried for information about the
918
- speaker and sentence identifier for a given speech sample:
919
-
920
- >>> print(timit.spkrid(item))
921
- dr1-fvmh0
922
- >>> print(timit.sentid(item))
923
- sx116
924
- >>> print(timit.spkrinfo(timit.spkrid(item))) # doctest: +NORMALIZE_WHITESPACE
925
- SpeakerInfo(id='VMH0',
926
- sex='F',
927
- dr='1',
928
- use='TRN',
929
- recdate='03/11/86',
930
- birthdate='01/08/60',
931
- ht='5\'05"',
932
- race='WHT',
933
- edu='BS',
934
- comments='BEST NEW ENGLAND ACCENT SO FAR')
935
-
936
- >>> # List the speech samples from the same speaker:
937
- >>> timit.utteranceids(spkrid=timit.spkrid(item)) # doctest: +ELLIPSIS
938
- ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466', ...]
939
-
940
- twitter_samples
941
- ---------------
942
-
943
- Twitter is well-known microblog service that allows public data to be
944
- collected via APIs. NLTK's twitter corpus currently contains a sample of 20k Tweets
945
- retrieved from the Twitter Streaming API.
946
-
947
- >>> from nltk.corpus import twitter_samples
948
- >>> twitter_samples.fileids()
949
- ['negative_tweets.json', 'positive_tweets.json', 'tweets.20150430-223406.json']
950
-
951
- We follow standard practice in storing full Tweets as line-separated
952
- JSON. These data structures can be accessed via `tweets.docs()`. However, in general it
953
- is more practical to focus just on the text field of the Tweets, which
954
- are accessed via the `strings()` method.
955
-
956
- >>> twitter_samples.strings('tweets.20150430-223406.json')
957
- ['RT @KirkKus: Indirect cost of the UK being in the EU is estimated to be costing Britain \xa3170 billion per year! #BetterOffOut #UKIP', ...]
958
-
959
- The default tokenizer for Tweets is specialised for 'casual' text, and
960
- the `tokenized()` method returns a list of lists of tokens.
961
-
962
- >>> twitter_samples.tokenized('tweets.20150430-223406.json')
963
- [['RT', '@KirkKus', ':', 'Indirect', 'cost', 'of', 'the', 'UK', 'being', 'in', ...],
964
- ['VIDEO', ':', 'Sturgeon', 'on', 'post-election', 'deals', 'http://t.co/BTJwrpbmOY'], ...]
965
-
966
- rte
967
- ---
968
- The RTE (Recognizing Textual Entailment) corpus was derived from the
969
- RTE1, RTE2 and RTE3 datasets (dev and test data), and consists of a
970
- list of XML-formatted 'text'/'hypothesis' pairs.
971
-
972
- >>> from nltk.corpus import rte
973
- >>> print(rte.fileids()) # doctest: +ELLIPSIS
974
- ['rte1_dev.xml', 'rte1_test.xml', 'rte2_dev.xml', ..., 'rte3_test.xml']
975
- >>> rtepairs = rte.pairs(['rte2_test.xml', 'rte3_test.xml'])
976
- >>> print(rtepairs) # doctest: +ELLIPSIS
977
- [<RTEPair: gid=2-8>, <RTEPair: gid=2-9>, <RTEPair: gid=2-15>, ...]
978
-
979
- In the gold standard test sets, each pair is labeled according to
980
- whether or not the text 'entails' the hypothesis; the
981
- entailment value is mapped to an integer 1 (True) or 0 (False).
982
-
983
- >>> rtepairs[5]
984
- <RTEPair: gid=2-23>
985
- >>> rtepairs[5].text # doctest: +NORMALIZE_WHITESPACE
986
- 'His wife Strida won a seat in parliament after forging an alliance
987
- with the main anti-Syrian coalition in the recent election.'
988
- >>> rtepairs[5].hyp
989
- 'Strida elected to parliament.'
990
- >>> rtepairs[5].value
991
- 1
992
-
993
- The RTE corpus also supports an ``xml()`` method which produces ElementTrees.
994
-
995
- >>> xmltree = rte.xml('rte3_dev.xml')
996
- >>> xmltree # doctest: +SKIP
997
- <Element entailment-corpus at ...>
998
- >>> xmltree[7].findtext('t') # doctest: +NORMALIZE_WHITESPACE
999
- "Mrs. Bush's approval ratings have remained very high, above 80%,
1000
- even as her husband's have recently dropped below 50%."
1001
-
1002
- verbnet
1003
- -------
1004
- The VerbNet corpus is a lexicon that divides verbs into classes, based
1005
- on their syntax-semantics linking behavior. The basic elements in the
1006
- lexicon are verb lemmas, such as 'abandon' and 'accept', and verb
1007
- classes, which have identifiers such as 'remove-10.1' and
1008
- 'admire-31.2-1'. These class identifiers consist of a representative
1009
- verb selected from the class, followed by a numerical identifier. The
1010
- list of verb lemmas, and the list of class identifiers, can be
1011
- retrieved with the following methods:
1012
-
1013
- >>> from nltk.corpus import verbnet
1014
- >>> verbnet.lemmas()[20:25]
1015
- ['accelerate', 'accept', 'acclaim', 'accompany', 'accrue']
1016
- >>> verbnet.classids()[:5]
1017
- ['accompany-51.7', 'admire-31.2', 'admire-31.2-1', 'admit-65', 'adopt-93']
1018
-
1019
- The `classids()` method may also be used to retrieve the classes that
1020
- a given lemma belongs to:
1021
-
1022
- >>> verbnet.classids('accept')
1023
- ['approve-77', 'characterize-29.2-1-1', 'obtain-13.5.2']
1024
-
1025
- The primary object in the lexicon is a class record, which is stored
1026
- as an ElementTree xml object. The class record for a given class
1027
- identifier is returned by the `vnclass()` method:
1028
-
1029
- >>> verbnet.vnclass('remove-10.1') # doctest: +ELLIPSIS
1030
- <Element 'VNCLASS' at ...>
1031
-
1032
- The `vnclass()` method also accepts "short" identifiers, such as '10.1':
1033
-
1034
- >>> verbnet.vnclass('10.1') # doctest: +ELLIPSIS
1035
- <Element 'VNCLASS' at ...>
1036
-
1037
- See the Verbnet documentation, or the Verbnet files, for information
1038
- about the structure of this xml. As an example, we can retrieve a
1039
- list of thematic roles for a given Verbnet class:
1040
-
1041
- >>> vn_31_2 = verbnet.vnclass('admire-31.2')
1042
- >>> for themrole in vn_31_2.findall('THEMROLES/THEMROLE'):
1043
- ... print(themrole.attrib['type'], end=' ')
1044
- ... for selrestr in themrole.findall('SELRESTRS/SELRESTR'):
1045
- ... print('[%(Value)s%(type)s]' % selrestr.attrib, end=' ')
1046
- ... print()
1047
- Theme
1048
- Experiencer [+animate]
1049
- Predicate
1050
-
1051
- The Verbnet corpus also provides a variety of pretty printing
1052
- functions that can be used to display the xml contents in a more
1053
- concise form. The simplest such method is `pprint()`:
1054
-
1055
- >>> print(verbnet.pprint('57'))
1056
- weather-57
1057
- Subclasses: (none)
1058
- Members: blow clear drizzle fog freeze gust hail howl lightning mist
1059
- mizzle pelt pour precipitate rain roar shower sleet snow spit spot
1060
- sprinkle storm swelter teem thaw thunder
1061
- Thematic roles:
1062
- * Theme[+concrete +force]
1063
- Frames:
1064
- Intransitive (Expletive Subject)
1065
- Syntax: LEX[it] LEX[[+be]] VERB
1066
- Semantics:
1067
- * weather(during(E), Weather_type, ?Theme)
1068
- NP (Expletive Subject, Theme Object)
1069
- Syntax: LEX[it] LEX[[+be]] VERB NP[Theme]
1070
- Semantics:
1071
- * weather(during(E), Weather_type, Theme)
1072
- PP (Expletive Subject, Theme-PP)
1073
- Syntax: LEX[it[+be]] VERB PREP[with] NP[Theme]
1074
- Semantics:
1075
- * weather(during(E), Weather_type, Theme)
1076
-
1077
-
1078
- nps_chat
1079
- --------
1080
-
1081
- The NPS Chat Corpus, Release 1.0 consists of over 10,000 posts in age-specific
1082
- chat rooms, which have been anonymized, POS-tagged and dialogue-act tagged.
1083
-
1084
- >>> print(nltk.corpus.nps_chat.words())
1085
- ['now', 'im', 'left', 'with', 'this', 'gay', ...]
1086
- >>> print(nltk.corpus.nps_chat.tagged_words())
1087
- [('now', 'RB'), ('im', 'PRP'), ('left', 'VBD'), ...]
1088
- >>> print(nltk.corpus.nps_chat.tagged_posts()) # doctest: +NORMALIZE_WHITESPACE
1089
- [[('now', 'RB'), ('im', 'PRP'), ('left', 'VBD'), ('with', 'IN'),
1090
- ('this', 'DT'), ('gay', 'JJ'), ('name', 'NN')], [(':P', 'UH')], ...]
1091
-
1092
- We can access the XML elements corresponding to individual posts. These elements
1093
- have ``class`` and ``user`` attributes that we can access using ``p.attrib['class']``
1094
- and ``p.attrib['user']``. They also have text content, accessed using ``p.text``.
1095
-
1096
- >>> print(nltk.corpus.nps_chat.xml_posts()) # doctest: +ELLIPSIS
1097
- [<Element 'Post' at 0...>, <Element 'Post' at 0...>, ...]
1098
- >>> posts = nltk.corpus.nps_chat.xml_posts()
1099
- >>> sorted(nltk.FreqDist(p.attrib['class'] for p in posts).keys())
1100
- ['Accept', 'Bye', 'Clarify', 'Continuer', 'Emotion', 'Emphasis',
1101
- 'Greet', 'Other', 'Reject', 'Statement', 'System', 'nAnswer',
1102
- 'whQuestion', 'yAnswer', 'ynQuestion']
1103
- >>> posts[0].text
1104
- 'now im left with this gay name'
1105
-
1106
- In addition to the above methods for accessing tagged text, we can navigate
1107
- the XML structure directly, as follows:
1108
-
1109
- >>> tokens = posts[0].findall('terminals/t')
1110
- >>> [t.attrib['pos'] + "/" + t.attrib['word'] for t in tokens]
1111
- ['RB/now', 'PRP/im', 'VBD/left', 'IN/with', 'DT/this', 'JJ/gay', 'NN/name']
1112
-
1113
- multext_east
1114
- ------------
1115
-
1116
- The Multext-East Corpus consists of POS-tagged versions of George Orwell's book
1117
- 1984 in 12 languages: English, Czech, Hungarian, Macedonian, Slovenian, Serbian,
1118
- Slovak, Romanian, Estonian, Farsi, Bulgarian and Polish.
1119
- The corpus can be accessed using the usual methods for tagged corpora. The tagset
1120
- can be transformed from the Multext-East specific MSD tags to the Universal tagset
1121
- using the "tagset" parameter of all functions returning tagged parts of the corpus.
1122
-
1123
- >>> print(nltk.corpus.multext_east.words("oana-en.xml"))
1124
- ['It', 'was', 'a', 'bright', ...]
1125
- >>> print(nltk.corpus.multext_east.tagged_words("oana-en.xml"))
1126
- [('It', '#Pp3ns'), ('was', '#Vmis3s'), ('a', '#Di'), ...]
1127
- >>> print(nltk.corpus.multext_east.tagged_sents("oana-en.xml", "universal"))
1128
- [[('It', 'PRON'), ('was', 'VERB'), ('a', 'DET'), ...]
1129
-
1130
-
1131
-
1132
- ---------------------
1133
- Corpus Reader Classes
1134
- ---------------------
1135
-
1136
- NLTK's *corpus reader* classes are used to access the contents of a
1137
- diverse set of corpora. Each corpus reader class is specialized to
1138
- handle a specific corpus format. Examples include the
1139
- `PlaintextCorpusReader`, which handles corpora that consist of a set
1140
- of unannotated text files, and the `BracketParseCorpusReader`, which
1141
- handles corpora that consist of files containing
1142
- parenthesis-delineated parse trees.
1143
-
1144
- Automatically Created Corpus Reader Instances
1145
- =============================================
1146
-
1147
- When the `nltk.corpus` module is imported, it automatically creates a
1148
- set of corpus reader instances that can be used to access the corpora
1149
- in the NLTK data distribution. Here is a small sample of those
1150
- corpus reader instances:
1151
-
1152
- >>> import nltk
1153
- >>> nltk.corpus.brown # doctest: +ELLIPSIS
1154
- <CategorizedTaggedCorpusReader ...>
1155
- >>> nltk.corpus.treebank # doctest: +ELLIPSIS
1156
- <BracketParseCorpusReader ...>
1157
- >>> nltk.corpus.names # doctest: +ELLIPSIS
1158
- <WordListCorpusReader ...>
1159
- >>> nltk.corpus.genesis # doctest: +ELLIPSIS
1160
- <PlaintextCorpusReader ...>
1161
- >>> nltk.corpus.inaugural # doctest: +ELLIPSIS
1162
- <PlaintextCorpusReader ...>
1163
-
1164
- This sample illustrates that different corpus reader classes are used
1165
- to read different corpora; but that the same corpus reader class may
1166
- be used for more than one corpus (e.g., ``genesis`` and ``inaugural``).
1167
-
1168
- Creating New Corpus Reader Instances
1169
- ====================================
1170
-
1171
- Although the `nltk.corpus` module automatically creates corpus reader
1172
- instances for the corpora in the NLTK data distribution, you may
1173
- sometimes need to create your own corpus reader. In particular, you
1174
- would need to create your own corpus reader if you want...
1175
-
1176
- - To access a corpus that is not included in the NLTK data
1177
- distribution.
1178
-
1179
- - To access a full copy of a corpus for which the NLTK data
1180
- distribution only provides a sample.
1181
-
1182
- - To access a corpus using a customized corpus reader (e.g., with
1183
- a customized tokenizer).
1184
-
1185
- To create a new corpus reader, you will first need to look up the
1186
- signature for that corpus reader's constructor. Different corpus
1187
- readers have different constructor signatures, but most of the
1188
- constructor signatures have the basic form::
1189
-
1190
- SomeCorpusReader(root, files, ...options...)
1191
-
1192
- Where ``root`` is an absolute path to the directory containing the
1193
- corpus data files; ``files`` is either a list of file names (relative
1194
- to ``root``) or a regexp specifying which files should be included;
1195
- and ``options`` are additional reader-specific options. For example,
1196
- we can create a customized corpus reader for the genesis corpus that
1197
- uses a different sentence tokenizer as follows:
1198
-
1199
- >>> # Find the directory where the corpus lives.
1200
- >>> genesis_dir = nltk.data.find('corpora/genesis')
1201
- >>> # Create our custom sentence tokenizer.
1202
- >>> my_sent_tokenizer = nltk.RegexpTokenizer('[^.!?]+')
1203
- >>> # Create the new corpus reader object.
1204
- >>> my_genesis = nltk.corpus.PlaintextCorpusReader(
1205
- ... genesis_dir, '.*\.txt', sent_tokenizer=my_sent_tokenizer)
1206
- >>> # Use the new corpus reader object.
1207
- >>> print(my_genesis.sents('english-kjv.txt')[0]) # doctest: +NORMALIZE_WHITESPACE
1208
- ['In', 'the', 'beginning', 'God', 'created', 'the', 'heaven',
1209
- 'and', 'the', 'earth']
1210
-
1211
- If you wish to read your own plaintext corpus, which is stored in the
1212
- directory '/usr/share/some-corpus', then you can create a corpus
1213
- reader for it with::
1214
-
1215
- >>> my_corpus = nltk.corpus.PlaintextCorpusReader(
1216
- ... '/usr/share/some-corpus', '.*\.txt') # doctest: +SKIP
1217
-
1218
- For a complete list of corpus reader subclasses, see the API
1219
- documentation for `nltk.corpus.reader`.
1220
-
1221
- Corpus Types
1222
- ============
1223
-
1224
- Corpora vary widely in the types of content they include. This is
1225
- reflected in the fact that the base class `CorpusReader` only defines
1226
- a few general-purpose methods for listing and accessing the files that
1227
- make up a corpus. It is up to the subclasses to define *data access
1228
- methods* that provide access to the information in the corpus.
1229
- However, corpus reader subclasses should be consistent in their
1230
- definitions of these data access methods wherever possible.
1231
-
1232
- At a high level, corpora can be divided into three basic types:
1233
-
1234
- - A *token corpus* contains information about specific occurences of
1235
- language use (or linguistic tokens), such as dialogues or written
1236
- texts. Examples of token corpora are collections of written text
1237
- and collections of speech.
1238
-
1239
- - A *type corpus*, or *lexicon*, contains information about a coherent
1240
- set of lexical items (or linguistic types). Examples of lexicons
1241
- are dictionaries and word lists.
1242
-
1243
- - A *language description corpus* contains information about a set of
1244
- non-lexical linguistic constructs, such as grammar rules.
1245
-
1246
- However, many individual corpora blur the distinctions between these
1247
- types. For example, corpora that are primarily lexicons may include
1248
- token data in the form of example sentences; and corpora that are
1249
- primarily token corpora may be accompanied by one or more word lists
1250
- or other lexical data sets.
1251
-
1252
- Because corpora vary so widely in their information content, we have
1253
- decided that it would not be wise to use separate corpus reader base
1254
- classes for different corpus types. Instead, we simply try to make
1255
- the corpus readers consistent wherever possible, but let them differ
1256
- where the underlying data itself differs.
1257
-
1258
- Common Corpus Reader Methods
1259
- ============================
1260
-
1261
- As mentioned above, there are only a handful of methods that all
1262
- corpus readers are guaranteed to implement. These methods provide
1263
- access to the files that contain the corpus data. Every corpus is
1264
- assumed to consist of one or more files, all located in a common root
1265
- directory (or in subdirectories of that root directory). The absolute
1266
- path to the root directory is stored in the ``root`` property:
1267
-
1268
- >>> import os
1269
- >>> str(nltk.corpus.genesis.root).replace(os.path.sep,'/') # doctest: +ELLIPSIS
1270
- '.../nltk_data/corpora/genesis'
1271
-
1272
- Each file within the corpus is identified by a platform-independent
1273
- identifier, which is basically a path string that uses ``/`` as the
1274
- path separator. I.e., this identifier can be converted to a relative
1275
- path as follows:
1276
-
1277
- >>> some_corpus_file_id = nltk.corpus.reuters.fileids()[0]
1278
- >>> import os.path
1279
- >>> os.path.normpath(some_corpus_file_id).replace(os.path.sep,'/')
1280
- 'test/14826'
1281
-
1282
- To get a list of all data files that make up a corpus, use the
1283
- ``fileids()`` method. In some corpora, these files will not all contain
1284
- the same type of data; for example, for the ``nltk.corpus.timit``
1285
- corpus, ``fileids()`` will return a list including text files, word
1286
- segmentation files, phonetic transcription files, sound files, and
1287
- metadata files. For corpora with diverse file types, the ``fileids()``
1288
- method will often take one or more optional arguments, which can be
1289
- used to get a list of the files with a specific file type:
1290
-
1291
- >>> nltk.corpus.timit.fileids() # doctest: +ELLIPSIS
1292
- ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa1.txt', 'dr1-fvmh0/sa1.wav', ...]
1293
- >>> nltk.corpus.timit.fileids('phn') # doctest: +ELLIPSIS
1294
- ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa2.phn', 'dr1-fvmh0/si1466.phn', ...]
1295
-
1296
- In some corpora, the files are divided into distinct categories. For
1297
- these corpora, the ``fileids()`` method takes an optional argument,
1298
- which can be used to get a list of the files within a specific category:
1299
-
1300
- >>> nltk.corpus.brown.fileids('hobbies') # doctest: +ELLIPSIS
1301
- ['ce01', 'ce02', 'ce03', 'ce04', 'ce05', 'ce06', 'ce07', ...]
1302
-
1303
- The ``abspath()`` method can be used to find the absolute path to a
1304
- corpus file, given its file identifier:
1305
-
1306
- >>> str(nltk.corpus.brown.abspath('ce06')).replace(os.path.sep,'/') # doctest: +ELLIPSIS
1307
- '.../corpora/brown/ce06'
1308
-
1309
- The ``abspaths()`` method can be used to find the absolute paths for
1310
- one corpus file, a list of corpus files, or (if no fileids are specified),
1311
- all corpus files.
1312
-
1313
- This method is mainly useful as a helper method when defining corpus
1314
- data access methods, since data access methods can usually be called
1315
- with a string argument (to get a view for a specific file), with a
1316
- list argument (to get a view for a specific list of files), or with no
1317
- argument (to get a view for the whole corpus).
1318
-
1319
- Data Access Methods
1320
- ===================
1321
-
1322
- Individual corpus reader subclasses typically extend this basic set of
1323
- file-access methods with one or more *data access methods*, which provide
1324
- easy access to the data contained in the corpus. The signatures for
1325
- data access methods often have the basic form::
1326
-
1327
- corpus_reader.some_data access(fileids=None, ...options...)
1328
-
1329
- Where ``fileids`` can be a single file identifier string (to get a view
1330
- for a specific file); a list of file identifier strings (to get a view
1331
- for a specific list of files); or None (to get a view for the entire
1332
- corpus). Some of the common data access methods, and their return
1333
- types, are:
1334
-
1335
- - I{corpus}.words(): list of str
1336
- - I{corpus}.sents(): list of (list of str)
1337
- - I{corpus}.paras(): list of (list of (list of str))
1338
- - I{corpus}.tagged_words(): list of (str,str) tuple
1339
- - I{corpus}.tagged_sents(): list of (list of (str,str))
1340
- - I{corpus}.tagged_paras(): list of (list of (list of (str,str)))
1341
- - I{corpus}.chunked_sents(): list of (Tree w/ (str,str) leaves)
1342
- - I{corpus}.parsed_sents(): list of (Tree with str leaves)
1343
- - I{corpus}.parsed_paras(): list of (list of (Tree with str leaves))
1344
- - I{corpus}.xml(): A single xml ElementTree
1345
- - I{corpus}.raw(): str (unprocessed corpus contents)
1346
-
1347
- For example, the `words()` method is supported by many different
1348
- corpora, and returns a flat list of word strings:
1349
-
1350
- >>> nltk.corpus.brown.words()
1351
- ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
1352
- >>> nltk.corpus.treebank.words()
1353
- ['Pierre', 'Vinken', ',', '61', 'years', 'old', ...]
1354
- >>> nltk.corpus.conll2002.words()
1355
- [u'Sao', u'Paulo', u'(', u'Brasil', u')', u',', u'23', ...]
1356
- >>> nltk.corpus.genesis.words()
1357
- [u'In', u'the', u'beginning', u'God', u'created', ...]
1358
-
1359
- On the other hand, the `tagged_words()` method is only supported by
1360
- corpora that include part-of-speech annotations:
1361
-
1362
- >>> nltk.corpus.brown.tagged_words()
1363
- [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
1364
- >>> nltk.corpus.treebank.tagged_words()
1365
- [('Pierre', 'NNP'), ('Vinken', 'NNP'), ...]
1366
- >>> nltk.corpus.conll2002.tagged_words()
1367
- [(u'Sao', u'NC'), (u'Paulo', u'VMI'), (u'(', u'Fpa'), ...]
1368
- >>> nltk.corpus.genesis.tagged_words()
1369
- Traceback (most recent call last):
1370
- ...
1371
- AttributeError: 'PlaintextCorpusReader' object has no attribute 'tagged_words'
1372
-
1373
- Although most corpus readers use file identifiers to index their
1374
- content, some corpora use different identifiers instead. For example,
1375
- the data access methods for the ``timit`` corpus uses *utterance
1376
- identifiers* to select which corpus items should be returned:
1377
-
1378
- >>> nltk.corpus.timit.utteranceids() # doctest: +ELLIPSIS
1379
- ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466', ...]
1380
- >>> nltk.corpus.timit.words('dr1-fvmh0/sa2')
1381
- ["don't", 'ask', 'me', 'to', 'carry', 'an', 'oily', 'rag', 'like', 'that']
1382
-
1383
- Attempting to call ``timit``\ 's data access methods with a file
1384
- identifier will result in an exception:
1385
-
1386
- >>> nltk.corpus.timit.fileids() # doctest: +ELLIPSIS
1387
- ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa1.txt', 'dr1-fvmh0/sa1.wav', ...]
1388
- >>> nltk.corpus.timit.words('dr1-fvmh0/sa1.txt') # doctest: +SKIP
1389
- Traceback (most recent call last):
1390
- ...
1391
- IOError: No such file or directory: '.../dr1-fvmh0/sa1.txt.wrd'
1392
-
1393
- As another example, the ``propbank`` corpus defines the ``roleset()``
1394
- method, which expects a roleset identifier, not a file identifier:
1395
-
1396
- >>> roleset = nltk.corpus.propbank.roleset('eat.01')
1397
- >>> from xml.etree import ElementTree as ET
1398
- >>> print(ET.tostring(roleset).decode('utf8')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1399
- <roleset id="eat.01" name="consume" vncls="39.1">
1400
- <roles>
1401
- <role descr="consumer, eater" n="0">...</role>...
1402
- </roles>...
1403
- </roleset>...
1404
-
1405
- Stream Backed Corpus Views
1406
- ==========================
1407
- An important feature of NLTK's corpus readers is that many of them
1408
- access the underlying data files using "corpus views." A *corpus
1409
- view* is an object that acts like a simple data structure (such as a
1410
- list), but does not store the data elements in memory; instead, data
1411
- elements are read from the underlying data files on an as-needed
1412
- basis.
1413
-
1414
- By only loading items from the file on an as-needed basis, corpus
1415
- views maintain both memory efficiency and responsiveness. The memory
1416
- efficiency of corpus readers is important because some corpora contain
1417
- very large amounts of data, and storing the entire data set in memory
1418
- could overwhelm many machines. The responsiveness is important when
1419
- experimenting with corpora in interactive sessions and in in-class
1420
- demonstrations.
1421
-
1422
- The most common corpus view is the `StreamBackedCorpusView`, which
1423
- acts as a read-only list of tokens. Two additional corpus view
1424
- classes, `ConcatenatedCorpusView` and `LazySubsequence`, make it
1425
- possible to create concatenations and take slices of
1426
- `StreamBackedCorpusView` objects without actually storing the
1427
- resulting list-like object's elements in memory.
1428
-
1429
- In the future, we may add additional corpus views that act like other
1430
- basic data structures, such as dictionaries.
1431
-
1432
- Writing New Corpus Readers
1433
- ==========================
1434
-
1435
- In order to add support for new corpus formats, it is necessary to
1436
- define new corpus reader classes. For many corpus formats, writing
1437
- new corpus readers is relatively straight-forward. In this section,
1438
- we'll describe what's involved in creating a new corpus reader. If
1439
- you do create a new corpus reader, we encourage you to contribute it
1440
- back to the NLTK project.
1441
-
1442
- Don't Reinvent the Wheel
1443
- ------------------------
1444
- Before you start writing a new corpus reader, you should check to be
1445
- sure that the desired format can't be read using an existing corpus
1446
- reader with appropriate constructor arguments. For example, although
1447
- the `TaggedCorpusReader` assumes that words and tags are separated by
1448
- ``/`` characters by default, an alternative tag-separation character
1449
- can be specified via the ``sep`` constructor argument. You should
1450
- also check whether the new corpus format can be handled by subclassing
1451
- an existing corpus reader, and tweaking a few methods or variables.
1452
-
1453
- Design
1454
- ------
1455
- If you decide to write a new corpus reader from scratch, then you
1456
- should first decide which data access methods you want the reader to
1457
- provide, and what their signatures should be. You should look at
1458
- existing corpus readers that process corpora with similar data
1459
- contents, and try to be consistent with those corpus readers whenever
1460
- possible.
1461
-
1462
- You should also consider what sets of identifiers are appropriate for
1463
- the corpus format. Where it's practical, file identifiers should be
1464
- used. However, for some corpora, it may make sense to use additional
1465
- sets of identifiers. Each set of identifiers should have a distinct
1466
- name (e.g., fileids, utteranceids, rolesets); and you should be consistent
1467
- in using that name to refer to that identifier. Do not use parameter
1468
- names like ``id``, which leave it unclear what type of identifier is
1469
- required.
1470
-
1471
- Once you've decided what data access methods and identifiers are
1472
- appropriate for your corpus, you should decide if there are any
1473
- customizable parameters that you'd like the corpus reader to handle.
1474
- These parameters make it possible to use a single corpus reader to
1475
- handle a wider variety of corpora. The ``sep`` argument for
1476
- `TaggedCorpusReader`, mentioned above, is an example of a customizable
1477
- corpus reader parameter.
1478
-
1479
- Implementation
1480
- --------------
1481
-
1482
- Constructor
1483
- ~~~~~~~~~~~
1484
- If your corpus reader implements any customizable parameters, then
1485
- you'll need to override the constructor. Typically, the new
1486
- constructor will first call its base class's constructor, and then
1487
- store the customizable parameters. For example, the
1488
- `ConllChunkCorpusReader`\ 's constructor is defined as follows:
1489
-
1490
- >>> def __init__(self, root, files, chunk_types):
1491
- ... CorpusReader.__init__(self, root, files)
1492
- ... self.chunk_types = tuple(chunk_types)
1493
-
1494
- If your corpus reader does not implement any customization parameters,
1495
- then you can often just inherit the base class's constructor.
1496
-
1497
- Data Access Methods
1498
- ~~~~~~~~~~~~~~~~~~~
1499
-
1500
- The most common type of data access method takes an argument
1501
- identifying which files to access, and returns a view covering those
1502
- files. This argument may be a single file identifier string (to get a
1503
- view for a specific file); a list of file identifier strings (to get a
1504
- view for a specific list of files); or None (to get a view for the
1505
- entire corpus). The method's implementation converts this argument to
1506
- a list of path names using the `abspaths()` method, which handles all
1507
- three value types (string, list, and None):
1508
-
1509
- >>> print(str(nltk.corpus.brown.abspaths()).replace('\\\\','/')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1510
- [FileSystemPathPointer('.../corpora/brown/ca01'),
1511
- FileSystemPathPointer('.../corpora/brown/ca02'), ...]
1512
- >>> print(str(nltk.corpus.brown.abspaths('ce06')).replace('\\\\','/')) # doctest: +ELLIPSIS
1513
- [FileSystemPathPointer('.../corpora/brown/ce06')]
1514
- >>> print(str(nltk.corpus.brown.abspaths(['ce06', 'ce07'])).replace('\\\\','/')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1515
- [FileSystemPathPointer('.../corpora/brown/ce06'),
1516
- FileSystemPathPointer('.../corpora/brown/ce07')]
1517
-
1518
- An example of this type of method is the `words()` method, defined by
1519
- the `PlaintextCorpusReader` as follows:
1520
-
1521
- >>> def words(self, fileids=None):
1522
- ... return concat([self.CorpusView(fileid, self._read_word_block)
1523
- ... for fileid in self.abspaths(fileids)])
1524
-
1525
- This method first uses `abspaths()` to convert ``fileids`` to a list of
1526
- absolute paths. It then creates a corpus view for each file, using
1527
- the `PlaintextCorpusReader._read_word_block()` method to read elements
1528
- from the data file (see the discussion of corpus views below).
1529
- Finally, it combines these corpus views using the
1530
- `nltk.corpus.reader.util.concat()` function.
1531
-
1532
- When writing a corpus reader for a corpus that is never expected to be
1533
- very large, it can sometimes be appropriate to read the files
1534
- directly, rather than using a corpus view. For example, the
1535
- `WordListCorpusView` class defines its `words()` method as follows:
1536
-
1537
- >>> def words(self, fileids=None):
1538
- ... return concat([[w for w in open(fileid).read().split('\n') if w]
1539
- ... for fileid in self.abspaths(fileids)])
1540
-
1541
- (This is usually more appropriate for lexicons than for token corpora.)
1542
-
1543
- If the type of data returned by a data access method is one for which
1544
- NLTK has a conventional representation (e.g., words, tagged words, and
1545
- parse trees), then you should use that representation. Otherwise, you
1546
- may find it necessary to define your own representation. For data
1547
- structures that are relatively corpus-specific, it's usually best to
1548
- define new classes for these elements. For example, the ``propbank``
1549
- corpus defines the `PropbankInstance` class to store the semantic role
1550
- labeling instances described by the corpus; and the ``ppattach``
1551
- corpus defines the `PPAttachment` class to store the prepositional
1552
- attachment instances described by the corpus.
1553
-
1554
- Corpus Views
1555
- ~~~~~~~~~~~~
1556
- .. (Much of the content for this section is taken from the
1557
- StreamBackedCorpusView docstring.)
1558
-
1559
- The heart of a `StreamBackedCorpusView` is its *block reader*
1560
- function, which reads zero or more tokens from a stream, and returns
1561
- them as a list. A very simple example of a block reader is:
1562
-
1563
- >>> def simple_block_reader(stream):
1564
- ... return stream.readline().split()
1565
-
1566
- This simple block reader reads a single line at a time, and returns a
1567
- single token (consisting of a string) for each whitespace-separated
1568
- substring on the line. A `StreamBackedCorpusView` built from this
1569
- block reader will act like a read-only list of all the
1570
- whitespace-separated tokens in an underlying file.
1571
-
1572
- When deciding how to define the block reader for a given corpus,
1573
- careful consideration should be given to the size of blocks handled by
1574
- the block reader. Smaller block sizes will increase the memory
1575
- requirements of the corpus view's internal data structures (by 2
1576
- integers per block). On the other hand, larger block sizes may
1577
- decrease performance for random access to the corpus. (But note that
1578
- larger block sizes will *not* decrease performance for iteration.)
1579
-
1580
- Internally, the `StreamBackedCorpusView` class maintains a partial
1581
- mapping from token index to file position, with one entry per block.
1582
- When a token with a given index *i* is requested, the corpus view
1583
- constructs it as follows:
1584
-
1585
- 1. First, it searches the toknum/filepos mapping for the token index
1586
- closest to (but less than or equal to) *i*.
1587
-
1588
- 2. Then, starting at the file position corresponding to that index, it
1589
- reads one block at a time using the block reader until it reaches
1590
- the requested token.
1591
-
1592
- The toknum/filepos mapping is created lazily: it is initially empty,
1593
- but every time a new block is read, the block's initial token is added
1594
- to the mapping. (Thus, the toknum/filepos map has one entry per
1595
- block.)
1596
-
1597
- You can create your own corpus view in one of two ways:
1598
-
1599
- 1. Call the `StreamBackedCorpusView` constructor, and provide your
1600
- block reader function via the ``block_reader`` argument.
1601
-
1602
- 2. Subclass `StreamBackedCorpusView`, and override the
1603
- `read_block()` method.
1604
-
1605
- The first option is usually easier, but the second option can allow
1606
- you to write a single `read_block` method whose behavior can be
1607
- customized by different parameters to the subclass's constructor. For
1608
- an example of this design pattern, see the `TaggedCorpusView` class,
1609
- which is used by `TaggedCorpusView`.
1610
-
1611
- ----------------
1612
- Regression Tests
1613
- ----------------
1614
-
1615
- The following helper functions are used to create and then delete
1616
- testing corpora that are stored in temporary directories. These
1617
- testing corpora are used to make sure the readers work correctly.
1618
-
1619
- >>> import tempfile, os.path, textwrap
1620
- >>> def make_testcorpus(ext='', **fileids):
1621
- ... root = tempfile.mkdtemp()
1622
- ... for fileid, contents in fileids.items():
1623
- ... fileid += ext
1624
- ... f = open(os.path.join(root, fileid), 'w')
1625
- ... f.write(textwrap.dedent(contents))
1626
- ... f.close()
1627
- ... return root
1628
- >>> def del_testcorpus(root):
1629
- ... for fileid in os.listdir(root):
1630
- ... os.remove(os.path.join(root, fileid))
1631
- ... os.rmdir(root)
1632
-
1633
- Plaintext Corpus Reader
1634
- =======================
1635
- The plaintext corpus reader is used to access corpora that consist of
1636
- unprocessed plaintext data. It assumes that paragraph breaks are
1637
- indicated by blank lines. Sentences and words can be tokenized using
1638
- the default tokenizers, or by custom tokenizers specified as
1639
- parameters to the constructor.
1640
-
1641
- >>> root = make_testcorpus(ext='.txt',
1642
- ... a="""\
1643
- ... This is the first sentence. Here is another
1644
- ... sentence! And here's a third sentence.
1645
- ...
1646
- ... This is the second paragraph. Tokenization is currently
1647
- ... fairly simple, so the period in Mr. gets tokenized.
1648
- ... """,
1649
- ... b="""This is the second file.""")
1650
-
1651
- >>> from nltk.corpus.reader.plaintext import PlaintextCorpusReader
1652
-
1653
- The list of documents can be specified explicitly, or implicitly (using a
1654
- regexp). The ``ext`` argument specifies a file extension.
1655
-
1656
- >>> corpus = PlaintextCorpusReader(root, ['a.txt', 'b.txt'])
1657
- >>> corpus.fileids()
1658
- ['a.txt', 'b.txt']
1659
- >>> corpus = PlaintextCorpusReader(root, '.*\.txt')
1660
- >>> corpus.fileids()
1661
- ['a.txt', 'b.txt']
1662
-
1663
- The directory containing the corpus is corpus.root:
1664
-
1665
- >>> str(corpus.root) == str(root)
1666
- True
1667
-
1668
- We can get a list of words, or the raw string:
1669
-
1670
- >>> corpus.words()
1671
- ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1672
- >>> corpus.raw()[:40]
1673
- 'This is the first sentence. Here is ano'
1674
-
1675
- Check that reading individual documents works, and reading all documents at
1676
- once works:
1677
-
1678
- >>> len(corpus.words()), [len(corpus.words(d)) for d in corpus.fileids()]
1679
- (46, [40, 6])
1680
- >>> corpus.words('a.txt')
1681
- ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1682
- >>> corpus.words('b.txt')
1683
- ['This', 'is', 'the', 'second', 'file', '.']
1684
- >>> corpus.words()[:4], corpus.words()[-4:]
1685
- (['This', 'is', 'the', 'first'], ['the', 'second', 'file', '.'])
1686
-
1687
- We're done with the test corpus:
1688
-
1689
- >>> del_testcorpus(root)
1690
-
1691
- Test the plaintext corpora that come with nltk:
1692
-
1693
- >>> from nltk.corpus import abc, genesis, inaugural
1694
- >>> from nltk.corpus import state_union, webtext
1695
- >>> for corpus in (abc, genesis, inaugural, state_union,
1696
- ... webtext):
1697
- ... print(str(corpus).replace('\\\\','/'))
1698
- ... print(' ', repr(corpus.fileids())[:60])
1699
- ... print(' ', repr(corpus.words()[:10])[:60])
1700
- <PlaintextCorpusReader in '.../nltk_data/corpora/ab...'>
1701
- ['rural.txt', 'science.txt']
1702
- ['PM', 'denies', 'knowledge', 'of', 'AWB', ...
1703
- <PlaintextCorpusReader in '.../nltk_data/corpora/genesi...'>
1704
- ['english-kjv.txt', 'english-web.txt', 'finnish.txt', ...
1705
- ['In', 'the', 'beginning', 'God', 'created', 'the', ...
1706
- <PlaintextCorpusReader in '.../nltk_data/corpora/inaugura...'>
1707
- ['1789-Washington.txt', '1793-Washington.txt', ...
1708
- ['Fellow', '-', 'Citizens', 'of', 'the', 'Senate', ...
1709
- <PlaintextCorpusReader in '.../nltk_data/corpora/state_unio...'>
1710
- ['1945-Truman.txt', '1946-Truman.txt', ...
1711
- ['PRESIDENT', 'HARRY', 'S', '.', 'TRUMAN', "'", ...
1712
- <PlaintextCorpusReader in '.../nltk_data/corpora/webtex...'>
1713
- ['firefox.txt', 'grail.txt', 'overheard.txt', ...
1714
- ['Cookie', 'Manager', ':', '"', 'Don', "'", 't', ...
1715
-
1716
-
1717
- Tagged Corpus Reader
1718
- ====================
1719
- The Tagged Corpus reader can give us words, sentences, and paragraphs,
1720
- each tagged or untagged. All of the read methods can take one item
1721
- (in which case they return the contents of that file) or a list of
1722
- documents (in which case they concatenate the contents of those files).
1723
- By default, they apply to all documents in the corpus.
1724
-
1725
- >>> root = make_testcorpus(
1726
- ... a="""\
1727
- ... This/det is/verb the/det first/adj sentence/noun ./punc
1728
- ... Here/det is/verb another/adj sentence/noun ./punc
1729
- ... Note/verb that/comp you/pron can/verb use/verb \
1730
- ... any/noun tag/noun set/noun
1731
- ...
1732
- ... This/det is/verb the/det second/adj paragraph/noun ./punc
1733
- ... word/n without/adj a/det tag/noun :/: hello ./punc
1734
- ... """,
1735
- ... b="""\
1736
- ... This/det is/verb the/det second/adj file/noun ./punc
1737
- ... """)
1738
-
1739
- >>> from nltk.corpus.reader.tagged import TaggedCorpusReader
1740
- >>> corpus = TaggedCorpusReader(root, list('ab'))
1741
- >>> corpus.fileids()
1742
- ['a', 'b']
1743
- >>> str(corpus.root) == str(root)
1744
- True
1745
- >>> corpus.words()
1746
- ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1747
- >>> corpus.sents() # doctest: +ELLIPSIS
1748
- [['This', 'is', 'the', 'first', ...], ['Here', 'is', 'another'...], ...]
1749
- >>> corpus.paras() # doctest: +ELLIPSIS
1750
- [[['This', ...], ['Here', ...], ...], [['This', ...], ...], ...]
1751
- >>> corpus.tagged_words() # doctest: +ELLIPSIS
1752
- [('This', 'DET'), ('is', 'VERB'), ('the', 'DET'), ...]
1753
- >>> corpus.tagged_sents() # doctest: +ELLIPSIS
1754
- [[('This', 'DET'), ('is', 'VERB'), ...], [('Here', 'DET'), ...], ...]
1755
- >>> corpus.tagged_paras() # doctest: +ELLIPSIS
1756
- [[[('This', 'DET'), ...], ...], [[('This', 'DET'), ...], ...], ...]
1757
- >>> corpus.raw()[:40]
1758
- 'This/det is/verb the/det first/adj sente'
1759
- >>> len(corpus.words()), [len(corpus.words(d)) for d in corpus.fileids()]
1760
- (38, [32, 6])
1761
- >>> len(corpus.sents()), [len(corpus.sents(d)) for d in corpus.fileids()]
1762
- (6, [5, 1])
1763
- >>> len(corpus.paras()), [len(corpus.paras(d)) for d in corpus.fileids()]
1764
- (3, [2, 1])
1765
- >>> print(corpus.words('a'))
1766
- ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1767
- >>> print(corpus.words('b'))
1768
- ['This', 'is', 'the', 'second', 'file', '.']
1769
- >>> del_testcorpus(root)
1770
-
1771
- The Brown Corpus uses the tagged corpus reader:
1772
-
1773
- >>> from nltk.corpus import brown
1774
- >>> brown.fileids() # doctest: +ELLIPSIS
1775
- ['ca01', 'ca02', 'ca03', 'ca04', 'ca05', 'ca06', 'ca07', ...]
1776
- >>> brown.categories() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1777
- ['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor',
1778
- 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']
1779
- >>> print(repr(brown.root).replace('\\\\','/')) # doctest: +ELLIPSIS
1780
- FileSystemPathPointer('.../corpora/brown')
1781
- >>> brown.words()
1782
- ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
1783
- >>> brown.sents() # doctest: +ELLIPSIS
1784
- [['The', 'Fulton', 'County', 'Grand', ...], ...]
1785
- >>> brown.paras() # doctest: +ELLIPSIS
1786
- [[['The', 'Fulton', 'County', ...]], [['The', 'jury', ...]], ...]
1787
- >>> brown.tagged_words() # doctest: +ELLIPSIS
1788
- [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
1789
- >>> brown.tagged_sents() # doctest: +ELLIPSIS
1790
- [[('The', 'AT'), ('Fulton', 'NP-TL'), ('County', 'NN-TL'), ...], ...]
1791
- >>> brown.tagged_paras() # doctest: +ELLIPSIS
1792
- [[[('The', 'AT'), ...]], [[('The', 'AT'), ...]], ...]
1793
-
1794
- Verbnet Corpus Reader
1795
- =====================
1796
-
1797
- Make sure we're picking up the right number of elements:
1798
-
1799
- >>> from nltk.corpus import verbnet
1800
- >>> len(verbnet.lemmas())
1801
- 3621
1802
- >>> len(verbnet.wordnetids())
1803
- 4953
1804
- >>> len(verbnet.classids())
1805
- 429
1806
-
1807
- Selecting classids based on various selectors:
1808
-
1809
- >>> verbnet.classids(lemma='take') # doctest: +NORMALIZE_WHITESPACE
1810
- ['bring-11.3', 'characterize-29.2', 'convert-26.6.2', 'cost-54.2',
1811
- 'fit-54.3', 'performance-26.7-2', 'steal-10.5']
1812
- >>> verbnet.classids(wordnetid='lead%2:38:01')
1813
- ['accompany-51.7']
1814
- >>> verbnet.classids(fileid='approve-77.xml')
1815
- ['approve-77']
1816
- >>> verbnet.classids(classid='admire-31.2') # subclasses
1817
- ['admire-31.2-1']
1818
-
1819
- vnclass() accepts filenames, long ids, and short ids:
1820
-
1821
- >>> a = ElementTree.tostring(verbnet.vnclass('admire-31.2.xml'))
1822
- >>> b = ElementTree.tostring(verbnet.vnclass('admire-31.2'))
1823
- >>> c = ElementTree.tostring(verbnet.vnclass('31.2'))
1824
- >>> a == b == c
1825
- True
1826
-
1827
- fileids() can be used to get files based on verbnet class ids:
1828
-
1829
- >>> verbnet.fileids('admire-31.2')
1830
- ['admire-31.2.xml']
1831
- >>> verbnet.fileids(['admire-31.2', 'obtain-13.5.2'])
1832
- ['admire-31.2.xml', 'obtain-13.5.2.xml']
1833
- >>> verbnet.fileids('badidentifier')
1834
- Traceback (most recent call last):
1835
- . . .
1836
- ValueError: vnclass identifier 'badidentifier' not found
1837
-
1838
- longid() and shortid() can be used to convert identifiers:
1839
-
1840
- >>> verbnet.longid('31.2')
1841
- 'admire-31.2'
1842
- >>> verbnet.longid('admire-31.2')
1843
- 'admire-31.2'
1844
- >>> verbnet.shortid('31.2')
1845
- '31.2'
1846
- >>> verbnet.shortid('admire-31.2')
1847
- '31.2'
1848
- >>> verbnet.longid('badidentifier')
1849
- Traceback (most recent call last):
1850
- . . .
1851
- ValueError: vnclass identifier 'badidentifier' not found
1852
- >>> verbnet.shortid('badidentifier')
1853
- Traceback (most recent call last):
1854
- . . .
1855
- ValueError: vnclass identifier 'badidentifier' not found
1856
-
1857
- Corpus View Regression Tests
1858
- ============================
1859
-
1860
- Select some corpus files to play with:
1861
-
1862
- >>> import nltk.data
1863
- >>> # A very short file (160 chars):
1864
- >>> f1 = nltk.data.find('corpora/inaugural/README')
1865
- >>> # A relatively short file (791 chars):
1866
- >>> f2 = nltk.data.find('corpora/inaugural/1793-Washington.txt')
1867
- >>> # A longer file (32k chars):
1868
- >>> f3 = nltk.data.find('corpora/inaugural/1909-Taft.txt')
1869
- >>> fileids = [f1, f2, f3]
1870
-
1871
-
1872
- Concatenation
1873
- -------------
1874
- Check that concatenation works as intended.
1875
-
1876
- >>> from nltk.corpus.reader.util import *
1877
-
1878
- >>> c1 = StreamBackedCorpusView(f1, read_whitespace_block, encoding='utf-8')
1879
- >>> c2 = StreamBackedCorpusView(f2, read_whitespace_block, encoding='utf-8')
1880
- >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block, encoding='utf-8')
1881
- >>> c123 = c1+c2+c3
1882
- >>> print(c123)
1883
- ['C-Span', 'Inaugural', 'Address', 'Corpus', 'US', ...]
1884
-
1885
- >>> l1 = f1.open(encoding='utf-8').read().split()
1886
- >>> l2 = f2.open(encoding='utf-8').read().split()
1887
- >>> l3 = f3.open(encoding='utf-8').read().split()
1888
- >>> l123 = l1+l2+l3
1889
-
1890
- >>> list(c123) == l123
1891
- True
1892
-
1893
- >>> (c1+c2+c3)[100] == l123[100]
1894
- True
1895
-
1896
- Slicing
1897
- -------
1898
- First, do some tests with fairly small slices. These will all
1899
- generate tuple values.
1900
-
1901
- >>> from nltk.util import LazySubsequence
1902
- >>> c1 = StreamBackedCorpusView(f1, read_whitespace_block, encoding='utf-8')
1903
- >>> l1 = f1.open(encoding='utf-8').read().split()
1904
- >>> print(len(c1))
1905
- 21
1906
- >>> len(c1) < LazySubsequence.MIN_SIZE
1907
- True
1908
-
1909
- Choose a list of indices, based on the length, that covers the
1910
- important corner cases:
1911
-
1912
- >>> indices = [-60, -30, -22, -21, -20, -1,
1913
- ... 0, 1, 10, 20, 21, 22, 30, 60]
1914
-
1915
- Test slicing with explicit start & stop value:
1916
-
1917
- >>> for s in indices:
1918
- ... for e in indices:
1919
- ... assert list(c1[s:e]) == l1[s:e]
1920
-
1921
- Test slicing with stop=None:
1922
-
1923
- >>> for s in indices:
1924
- ... assert list(c1[s:]) == l1[s:]
1925
-
1926
- Test slicing with start=None:
1927
-
1928
- >>> for e in indices:
1929
- ... assert list(c1[:e]) == l1[:e]
1930
-
1931
- Test slicing with start=stop=None:
1932
-
1933
- >>> list(c1[:]) == list(l1[:])
1934
- True
1935
-
1936
- Next, we'll do some tests with much longer slices. These will
1937
- generate LazySubsequence objects.
1938
-
1939
- >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block, encoding='utf-8')
1940
- >>> l3 = f3.open(encoding='utf-8').read().split()
1941
- >>> print(len(c3))
1942
- 5430
1943
- >>> len(c3) > LazySubsequence.MIN_SIZE*2
1944
- True
1945
-
1946
- Choose a list of indices, based on the length, that covers the
1947
- important corner cases:
1948
-
1949
- >>> indices = [-12000, -6000, -5431, -5430, -5429, -3000, -200, -1,
1950
- ... 0, 1, 200, 3000, 5000, 5429, 5430, 5431, 6000, 12000]
1951
-
1952
- Test slicing with explicit start & stop value:
1953
-
1954
- >>> for s in indices:
1955
- ... for e in indices:
1956
- ... assert list(c3[s:e]) == l3[s:e]
1957
-
1958
- Test slicing with stop=None:
1959
-
1960
- >>> for s in indices:
1961
- ... assert list(c3[s:]) == l3[s:]
1962
-
1963
- Test slicing with start=None:
1964
-
1965
- >>> for e in indices:
1966
- ... assert list(c3[:e]) == l3[:e]
1967
-
1968
- Test slicing with start=stop=None:
1969
-
1970
- >>> list(c3[:]) == list(l3[:])
1971
- True
1972
-
1973
- Multiple Iterators
1974
- ------------------
1975
- If multiple iterators are created for the same corpus view, their
1976
- iteration can be interleaved:
1977
-
1978
- >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block)
1979
- >>> iterators = [c3.iterate_from(n) for n in [0,15,30,45]]
1980
- >>> for i in range(15):
1981
- ... for iterator in iterators:
1982
- ... print('%-15s' % next(iterator), end=' ')
1983
- ... print()
1984
- My a duties in
1985
- fellow heavy of a
1986
- citizens: weight the proper
1987
- Anyone of office sense
1988
- who responsibility. upon of
1989
- has If which the
1990
- taken not, he obligation
1991
- the he is which
1992
- oath has about the
1993
- I no to oath
1994
- have conception enter, imposes.
1995
- just of or The
1996
- taken the he office
1997
- must powers is of
1998
- feel and lacking an
1999
-
2000
- SeekableUnicodeStreamReader
2001
- ===========================
2002
-
2003
- The file-like objects provided by the ``codecs`` module unfortunately
2004
- suffer from a bug that prevents them from working correctly with
2005
- corpus view objects. In particular, although the expose ``seek()``
2006
- and ``tell()`` methods, those methods do not exhibit the expected
2007
- behavior, because they are not synchronized with the internal buffers
2008
- that are kept by the file-like objects. For example, the ``tell()``
2009
- method will return the file position at the end of the buffers (whose
2010
- contents have not yet been returned by the stream); and therefore this
2011
- file position can not be used to return to the 'current' location in
2012
- the stream (since ``seek()`` has no way to reconstruct the buffers).
2013
-
2014
- To get around these problems, we define a new class,
2015
- `SeekableUnicodeStreamReader`, to act as a file-like interface to
2016
- files containing encoded unicode data. This class is loosely based on
2017
- the ``codecs.StreamReader`` class. To construct a new reader, we call
2018
- the constructor with an underlying stream and an encoding name:
2019
-
2020
- >>> from io import StringIO, BytesIO
2021
- >>> from nltk.data import SeekableUnicodeStreamReader
2022
- >>> stream = BytesIO(b"""\
2023
- ... This is a test file.
2024
- ... It is encoded in ascii.
2025
- ... """.decode('ascii').encode('ascii'))
2026
- >>> reader = SeekableUnicodeStreamReader(stream, 'ascii')
2027
-
2028
- `SeekableUnicodeStreamReader`\ s support all of the normal operations
2029
- supplied by a read-only stream. Note that all of the read operations
2030
- return ``unicode`` objects (not ``str`` objects).
2031
-
2032
- >>> reader.read() # read the entire file.
2033
- u'This is a test file.\nIt is encoded in ascii.\n'
2034
- >>> reader.seek(0) # rewind to the start.
2035
- >>> reader.read(5) # read at most 5 bytes.
2036
- u'This '
2037
- >>> reader.readline() # read to the end of the line.
2038
- u'is a test file.\n'
2039
- >>> reader.seek(0) # rewind to the start.
2040
- >>> for line in reader:
2041
- ... print(repr(line)) # iterate over lines
2042
- u'This is a test file.\n'
2043
- u'It is encoded in ascii.\n'
2044
- >>> reader.seek(0) # rewind to the start.
2045
- >>> reader.readlines() # read a list of line strings
2046
- [u'This is a test file.\n', u'It is encoded in ascii.\n']
2047
- >>> reader.close()
2048
-
2049
- Size argument to ``read()``
2050
- ---------------------------
2051
- The ``size`` argument to ``read()`` specifies the maximum number of
2052
- *bytes* to read, not the maximum number of *characters*. Thus, for
2053
- encodings that use multiple bytes per character, it may return fewer
2054
- characters than the ``size`` argument:
2055
-
2056
- >>> stream = BytesIO(b"""\
2057
- ... This is a test file.
2058
- ... It is encoded in utf-16.
2059
- ... """.decode('ascii').encode('utf-16'))
2060
- >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2061
- >>> reader.read(10)
2062
- u'This '
2063
-
2064
- If a read block ends in the middle of the byte string encoding a
2065
- single character, then that byte string is stored in an internal
2066
- buffer, and re-used on the next call to ``read()``. However, if the
2067
- size argument is too small to read even a single character, even
2068
- though at least one character is available, then the ``read()`` method
2069
- will read additional bytes until it can return a single character.
2070
- This ensures that the ``read()`` method does not return an empty
2071
- string, which could be mistaken for indicating the end of the file.
2072
-
2073
- >>> reader.seek(0) # rewind to the start.
2074
- >>> reader.read(1) # we actually need to read 4 bytes
2075
- u'T'
2076
- >>> int(reader.tell())
2077
- 4
2078
-
2079
- The ``readline()`` method may read more than a single line of text, in
2080
- which case it stores the text that it does not return in a buffer. If
2081
- this buffer is not empty, then its contents will be included in the
2082
- value returned by the next call to ``read()``, regardless of the
2083
- ``size`` argument, since they are available without reading any new
2084
- bytes from the stream:
2085
-
2086
- >>> reader.seek(0) # rewind to the start.
2087
- >>> reader.readline() # stores extra text in a buffer
2088
- u'This is a test file.\n'
2089
- >>> print(reader.linebuffer) # examine the buffer contents
2090
- [u'It is encoded i']
2091
- >>> reader.read(0) # returns the contents of the buffer
2092
- u'It is encoded i'
2093
- >>> print(reader.linebuffer) # examine the buffer contents
2094
- None
2095
-
2096
- Seek and Tell
2097
- -------------
2098
- In addition to these basic read operations,
2099
- `SeekableUnicodeStreamReader` also supports the ``seek()`` and
2100
- ``tell()`` operations. However, some care must still be taken when
2101
- using these operations. In particular, the only file offsets that
2102
- should be passed to ``seek()`` are ``0`` and any offset that has been
2103
- returned by ``tell``.
2104
-
2105
- >>> stream = BytesIO(b"""\
2106
- ... This is a test file.
2107
- ... It is encoded in utf-16.
2108
- ... """.decode('ascii').encode('utf-16'))
2109
- >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2110
- >>> reader.read(20)
2111
- u'This is a '
2112
- >>> pos = reader.tell(); print(pos)
2113
- 22
2114
- >>> reader.read(20)
2115
- u'test file.'
2116
- >>> reader.seek(pos) # rewind to the position from tell.
2117
- >>> reader.read(20)
2118
- u'test file.'
2119
-
2120
- The ``seek()`` and ``tell()`` methods work property even when
2121
- ``readline()`` is used.
2122
-
2123
- >>> stream = BytesIO(b"""\
2124
- ... This is a test file.
2125
- ... It is encoded in utf-16.
2126
- ... """.decode('ascii').encode('utf-16'))
2127
- >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2128
- >>> reader.readline()
2129
- u'This is a test file.\n'
2130
- >>> pos = reader.tell(); print(pos)
2131
- 44
2132
- >>> reader.readline()
2133
- u'It is encoded in utf-16.\n'
2134
- >>> reader.seek(pos) # rewind to the position from tell.
2135
- >>> reader.readline()
2136
- u'It is encoded in utf-16.\n'
2137
-
2138
-
2139
- Squashed Bugs
2140
- =============
2141
-
2142
- svn 5276 fixed a bug in the comment-stripping behavior of
2143
- parse_sexpr_block.
2144
-
2145
- >>> from io import StringIO
2146
- >>> from nltk.corpus.reader.util import read_sexpr_block
2147
- >>> f = StringIO(b"""
2148
- ... (a b c)
2149
- ... # This line is a comment.
2150
- ... (d e f\ng h)""".decode('ascii'))
2151
- >>> print(read_sexpr_block(f, block_size=38, comment_char='#'))
2152
- ['(a b c)']
2153
- >>> print(read_sexpr_block(f, block_size=38, comment_char='#'))
2154
- ['(d e f\ng h)']
2155
-
2156
- svn 5277 fixed a bug in parse_sexpr_block, which would cause it to
2157
- enter an infinite loop if a file ended mid-sexpr, or ended with a
2158
- token that was not followed by whitespace. A related bug caused
2159
- an infinite loop if the corpus ended in an unmatched close paren --
2160
- this was fixed in svn 5279
2161
-
2162
- >>> f = StringIO(b"""
2163
- ... This file ends mid-sexpr
2164
- ... (hello (world""".decode('ascii'))
2165
- >>> for i in range(3): print(read_sexpr_block(f))
2166
- ['This', 'file', 'ends', 'mid-sexpr']
2167
- ['(hello (world']
2168
- []
2169
-
2170
- >>> f = StringIO(b"This file has no trailing whitespace.".decode('ascii'))
2171
- >>> for i in range(3): print(read_sexpr_block(f))
2172
- ['This', 'file', 'has', 'no', 'trailing']
2173
- ['whitespace.']
2174
- []
2175
-
2176
- >>> # Bug fixed in 5279:
2177
- >>> f = StringIO(b"a b c)".decode('ascii'))
2178
- >>> for i in range(3): print(read_sexpr_block(f))
2179
- ['a', 'b']
2180
- ['c)']
2181
- []
2182
-
2183
-
2184
- svn 5624 & 5265 fixed a bug in ConcatenatedCorpusView, which caused it
2185
- to return the wrong items when indexed starting at any index beyond
2186
- the first file.
2187
-
2188
- >>> import nltk
2189
- >>> sents = nltk.corpus.brown.sents()
2190
- >>> print(sents[6000])
2191
- ['Cholesterol', 'and', 'thyroid']
2192
- >>> print(sents[6000])
2193
- ['Cholesterol', 'and', 'thyroid']
2194
-
2195
- svn 5728 fixed a bug in Categorized*CorpusReader, which caused them
2196
- to return words from *all* files when just one file was specified.
2197
-
2198
- >>> from nltk.corpus import reuters
2199
- >>> reuters.words('training/13085')
2200
- ['SNYDER', '&', 'lt', ';', 'SOI', '>', 'MAKES', ...]
2201
- >>> reuters.words('training/5082')
2202
- ['SHEPPARD', 'RESOURCES', 'TO', 'MERGE', 'WITH', ...]
2203
-
2204
- svn 7227 fixed a bug in the qc corpus reader, which prevented
2205
- access to its tuples() method
2206
-
2207
- >>> from nltk.corpus import qc
2208
- >>> qc.tuples('test.txt')
2209
- [('NUM:dist', 'How far is it from Denver to Aspen ?'), ('LOC:city', 'What county is Modesto , California in ?'), ...]
2210
-
2211
-
2212
-
1
+ .. Copyright (C) 2001-2018 NLTK Project
2
+ .. For license information, see LICENSE.TXT
3
+
4
+ ================
5
+ Corpus Readers
6
+ ================
7
+
8
+ The `nltk.corpus` package defines a collection of *corpus reader*
9
+ classes, which can be used to access the contents of a diverse set of
10
+ corpora. The list of available corpora is given at:
11
+
12
+ http://www.nltk.org/nltk_data/
13
+
14
+ Each corpus reader class is specialized to handle a specific
15
+ corpus format. In addition, the `nltk.corpus` package automatically
16
+ creates a set of corpus reader instances that can be used to access
17
+ the corpora in the NLTK data package.
18
+ Section `Corpus Reader Objects`_ ("Corpus Reader Objects") describes
19
+ the corpus reader instances that can be used to read the corpora in
20
+ the NLTK data package. Section `Corpus Reader Classes`_ ("Corpus
21
+ Reader Classes") describes the corpus reader classes themselves, and
22
+ discusses the issues involved in creating new corpus reader objects
23
+ and new corpus reader classes. Section `Regression Tests`_
24
+ ("Regression Tests") contains regression tests for the corpus readers
25
+ and associated functions and classes.
26
+
27
+ .. contents:: **Table of Contents**
28
+ :depth: 2
29
+ :backlinks: none
30
+
31
+ ---------------------
32
+ Corpus Reader Objects
33
+ ---------------------
34
+
35
+ Overview
36
+ ========
37
+
38
+ NLTK includes a diverse set of corpora which can be
39
+ read using the ``nltk.corpus`` package. Each corpus is accessed by
40
+ means of a "corpus reader" object from ``nltk.corpus``:
41
+
42
+ >>> import nltk.corpus
43
+ >>> # The Brown corpus:
44
+ >>> print(str(nltk.corpus.brown).replace('\\\\','/'))
45
+ <CategorizedTaggedCorpusReader in '.../corpora/brown'...>
46
+ >>> # The Penn Treebank Corpus:
47
+ >>> print(str(nltk.corpus.treebank).replace('\\\\','/'))
48
+ <BracketParseCorpusReader in '.../corpora/treebank/combined'...>
49
+ >>> # The Name Genders Corpus:
50
+ >>> print(str(nltk.corpus.names).replace('\\\\','/'))
51
+ <WordListCorpusReader in '.../corpora/names'...>
52
+ >>> # The Inaugural Address Corpus:
53
+ >>> print(str(nltk.corpus.inaugural).replace('\\\\','/'))
54
+ <PlaintextCorpusReader in '.../corpora/inaugural'...>
55
+
56
+ Most corpora consist of a set of files, each containing a document (or
57
+ other pieces of text). A list of identifiers for these files is
58
+ accessed via the ``fileids()`` method of the corpus reader:
59
+
60
+ >>> nltk.corpus.treebank.fileids() # doctest: +ELLIPSIS
61
+ ['wsj_0001.mrg', 'wsj_0002.mrg', 'wsj_0003.mrg', 'wsj_0004.mrg', ...]
62
+ >>> nltk.corpus.inaugural.fileids() # doctest: +ELLIPSIS
63
+ ['1789-Washington.txt', '1793-Washington.txt', '1797-Adams.txt', ...]
64
+
65
+ Each corpus reader provides a variety of methods to read data from the
66
+ corpus, depending on the format of the corpus. For example, plaintext
67
+ corpora support methods to read the corpus as raw text, a list of
68
+ words, a list of sentences, or a list of paragraphs.
69
+
70
+ >>> from nltk.corpus import inaugural
71
+ >>> inaugural.raw('1789-Washington.txt') # doctest: +ELLIPSIS
72
+ 'Fellow-Citizens of the Senate ...'
73
+ >>> inaugural.words('1789-Washington.txt')
74
+ ['Fellow', '-', 'Citizens', 'of', 'the', ...]
75
+ >>> inaugural.sents('1789-Washington.txt') # doctest: +ELLIPSIS
76
+ [['Fellow', '-', 'Citizens'...], ['Among', 'the', 'vicissitudes'...]...]
77
+ >>> inaugural.paras('1789-Washington.txt') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
78
+ [[['Fellow', '-', 'Citizens'...]],
79
+ [['Among', 'the', 'vicissitudes'...],
80
+ ['On', 'the', 'one', 'hand', ',', 'I'...]...]...]
81
+
82
+ Each of these reader methods may be given a single document's item
83
+ name or a list of document item names. When given a list of document
84
+ item names, the reader methods will concatenate together the contents
85
+ of the individual documents.
86
+
87
+ >>> l1 = len(inaugural.words('1789-Washington.txt'))
88
+ >>> l2 = len(inaugural.words('1793-Washington.txt'))
89
+ >>> l3 = len(inaugural.words(['1789-Washington.txt', '1793-Washington.txt']))
90
+ >>> print('%s+%s == %s' % (l1, l2, l3))
91
+ 1538+147 == 1685
92
+
93
+ If the reader methods are called without any arguments, they will
94
+ typically load all documents in the corpus.
95
+
96
+ >>> len(inaugural.words())
97
+ 145735
98
+
99
+ If a corpus contains a README file, it can be accessed with a ``readme()`` method:
100
+
101
+ >>> inaugural.readme()[:32]
102
+ 'C-Span Inaugural Address Corpus\n'
103
+
104
+ Plaintext Corpora
105
+ =================
106
+
107
+ Here are the first few words from each of NLTK's plaintext corpora:
108
+
109
+ >>> nltk.corpus.abc.words()
110
+ ['PM', 'denies', 'knowledge', 'of', 'AWB', ...]
111
+ >>> nltk.corpus.genesis.words()
112
+ [u'In', u'the', u'beginning', u'God', u'created', ...]
113
+ >>> nltk.corpus.gutenberg.words(fileids='austen-emma.txt')
114
+ ['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ...]
115
+ >>> nltk.corpus.inaugural.words()
116
+ ['Fellow', '-', 'Citizens', 'of', 'the', ...]
117
+ >>> nltk.corpus.state_union.words()
118
+ ['PRESIDENT', 'HARRY', 'S', '.', 'TRUMAN', "'", ...]
119
+ >>> nltk.corpus.webtext.words()
120
+ ['Cookie', 'Manager', ':', '"', 'Don', "'", 't', ...]
121
+
122
+ Tagged Corpora
123
+ ==============
124
+
125
+ In addition to the plaintext corpora, NLTK's data package also
126
+ contains a wide variety of annotated corpora. For example, the Brown
127
+ Corpus is annotated with part-of-speech tags, and defines additional
128
+ methods ``tagged_*()`` which words as `(word,tag)` tuples, rather
129
+ than just bare word strings.
130
+
131
+ >>> from nltk.corpus import brown
132
+ >>> print(brown.words())
133
+ ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
134
+ >>> print(brown.tagged_words())
135
+ [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
136
+ >>> print(brown.sents()) # doctest: +ELLIPSIS
137
+ [['The', 'Fulton', 'County'...], ['The', 'jury', 'further'...], ...]
138
+ >>> print(brown.tagged_sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
139
+ [[('The', 'AT'), ('Fulton', 'NP-TL')...],
140
+ [('The', 'AT'), ('jury', 'NN'), ('further', 'RBR')...]...]
141
+ >>> print(brown.paras(categories='reviews')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
142
+ [[['It', 'is', 'not', 'news', 'that', 'Nathan', 'Milstein'...],
143
+ ['Certainly', 'not', 'in', 'Orchestra', 'Hall', 'where'...]],
144
+ [['There', 'was', 'about', 'that', 'song', 'something', ...],
145
+ ['Not', 'the', 'noblest', 'performance', 'we', 'have', ...], ...], ...]
146
+ >>> print(brown.tagged_paras(categories='reviews')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
147
+ [[[('It', 'PPS'), ('is', 'BEZ'), ('not', '*'), ...],
148
+ [('Certainly', 'RB'), ('not', '*'), ('in', 'IN'), ...]],
149
+ [[('There', 'EX'), ('was', 'BEDZ'), ('about', 'IN'), ...],
150
+ [('Not', '*'), ('the', 'AT'), ('noblest', 'JJT'), ...], ...], ...]
151
+
152
+ Similarly, the Indian Language POS-Tagged Corpus includes samples of
153
+ Indian text annotated with part-of-speech tags:
154
+
155
+ >>> from nltk.corpus import indian
156
+ >>> print(indian.words()) # doctest: +SKIP
157
+ ['\xe0\xa6\xae\xe0\xa6\xb9\xe0\xa6\xbf\...',
158
+ '\xe0\xa6\xb8\xe0\xa6\xa8\xe0\xa7\x8d\xe0...', ...]
159
+ >>> print(indian.tagged_words()) # doctest: +SKIP
160
+ [('\xe0\xa6\xae\xe0\xa6\xb9\xe0\xa6\xbf...', 'NN'),
161
+ ('\xe0\xa6\xb8\xe0\xa6\xa8\xe0\xa7\x8d\xe0...', 'NN'), ...]
162
+
163
+ Several tagged corpora support access to a simplified, universal tagset, e.g. where all nouns
164
+ tags are collapsed to a single category ``NOUN``:
165
+
166
+ >>> print(brown.tagged_sents(tagset='universal')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
167
+ [[('The', 'DET'), ('Fulton', 'NOUN'), ('County', 'NOUN'), ('Grand', 'ADJ'), ('Jury', 'NOUN'), ...],
168
+ [('The', 'DET'), ('jury', 'NOUN'), ('further', 'ADV'), ('said', 'VERB'), ('in', 'ADP'), ...]...]
169
+ >>> from nltk.corpus import conll2000, switchboard
170
+ >>> print(conll2000.tagged_words(tagset='universal')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
171
+ [('Confidence', 'NOUN'), ('in', 'ADP'), ...]
172
+
173
+ Use ``nltk.app.pos_concordance()`` to access a GUI for searching tagged corpora.
174
+
175
+ Chunked Corpora
176
+ ===============
177
+
178
+ The CoNLL corpora also provide chunk structures, which are encoded as
179
+ flat trees. The CoNLL 2000 Corpus includes phrasal chunks; and the
180
+ CoNLL 2002 Corpus includes named entity chunks.
181
+
182
+ >>> from nltk.corpus import conll2000, conll2002
183
+ >>> print(conll2000.sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
184
+ [['Confidence', 'in', 'the', 'pound', 'is', 'widely', ...],
185
+ ['Chancellor', 'of', 'the', 'Exchequer', ...], ...]
186
+ >>> for tree in conll2000.chunked_sents()[:2]:
187
+ ... print(tree) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
188
+ (S
189
+ (NP Confidence/NN)
190
+ (PP in/IN)
191
+ (NP the/DT pound/NN)
192
+ (VP is/VBZ widely/RB expected/VBN to/TO take/VB)
193
+ (NP another/DT sharp/JJ dive/NN)
194
+ if/IN
195
+ ...)
196
+ (S
197
+ Chancellor/NNP
198
+ (PP of/IN)
199
+ (NP the/DT Exchequer/NNP)
200
+ ...)
201
+ >>> print(conll2002.sents()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
202
+ [[u'Sao', u'Paulo', u'(', u'Brasil', u')', u',', ...], [u'-'], ...]
203
+ >>> for tree in conll2002.chunked_sents()[:2]:
204
+ ... print(tree) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
205
+ (S
206
+ (LOC Sao/NC Paulo/VMI)
207
+ (/Fpa
208
+ (LOC Brasil/NC)
209
+ )/Fpt
210
+ ...)
211
+ (S -/Fg)
212
+
213
+ .. note:: Since the CONLL corpora do not contain paragraph break
214
+ information, these readers do not support the ``para()`` method.)
215
+
216
+ .. warning:: if you call the conll corpora reader methods without any
217
+ arguments, they will return the contents of the entire corpus,
218
+ *including* the 'test' portions of the corpus.)
219
+
220
+ SemCor is a subset of the Brown corpus tagged with WordNet senses and
221
+ named entities. Both kinds of lexical items include multiword units,
222
+ which are encoded as chunks (senses and part-of-speech tags pertain
223
+ to the entire chunk).
224
+
225
+ >>> from nltk.corpus import semcor
226
+ >>> semcor.words()
227
+ ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
228
+ >>> semcor.chunks()
229
+ [['The'], ['Fulton', 'County', 'Grand', 'Jury'], ...]
230
+ >>> semcor.sents() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
231
+ [['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...],
232
+ ['The', 'jury', 'further', 'said', ...], ...]
233
+ >>> semcor.chunk_sents() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
234
+ [[['The'], ['Fulton', 'County', 'Grand', 'Jury'], ['said'], ...
235
+ ['.']], [['The'], ['jury'], ['further'], ['said'], ... ['.']], ...]
236
+ >>> list(map(str, semcor.tagged_chunks(tag='both')[:3]))
237
+ ['(DT The)', "(Lemma('group.n.01.group') (NE (NNP Fulton County Grand Jury)))", "(Lemma('state.v.01.say') (VB said))"]
238
+ >>> [[str(c) for c in s] for s in semcor.tagged_sents(tag='both')[:2]]
239
+ [['(DT The)', "(Lemma('group.n.01.group') (NE (NNP Fulton County Grand Jury)))", ...
240
+ '(None .)'], ['(DT The)', ... '(None .)']]
241
+
242
+
243
+ The IEER corpus is another chunked corpus. This corpus is unusual in
244
+ that each corpus item contains multiple documents. (This reflects the
245
+ fact that each corpus file contains multiple documents.) The IEER
246
+ corpus defines the `parsed_docs` method, which returns the documents
247
+ in a given item as `IEERDocument` objects:
248
+
249
+ >>> from nltk.corpus import ieer
250
+ >>> ieer.fileids() # doctest: +NORMALIZE_WHITESPACE
251
+ ['APW_19980314', 'APW_19980424', 'APW_19980429',
252
+ 'NYT_19980315', 'NYT_19980403', 'NYT_19980407']
253
+ >>> docs = ieer.parsed_docs('APW_19980314')
254
+ >>> print(docs[0])
255
+ <IEERDocument APW19980314.0391: 'Kenyans protest tax hikes'>
256
+ >>> print(docs[0].docno)
257
+ APW19980314.0391
258
+ >>> print(docs[0].doctype)
259
+ NEWS STORY
260
+ >>> print(docs[0].date_time)
261
+ 03/14/1998 10:36:00
262
+ >>> print(docs[0].headline)
263
+ (DOCUMENT Kenyans protest tax hikes)
264
+ >>> print(docs[0].text) # doctest: +ELLIPSIS
265
+ (DOCUMENT
266
+ (LOCATION NAIROBI)
267
+ ,
268
+ (LOCATION Kenya)
269
+ (
270
+ (ORGANIZATION AP)
271
+ )
272
+ _
273
+ (CARDINAL Thousands)
274
+ of
275
+ laborers,
276
+ ...
277
+ on
278
+ (DATE Saturday)
279
+ ...)
280
+
281
+ Parsed Corpora
282
+ ==============
283
+
284
+ The Treebank corpora provide a syntactic parse for each sentence. The
285
+ NLTK data package includes a 10% sample of the Penn Treebank (in
286
+ ``treebank``), as well as the Sinica Treebank (in ``sinica_treebank``).
287
+
288
+ Reading the Penn Treebank (Wall Street Journal sample):
289
+
290
+ >>> from nltk.corpus import treebank
291
+ >>> print(treebank.fileids()) # doctest: +ELLIPSIS
292
+ ['wsj_0001.mrg', 'wsj_0002.mrg', 'wsj_0003.mrg', 'wsj_0004.mrg', ...]
293
+ >>> print(treebank.words('wsj_0003.mrg'))
294
+ ['A', 'form', 'of', 'asbestos', 'once', 'used', ...]
295
+ >>> print(treebank.tagged_words('wsj_0003.mrg'))
296
+ [('A', 'DT'), ('form', 'NN'), ('of', 'IN'), ...]
297
+ >>> print(treebank.parsed_sents('wsj_0003.mrg')[0]) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
298
+ (S
299
+ (S-TPC-1
300
+ (NP-SBJ
301
+ (NP (NP (DT A) (NN form)) (PP (IN of) (NP (NN asbestos))))
302
+ (RRC ...)...)...)
303
+ ...
304
+ (VP (VBD reported) (SBAR (-NONE- 0) (S (-NONE- *T*-1))))
305
+ (. .))
306
+
307
+ If you have access to a full installation of the Penn Treebank, NLTK
308
+ can be configured to load it as well. Download the ``ptb`` package,
309
+ and in the directory ``nltk_data/corpora/ptb`` place the ``BROWN``
310
+ and ``WSJ`` directories of the Treebank installation (symlinks work
311
+ as well). Then use the ``ptb`` module instead of ``treebank``:
312
+
313
+ >>> from nltk.corpus import ptb
314
+ >>> print(ptb.fileids()) # doctest: +SKIP
315
+ ['BROWN/CF/CF01.MRG', 'BROWN/CF/CF02.MRG', 'BROWN/CF/CF03.MRG', 'BROWN/CF/CF04.MRG', ...]
316
+ >>> print(ptb.words('WSJ/00/WSJ_0003.MRG')) # doctest: +SKIP
317
+ ['A', 'form', 'of', 'asbestos', 'once', 'used', '*', ...]
318
+ >>> print(ptb.tagged_words('WSJ/00/WSJ_0003.MRG')) # doctest: +SKIP
319
+ [('A', 'DT'), ('form', 'NN'), ('of', 'IN'), ...]
320
+
321
+ ...and so forth, like ``treebank`` but with extended fileids. Categories
322
+ specified in ``allcats.txt`` can be used to filter by genre; they consist
323
+ of ``news`` (for WSJ articles) and names of the Brown subcategories
324
+ (``fiction``, ``humor``, ``romance``, etc.):
325
+
326
+ >>> ptb.categories() # doctest: +SKIP
327
+ ['adventure', 'belles_lettres', 'fiction', 'humor', 'lore', 'mystery', 'news', 'romance', 'science_fiction']
328
+ >>> print(ptb.fileids('news')) # doctest: +SKIP
329
+ ['WSJ/00/WSJ_0001.MRG', 'WSJ/00/WSJ_0002.MRG', 'WSJ/00/WSJ_0003.MRG', ...]
330
+ >>> print(ptb.words(categories=['humor','fiction'])) # doctest: +SKIP
331
+ ['Thirty-three', 'Scotty', 'did', 'not', 'go', 'back', ...]
332
+
333
+ As PropBank and NomBank depend on the (WSJ portion of the) Penn Treebank,
334
+ the modules ``propbank_ptb`` and ``nombank_ptb`` are provided for access
335
+ to a full PTB installation.
336
+
337
+ Reading the Sinica Treebank:
338
+
339
+ >>> from nltk.corpus import sinica_treebank
340
+ >>> print(sinica_treebank.sents()) # doctest: +SKIP
341
+ [['\xe4\xb8\x80'], ['\xe5\x8f\x8b\xe6\x83\x85'], ...]
342
+ >>> sinica_treebank.parsed_sents()[25] # doctest: +SKIP
343
+ Tree('S',
344
+ [Tree('NP',
345
+ [Tree('Nba', ['\xe5\x98\x89\xe7\x8f\x8d'])]),
346
+ Tree('V\xe2\x80\xa7\xe5\x9c\xb0',
347
+ [Tree('VA11', ['\xe4\xb8\x8d\xe5\x81\x9c']),
348
+ Tree('DE', ['\xe7\x9a\x84'])]),
349
+ Tree('VA4', ['\xe5\x93\xad\xe6\xb3\xa3'])])
350
+
351
+ Reading the CoNLL 2007 Dependency Treebanks:
352
+
353
+ >>> from nltk.corpus import conll2007
354
+ >>> conll2007.sents('esp.train')[0] # doctest: +SKIP
355
+ ['El', 'aumento', 'del', 'índice', 'de', 'desempleo', ...]
356
+ >>> conll2007.parsed_sents('esp.train')[0] # doctest: +SKIP
357
+ <DependencyGraph with 38 nodes>
358
+ >>> print(conll2007.parsed_sents('esp.train')[0].tree()) # doctest: +SKIP
359
+ (fortaleció
360
+ (aumento El (del (índice (de (desempleo estadounidense)))))
361
+ hoy
362
+ considerablemente
363
+ (al
364
+ (euro
365
+ (cotizaba
366
+ ,
367
+ que
368
+ (a (15.35 las GMT))
369
+ se
370
+ (en (mercado el (de divisas) (de Fráncfort)))
371
+ (a 0,9452_dólares)
372
+ (frente_a , (0,9349_dólares los (de (mañana esta)))))))
373
+ .)
374
+
375
+ Word Lists and Lexicons
376
+ =======================
377
+
378
+ The NLTK data package also includes a number of lexicons and word
379
+ lists. These are accessed just like text corpora. The following
380
+ examples illustrate the use of the wordlist corpora:
381
+
382
+ >>> from nltk.corpus import names, stopwords, words
383
+ >>> words.fileids()
384
+ ['en', 'en-basic']
385
+ >>> words.words('en') # doctest: +ELLIPSIS
386
+ ['A', 'a', 'aa', 'aal', 'aalii', 'aam', 'Aani', 'aardvark', 'aardwolf', ...]
387
+
388
+ >>> stopwords.fileids() # doctest: +ELLIPSIS
389
+ ['arabic', 'azerbaijani', 'danish', 'dutch', 'english', 'finnish', 'french', ...]
390
+ >>> stopwords.words('portuguese') # doctest: +ELLIPSIS
391
+ ['de', 'a', 'o', 'que', 'e', 'do', 'da', 'em', 'um', 'para', ...]
392
+ >>> names.fileids()
393
+ ['female.txt', 'male.txt']
394
+ >>> names.words('male.txt') # doctest: +ELLIPSIS
395
+ ['Aamir', 'Aaron', 'Abbey', 'Abbie', 'Abbot', 'Abbott', ...]
396
+ >>> names.words('female.txt') # doctest: +ELLIPSIS
397
+ ['Abagael', 'Abagail', 'Abbe', 'Abbey', 'Abbi', 'Abbie', ...]
398
+
399
+ The CMU Pronunciation Dictionary corpus contains pronounciation
400
+ transcriptions for over 100,000 words. It can be accessed as a list
401
+ of entries (where each entry consists of a word, an identifier, and a
402
+ transcription) or as a dictionary from words to lists of
403
+ transcriptions. Transcriptions are encoded as tuples of phoneme
404
+ strings.
405
+
406
+ >>> from nltk.corpus import cmudict
407
+ >>> print(cmudict.entries()[653:659]) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
408
+ [('acetate', ['AE1', 'S', 'AH0', 'T', 'EY2', 'T']),
409
+ ('acetic', ['AH0', 'S', 'EH1', 'T', 'IH0', 'K']),
410
+ ('acetic', ['AH0', 'S', 'IY1', 'T', 'IH0', 'K']),
411
+ ('aceto', ['AA0', 'S', 'EH1', 'T', 'OW0']),
412
+ ('acetochlor', ['AA0', 'S', 'EH1', 'T', 'OW0', 'K', 'L', 'AO2', 'R']),
413
+ ('acetone', ['AE1', 'S', 'AH0', 'T', 'OW2', 'N'])]
414
+ >>> # Load the entire cmudict corpus into a Python dictionary:
415
+ >>> transcr = cmudict.dict()
416
+ >>> print([transcr[w][0] for w in 'Natural Language Tool Kit'.lower().split()]) # doctest: +NORMALIZE_WHITESPACE
417
+ [['N', 'AE1', 'CH', 'ER0', 'AH0', 'L'],
418
+ ['L', 'AE1', 'NG', 'G', 'W', 'AH0', 'JH'],
419
+ ['T', 'UW1', 'L'],
420
+ ['K', 'IH1', 'T']]
421
+
422
+
423
+ WordNet
424
+ =======
425
+
426
+ Please see the separate WordNet howto.
427
+
428
+ FrameNet
429
+ ========
430
+
431
+ Please see the separate FrameNet howto.
432
+
433
+ PropBank
434
+ ========
435
+
436
+ Please see the separate PropBank howto.
437
+
438
+ SentiWordNet
439
+ ============
440
+
441
+ Please see the separate SentiWordNet howto.
442
+
443
+ Categorized Corpora
444
+ ===================
445
+
446
+ Several corpora included with NLTK contain documents that have been categorized for
447
+ topic, genre, polarity, etc. In addition to the standard corpus interface, these
448
+ corpora provide access to the list of categories and the mapping between the documents
449
+ and their categories (in both directions). Access the categories using the ``categories()``
450
+ method, e.g.:
451
+
452
+ >>> from nltk.corpus import brown, movie_reviews, reuters
453
+ >>> brown.categories() # doctest: +NORMALIZE_WHITESPACE
454
+ ['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor',
455
+ 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']
456
+ >>> movie_reviews.categories()
457
+ ['neg', 'pos']
458
+ >>> reuters.categories() # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
459
+ ['acq', 'alum', 'barley', 'bop', 'carcass', 'castor-oil', 'cocoa',
460
+ 'coconut', 'coconut-oil', 'coffee', 'copper', 'copra-cake', 'corn',
461
+ 'cotton', 'cotton-oil', 'cpi', 'cpu', 'crude', 'dfl', 'dlr', ...]
462
+
463
+ This method has an optional argument that specifies a document or a list
464
+ of documents, allowing us to map from (one or more) documents to (one or more) categories:
465
+
466
+ >>> brown.categories('ca01')
467
+ ['news']
468
+ >>> brown.categories(['ca01','cb01'])
469
+ ['editorial', 'news']
470
+ >>> reuters.categories('training/9865')
471
+ ['barley', 'corn', 'grain', 'wheat']
472
+ >>> reuters.categories(['training/9865', 'training/9880'])
473
+ ['barley', 'corn', 'grain', 'money-fx', 'wheat']
474
+
475
+ We can go back the other way using the optional argument of the ``fileids()`` method:
476
+
477
+ >>> reuters.fileids('barley') # doctest: +ELLIPSIS
478
+ ['test/15618', 'test/15649', 'test/15676', 'test/15728', 'test/15871', ...]
479
+
480
+ Both the ``categories()`` and ``fileids()`` methods return a sorted list containing
481
+ no duplicates.
482
+
483
+ In addition to mapping between categories and documents, these corpora permit
484
+ direct access to their contents via the categories. Instead of accessing a subset
485
+ of a corpus by specifying one or more fileids, we can identify one or more categories, e.g.:
486
+
487
+ >>> brown.tagged_words(categories='news')
488
+ [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
489
+ >>> brown.sents(categories=['editorial','reviews']) # doctest: +NORMALIZE_WHITESPACE
490
+ [['Assembly', 'session', 'brought', 'much', 'good'], ['The', 'General',
491
+ 'Assembly', ',', 'which', 'adjourns', 'today', ',', 'has', 'performed',
492
+ 'in', 'an', 'atmosphere', 'of', 'crisis', 'and', 'struggle', 'from',
493
+ 'the', 'day', 'it', 'convened', '.'], ...]
494
+
495
+ Note that it is an error to specify both documents and categories.
496
+
497
+ In the context of a text categorization system, we can easily test if the
498
+ category assigned to a document is correct as follows:
499
+
500
+ >>> def classify(doc): return 'news' # Trivial classifier
501
+ >>> doc = 'ca01'
502
+ >>> classify(doc) in brown.categories(doc)
503
+ True
504
+
505
+
506
+ Other Corpora
507
+ =============
508
+
509
+ comparative_sentences
510
+ ---------------------
511
+ A list of sentences from various sources, especially reviews and articles. Each
512
+ line contains one sentence; sentences were separated by using a sentence tokenizer.
513
+ Comparative sentences have been annotated with their type, entities, features and
514
+ keywords.
515
+
516
+ >>> from nltk.corpus import comparative_sentences
517
+ >>> comparison = comparative_sentences.comparisons()[0]
518
+ >>> comparison.text
519
+ ['its', 'fast-forward', 'and', 'rewind', 'work', 'much', 'more', 'smoothly',
520
+ 'and', 'consistently', 'than', 'those', 'of', 'other', 'models', 'i', "'ve",
521
+ 'had', '.']
522
+ >>> comparison.entity_2
523
+ 'models'
524
+ >>> (comparison.feature, comparison.keyword)
525
+ ('rewind', 'more')
526
+ >>> len(comparative_sentences.comparisons())
527
+ 853
528
+
529
+ opinion_lexicon
530
+ ---------------
531
+ A list of positive and negative opinion words or sentiment words for English.
532
+
533
+ >>> from nltk.corpus import opinion_lexicon
534
+ >>> opinion_lexicon.words()[:4]
535
+ ['2-faced', '2-faces', 'abnormal', 'abolish']
536
+
537
+ The OpinionLexiconCorpusReader also provides shortcuts to retrieve positive/negative
538
+ words:
539
+
540
+ >>> opinion_lexicon.negative()[:4]
541
+ ['2-faced', '2-faces', 'abnormal', 'abolish']
542
+
543
+ Note that words from `words()` method in opinion_lexicon are sorted by file id,
544
+ not alphabetically:
545
+
546
+ >>> opinion_lexicon.words()[0:10]
547
+ ['2-faced', '2-faces', 'abnormal', 'abolish', 'abominable', 'abominably',
548
+ 'abominate', 'abomination', 'abort', 'aborted']
549
+ >>> sorted(opinion_lexicon.words())[0:10]
550
+ ['2-faced', '2-faces', 'a+', 'abnormal', 'abolish', 'abominable', 'abominably',
551
+ 'abominate', 'abomination', 'abort']
552
+
553
+ ppattach
554
+ --------
555
+ The Prepositional Phrase Attachment corpus is a corpus of
556
+ prepositional phrase attachment decisions. Each instance in the
557
+ corpus is encoded as a ``PPAttachment`` object:
558
+
559
+ >>> from nltk.corpus import ppattach
560
+ >>> ppattach.attachments('training') # doctest: +NORMALIZE_WHITESPACE
561
+ [PPAttachment(sent='0', verb='join', noun1='board',
562
+ prep='as', noun2='director', attachment='V'),
563
+ PPAttachment(sent='1', verb='is', noun1='chairman',
564
+ prep='of', noun2='N.V.', attachment='N'),
565
+ ...]
566
+ >>> inst = ppattach.attachments('training')[0]
567
+ >>> (inst.sent, inst.verb, inst.noun1, inst.prep, inst.noun2)
568
+ ('0', 'join', 'board', 'as', 'director')
569
+ >>> inst.attachment
570
+ 'V'
571
+
572
+ product_reviews_1 and product_reviews_2
573
+ ---------------------------------------
574
+ These two datasets respectively contain annotated customer reviews of 5 and 9
575
+ products from amazon.com.
576
+
577
+ >>> from nltk.corpus import product_reviews_1
578
+ >>> camera_reviews = product_reviews_1.reviews('Canon_G3.txt')
579
+ >>> review = camera_reviews[0]
580
+ >>> review.sents()[0]
581
+ ['i', 'recently', 'purchased', 'the', 'canon', 'powershot', 'g3', 'and', 'am',
582
+ 'extremely', 'satisfied', 'with', 'the', 'purchase', '.']
583
+ >>> review.features()
584
+ [('canon powershot g3', '+3'), ('use', '+2'), ('picture', '+2'),
585
+ ('picture quality', '+1'), ('picture quality', '+1'), ('camera', '+2'),
586
+ ('use', '+2'), ('feature', '+1'), ('picture quality', '+3'), ('use', '+1'),
587
+ ('option', '+1')]
588
+
589
+ It is also possible to reach the same information directly from the stream:
590
+
591
+ >>> product_reviews_1.features('Canon_G3.txt')
592
+ [('canon powershot g3', '+3'), ('use', '+2'), ...]
593
+
594
+ We can compute stats for specific product features:
595
+
596
+ >>> n_reviews = len([(feat,score) for (feat,score) in product_reviews_1.features('Canon_G3.txt') if feat=='picture'])
597
+ >>> tot = sum([int(score) for (feat,score) in product_reviews_1.features('Canon_G3.txt') if feat=='picture'])
598
+ >>> # We use float for backward compatibility with division in Python2.7
599
+ >>> mean = tot/float(n_reviews)
600
+ >>> print(n_reviews, tot, mean)
601
+ 15 24 1.6
602
+
603
+ pros_cons
604
+ ---------
605
+ A list of pros/cons sentences for determining context (aspect) dependent
606
+ sentiment words, which are then applied to sentiment analysis of comparative
607
+ sentences.
608
+
609
+ >>> from nltk.corpus import pros_cons
610
+ >>> pros_cons.sents(categories='Cons')
611
+ [['East', 'batteries', '!', 'On', '-', 'off', 'switch', 'too', 'easy',
612
+ 'to', 'maneuver', '.'], ['Eats', '...', 'no', ',', 'GULPS', 'batteries'],
613
+ ...]
614
+ >>> pros_cons.words('IntegratedPros.txt')
615
+ ['Easy', 'to', 'use', ',', 'economical', '!', ...]
616
+
617
+ semcor
618
+ ------
619
+ The Brown Corpus, annotated with WordNet senses.
620
+
621
+ >>> from nltk.corpus import semcor
622
+ >>> semcor.words('brown2/tagfiles/br-n12.xml') # doctest: +ELLIPSIS
623
+ ['When', 'several', 'minutes', 'had', 'passed', ...]
624
+ >>> sent = semcor.xml('brown2/tagfiles/br-n12.xml').findall('context/p/s')[0]
625
+ >>> for wordform in sent.getchildren():
626
+ ... print(wordform.text, end=' ')
627
+ ... for key in sorted(wordform.keys()):
628
+ ... print(key + '=' + wordform.get(key), end=' ')
629
+ ... print()
630
+ ...
631
+ When cmd=ignore pos=WRB
632
+ several cmd=done lemma=several lexsn=5:00:00:some(a):00 pos=JJ wnsn=1
633
+ minutes cmd=done lemma=minute lexsn=1:28:00:: pos=NN wnsn=1
634
+ had cmd=done ot=notag pos=VBD
635
+ passed cmd=done lemma=pass lexsn=2:38:03:: pos=VB wnsn=4
636
+ and cmd=ignore pos=CC
637
+ Curt cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
638
+ had cmd=done ot=notag pos=VBD
639
+ n't cmd=done lemma=n't lexsn=4:02:00:: pos=RB wnsn=0
640
+ emerged cmd=done lemma=emerge lexsn=2:30:00:: pos=VB wnsn=1
641
+ from cmd=ignore pos=IN
642
+ the cmd=ignore pos=DT
643
+ livery_stable cmd=done lemma=livery_stable lexsn=1:06:00:: pos=NN wnsn=1
644
+ ,
645
+ Brenner cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
646
+ re-entered cmd=done lemma=re-enter lexsn=2:38:00:: pos=VB wnsn=1
647
+ the cmd=ignore pos=DT
648
+ hotel cmd=done lemma=hotel lexsn=1:06:00:: pos=NN wnsn=1
649
+ and cmd=ignore pos=CC
650
+ faced cmd=done lemma=face lexsn=2:42:02:: pos=VB wnsn=4
651
+ Summers cmd=done lemma=person lexsn=1:03:00:: pn=person pos=NNP rdf=person wnsn=1
652
+ across cmd=ignore pos=IN
653
+ the cmd=ignore pos=DT
654
+ counter cmd=done lemma=counter lexsn=1:06:00:: pos=NN wnsn=1
655
+ .
656
+
657
+ senseval
658
+ --------
659
+ The Senseval 2 corpus is a word sense disambiguation corpus. Each
660
+ item in the corpus corresponds to a single ambiguous word. For each
661
+ of these words, the corpus contains a list of instances, corresponding
662
+ to occurrences of that word. Each instance provides the word; a list
663
+ of word senses that apply to the word occurrence; and the word's
664
+ context.
665
+
666
+ >>> from nltk.corpus import senseval
667
+ >>> senseval.fileids()
668
+ ['hard.pos', 'interest.pos', 'line.pos', 'serve.pos']
669
+ >>> senseval.instances('hard.pos')
670
+ ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
671
+ [SensevalInstance(word='hard-a',
672
+ position=20,
673
+ context=[('``', '``'), ('he', 'PRP'), ...('hard', 'JJ'), ...],
674
+ senses=('HARD1',)),
675
+ SensevalInstance(word='hard-a',
676
+ position=10,
677
+ context=[('clever', 'NNP'), ...('hard', 'JJ'), ('time', 'NN'), ...],
678
+ senses=('HARD1',)), ...]
679
+
680
+ The following code looks at instances of the word 'interest', and
681
+ displays their local context (2 words on each side) and word sense(s):
682
+
683
+ >>> for inst in senseval.instances('interest.pos')[:10]:
684
+ ... p = inst.position
685
+ ... left = ' '.join(w for (w,t) in inst.context[p-2:p])
686
+ ... word = ' '.join(w for (w,t) in inst.context[p:p+1])
687
+ ... right = ' '.join(w for (w,t) in inst.context[p+1:p+3])
688
+ ... senses = ' '.join(inst.senses)
689
+ ... print('%20s |%10s | %-15s -> %s' % (left, word, right, senses))
690
+ declines in | interest | rates . -> interest_6
691
+ indicate declining | interest | rates because -> interest_6
692
+ in short-term | interest | rates . -> interest_6
693
+ 4 % | interest | in this -> interest_5
694
+ company with | interests | in the -> interest_5
695
+ , plus | interest | . -> interest_6
696
+ set the | interest | rate on -> interest_6
697
+ 's own | interest | , prompted -> interest_4
698
+ principal and | interest | is the -> interest_6
699
+ increase its | interest | to 70 -> interest_5
700
+
701
+ sentence_polarity
702
+ -----------------
703
+ The Sentence Polarity dataset contains 5331 positive and 5331 negative processed
704
+ sentences.
705
+
706
+ >>> from nltk.corpus import sentence_polarity
707
+ >>> sentence_polarity.sents()
708
+ [['simplistic', ',', 'silly', 'and', 'tedious', '.'], ["it's", 'so', 'laddish',
709
+ 'and', 'juvenile', ',', 'only', 'teenage', 'boys', 'could', 'possibly', 'find',
710
+ 'it', 'funny', '.'], ...]
711
+ >>> sentence_polarity.categories()
712
+ ['neg', 'pos']
713
+ >>> sentence_polarity.sents()[1]
714
+ ["it's", 'so', 'laddish', 'and', 'juvenile', ',', 'only', 'teenage', 'boys',
715
+ 'could', 'possibly', 'find', 'it', 'funny', '.']
716
+
717
+ shakespeare
718
+ -----------
719
+ The Shakespeare corpus contains a set of Shakespeare plays, formatted
720
+ as XML files. These corpora are returned as ElementTree objects:
721
+
722
+ >>> from nltk.corpus import shakespeare
723
+ >>> from xml.etree import ElementTree
724
+ >>> shakespeare.fileids() # doctest: +ELLIPSIS
725
+ ['a_and_c.xml', 'dream.xml', 'hamlet.xml', 'j_caesar.xml', ...]
726
+ >>> play = shakespeare.xml('dream.xml')
727
+ >>> print(play) # doctest: +ELLIPSIS
728
+ <Element 'PLAY' at ...>
729
+ >>> print('%s: %s' % (play[0].tag, play[0].text))
730
+ TITLE: A Midsummer Night's Dream
731
+ >>> personae = [persona.text for persona in
732
+ ... play.findall('PERSONAE/PERSONA')]
733
+ >>> print(personae) # doctest: +ELLIPSIS
734
+ ['THESEUS, Duke of Athens.', 'EGEUS, father to Hermia.', ...]
735
+ >>> # Find and print speakers not listed as personae
736
+ >>> names = [persona.split(',')[0] for persona in personae]
737
+ >>> speakers = set(speaker.text for speaker in
738
+ ... play.findall('*/*/*/SPEAKER'))
739
+ >>> print(sorted(speakers.difference(names))) # doctest: +NORMALIZE_WHITESPACE
740
+ ['ALL', 'COBWEB', 'DEMETRIUS', 'Fairy', 'HERNIA', 'LYSANDER',
741
+ 'Lion', 'MOTH', 'MUSTARDSEED', 'Moonshine', 'PEASEBLOSSOM',
742
+ 'Prologue', 'Pyramus', 'Thisbe', 'Wall']
743
+
744
+ subjectivity
745
+ -----------
746
+ The Subjectivity Dataset contains 5000 subjective and 5000 objective processed
747
+ sentences.
748
+
749
+ >>> from nltk.corpus import subjectivity
750
+ >>> subjectivity.categories()
751
+ ['obj', 'subj']
752
+ >>> subjectivity.sents()[23]
753
+ ['television', 'made', 'him', 'famous', ',', 'but', 'his', 'biggest', 'hits',
754
+ 'happened', 'off', 'screen', '.']
755
+ >>> subjectivity.words(categories='subj')
756
+ ['smart', 'and', 'alert', ',', 'thirteen', ...]
757
+
758
+ toolbox
759
+ -------
760
+ The Toolbox corpus distributed with NLTK contains a sample lexicon and
761
+ several sample texts from the Rotokas language. The Toolbox corpus
762
+ reader returns Toolbox files as XML ElementTree objects. The
763
+ following example loads the Rotokas dictionary, and figures out the
764
+ distribution of part-of-speech tags for reduplicated words.
765
+
766
+ .. doctest: +SKIP
767
+
768
+ >>> from nltk.corpus import toolbox
769
+ >>> from nltk.probability import FreqDist
770
+ >>> from xml.etree import ElementTree
771
+ >>> import re
772
+ >>> rotokas = toolbox.xml('rotokas.dic')
773
+ >>> redup_pos_freqdist = FreqDist()
774
+ >>> # Note: we skip over the first record, which is actually
775
+ >>> # the header.
776
+ >>> for record in rotokas[1:]:
777
+ ... lexeme = record.find('lx').text
778
+ ... if re.match(r'(.*)\1$', lexeme):
779
+ ... redup_pos_freqdist[record.find('ps').text] += 1
780
+ >>> for item, count in redup_pos_freqdist.most_common():
781
+ ... print(item, count)
782
+ V 41
783
+ N 14
784
+ ??? 4
785
+
786
+ This example displays some records from a Rotokas text:
787
+
788
+ .. doctest: +SKIP
789
+
790
+ >>> river = toolbox.xml('rotokas/river.txt', key='ref')
791
+ >>> for record in river.findall('record')[:3]:
792
+ ... for piece in record:
793
+ ... if len(piece.text) > 60:
794
+ ... print('%-6s %s...' % (piece.tag, piece.text[:57]))
795
+ ... else:
796
+ ... print('%-6s %s' % (piece.tag, piece.text))
797
+ ref Paragraph 1
798
+ t ``Viapau oisio ra ovaupasi ...
799
+ m viapau oisio ra ovau -pa -si ...
800
+ g NEG this way/like this and forget -PROG -2/3.DL...
801
+ p NEG ??? CONJ V.I -SUFF.V.3 -SUFF.V...
802
+ f ``No ken lus tingting wanema samting papa i bin tok,'' Na...
803
+ fe ``Don't forget what Dad said,'' yelled Naomi.
804
+ ref 2
805
+ t Osa Ira ora Reviti viapau uvupasiva.
806
+ m osa Ira ora Reviti viapau uvu -pa -si ...
807
+ g as/like name and name NEG hear/smell -PROG -2/3...
808
+ p CONJ N.PN CONJ N.PN NEG V.T -SUFF.V.3 -SUF...
809
+ f Tasol Ila na David no bin harim toktok.
810
+ fe But Ila and David took no notice.
811
+ ref 3
812
+ t Ikaupaoro rokosiva ...
813
+ m ikau -pa -oro roko -si -va ...
814
+ g run/hurry -PROG -SIM go down -2/3.DL.M -RP ...
815
+ p V.T -SUFF.V.3 -SUFF.V.4 ADV -SUFF.V.4 -SUFF.VT....
816
+ f Tupela i bin hariap i go long wara .
817
+ fe They raced to the river.
818
+
819
+ timit
820
+ -----
821
+ The NLTK data package includes a fragment of the TIMIT
822
+ Acoustic-Phonetic Continuous Speech Corpus. This corpus is broken
823
+ down into small speech samples, each of which is available as a wave
824
+ file, a phonetic transcription, and a tokenized word list.
825
+
826
+ >>> from nltk.corpus import timit
827
+ >>> print(timit.utteranceids()) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
828
+ ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466',
829
+ 'dr1-fvmh0/si2096', 'dr1-fvmh0/si836', 'dr1-fvmh0/sx116',
830
+ 'dr1-fvmh0/sx206', 'dr1-fvmh0/sx26', 'dr1-fvmh0/sx296', ...]
831
+
832
+ >>> item = timit.utteranceids()[5]
833
+ >>> print(timit.phones(item)) # doctest: +NORMALIZE_WHITESPACE
834
+ ['h#', 'k', 'l', 'ae', 's', 'pcl', 'p', 'dh', 'ax',
835
+ 's', 'kcl', 'k', 'r', 'ux', 'ix', 'nx', 'y', 'ax',
836
+ 'l', 'eh', 'f', 'tcl', 't', 'hh', 'ae', 'n', 'dcl',
837
+ 'd', 'h#']
838
+ >>> print(timit.words(item))
839
+ ['clasp', 'the', 'screw', 'in', 'your', 'left', 'hand']
840
+ >>> timit.play(item) # doctest: +SKIP
841
+
842
+ The corpus reader can combine the word segmentation information with
843
+ the phonemes to produce a single tree structure:
844
+
845
+ >>> for tree in timit.phone_trees(item):
846
+ ... print(tree)
847
+ (S
848
+ h#
849
+ (clasp k l ae s pcl p)
850
+ (the dh ax)
851
+ (screw s kcl k r ux)
852
+ (in ix nx)
853
+ (your y ax)
854
+ (left l eh f tcl t)
855
+ (hand hh ae n dcl d)
856
+ h#)
857
+
858
+ The start time and stop time of each phoneme, word, and sentence are
859
+ also available:
860
+
861
+ >>> print(timit.phone_times(item)) # doctest: +ELLIPSIS
862
+ [('h#', 0, 2190), ('k', 2190, 3430), ('l', 3430, 4326), ...]
863
+ >>> print(timit.word_times(item)) # doctest: +ELLIPSIS
864
+ [('clasp', 2190, 8804), ('the', 8804, 9734), ...]
865
+ >>> print(timit.sent_times(item))
866
+ [('Clasp the screw in your left hand.', 0, 32154)]
867
+
868
+ We can use these times to play selected pieces of a speech sample:
869
+
870
+ >>> timit.play(item, 2190, 8804) # 'clasp' # doctest: +SKIP
871
+
872
+ The corpus reader can also be queried for information about the
873
+ speaker and sentence identifier for a given speech sample:
874
+
875
+ >>> print(timit.spkrid(item))
876
+ dr1-fvmh0
877
+ >>> print(timit.sentid(item))
878
+ sx116
879
+ >>> print(timit.spkrinfo(timit.spkrid(item))) # doctest: +NORMALIZE_WHITESPACE
880
+ SpeakerInfo(id='VMH0',
881
+ sex='F',
882
+ dr='1',
883
+ use='TRN',
884
+ recdate='03/11/86',
885
+ birthdate='01/08/60',
886
+ ht='5\'05"',
887
+ race='WHT',
888
+ edu='BS',
889
+ comments='BEST NEW ENGLAND ACCENT SO FAR')
890
+
891
+ >>> # List the speech samples from the same speaker:
892
+ >>> timit.utteranceids(spkrid=timit.spkrid(item)) # doctest: +ELLIPSIS
893
+ ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466', ...]
894
+
895
+ twitter_samples
896
+ ---------------
897
+
898
+ Twitter is well-known microblog service that allows public data to be
899
+ collected via APIs. NLTK's twitter corpus currently contains a sample of 20k Tweets
900
+ retrieved from the Twitter Streaming API.
901
+
902
+ >>> from nltk.corpus import twitter_samples
903
+ >>> twitter_samples.fileids()
904
+ ['negative_tweets.json', 'positive_tweets.json', 'tweets.20150430-223406.json']
905
+
906
+ We follow standard practice in storing full Tweets as line-separated
907
+ JSON. These data structures can be accessed via `tweets.docs()`. However, in general it
908
+ is more practical to focus just on the text field of the Tweets, which
909
+ are accessed via the `strings()` method.
910
+
911
+ >>> twitter_samples.strings('tweets.20150430-223406.json')
912
+ ['RT @KirkKus: Indirect cost of the UK being in the EU is estimated to be costing Britain \xa3170 billion per year! #BetterOffOut #UKIP', ...]
913
+
914
+ The default tokenizer for Tweets is specialised for 'casual' text, and
915
+ the `tokenized()` method returns a list of lists of tokens.
916
+
917
+ >>> twitter_samples.tokenized('tweets.20150430-223406.json')
918
+ [['RT', '@KirkKus', ':', 'Indirect', 'cost', 'of', 'the', 'UK', 'being', 'in', ...],
919
+ ['VIDEO', ':', 'Sturgeon', 'on', 'post-election', 'deals', 'http://t.co/BTJwrpbmOY'], ...]
920
+
921
+ rte
922
+ ---
923
+ The RTE (Recognizing Textual Entailment) corpus was derived from the
924
+ RTE1, RTE2 and RTE3 datasets (dev and test data), and consists of a
925
+ list of XML-formatted 'text'/'hypothesis' pairs.
926
+
927
+ >>> from nltk.corpus import rte
928
+ >>> print(rte.fileids()) # doctest: +ELLIPSIS
929
+ ['rte1_dev.xml', 'rte1_test.xml', 'rte2_dev.xml', ..., 'rte3_test.xml']
930
+ >>> rtepairs = rte.pairs(['rte2_test.xml', 'rte3_test.xml'])
931
+ >>> print(rtepairs) # doctest: +ELLIPSIS
932
+ [<RTEPair: gid=2-8>, <RTEPair: gid=2-9>, <RTEPair: gid=2-15>, ...]
933
+
934
+ In the gold standard test sets, each pair is labeled according to
935
+ whether or not the text 'entails' the hypothesis; the
936
+ entailment value is mapped to an integer 1 (True) or 0 (False).
937
+
938
+ >>> rtepairs[5]
939
+ <RTEPair: gid=2-23>
940
+ >>> rtepairs[5].text # doctest: +NORMALIZE_WHITESPACE
941
+ 'His wife Strida won a seat in parliament after forging an alliance
942
+ with the main anti-Syrian coalition in the recent election.'
943
+ >>> rtepairs[5].hyp
944
+ 'Strida elected to parliament.'
945
+ >>> rtepairs[5].value
946
+ 1
947
+
948
+ The RTE corpus also supports an ``xml()`` method which produces ElementTrees.
949
+
950
+ >>> xmltree = rte.xml('rte3_dev.xml')
951
+ >>> xmltree # doctest: +SKIP
952
+ <Element entailment-corpus at ...>
953
+ >>> xmltree[7].findtext('t') # doctest: +NORMALIZE_WHITESPACE
954
+ "Mrs. Bush's approval ratings have remained very high, above 80%,
955
+ even as her husband's have recently dropped below 50%."
956
+
957
+ verbnet
958
+ -------
959
+ The VerbNet corpus is a lexicon that divides verbs into classes, based
960
+ on their syntax-semantics linking behavior. The basic elements in the
961
+ lexicon are verb lemmas, such as 'abandon' and 'accept', and verb
962
+ classes, which have identifiers such as 'remove-10.1' and
963
+ 'admire-31.2-1'. These class identifiers consist of a representative
964
+ verb selected from the class, followed by a numerical identifier. The
965
+ list of verb lemmas, and the list of class identifiers, can be
966
+ retrieved with the following methods:
967
+
968
+ >>> from nltk.corpus import verbnet
969
+ >>> verbnet.lemmas()[20:25]
970
+ ['accelerate', 'accept', 'acclaim', 'accompany', 'accrue']
971
+ >>> verbnet.classids()[:5]
972
+ ['accompany-51.7', 'admire-31.2', 'admire-31.2-1', 'admit-65', 'adopt-93']
973
+
974
+ The `classids()` method may also be used to retrieve the classes that
975
+ a given lemma belongs to:
976
+
977
+ >>> verbnet.classids('accept')
978
+ ['approve-77', 'characterize-29.2-1-1', 'obtain-13.5.2']
979
+
980
+ The `classids()` method may additionally be used to retrieve all classes
981
+ within verbnet if nothing is passed:
982
+
983
+ >>> verbnet.classids()
984
+ ['accompany-51.7', 'admire-31.2', 'admire-31.2-1', 'admit-65', 'adopt-93', 'advise-37.9', 'advise-37.9-1', 'allow-64', 'amalgamate-22.2', 'amalgamate-22.2-1', 'amalgamate-22.2-1-1', 'amalgamate-22.2-2', 'amalgamate-22.2-2-1', 'amalgamate-22.2-3', 'amalgamate-22.2-3-1', 'amalgamate-22.2-3-1-1', 'amalgamate-22.2-3-2', 'amuse-31.1', 'animal_sounds-38', 'appeal-31.4', 'appeal-31.4-1', 'appeal-31.4-2', 'appeal-31.4-3', 'appear-48.1.1', 'appoint-29.1', 'approve-77', 'assessment-34', 'assuming_position-50', 'avoid-52', 'banish-10.2', 'battle-36.4', 'battle-36.4-1', 'begin-55.1', 'begin-55.1-1', 'being_dressed-41.3.3', 'bend-45.2', 'berry-13.7', 'bill-54.5', 'body_internal_motion-49', 'body_internal_states-40.6', 'braid-41.2.2', 'break-45.1', 'breathe-40.1.2', 'breathe-40.1.2-1', 'bring-11.3', 'bring-11.3-1', 'build-26.1', 'build-26.1-1', 'bulge-47.5.3', 'bump-18.4', 'bump-18.4-1', 'butter-9.9', 'calibratable_cos-45.6', 'calibratable_cos-45.6-1', 'calve-28', 'captain-29.8', 'captain-29.8-1', 'captain-29.8-1-1', 'care-88', 'care-88-1', 'carry-11.4', 'carry-11.4-1', 'carry-11.4-1-1', 'carve-21.2', 'carve-21.2-1', 'carve-21.2-2', 'change_bodily_state-40.8.4', 'characterize-29.2', 'characterize-29.2-1', 'characterize-29.2-1-1', 'characterize-29.2-1-2', 'chase-51.6', 'cheat-10.6', 'cheat-10.6-1', 'cheat-10.6-1-1', 'chew-39.2', 'chew-39.2-1', 'chew-39.2-2', 'chit_chat-37.6', 'clear-10.3', 'clear-10.3-1', 'cling-22.5', 'coil-9.6', 'coil-9.6-1', 'coloring-24', 'complain-37.8', 'complete-55.2', 'concealment-16', 'concealment-16-1', 'confess-37.10', 'confine-92', 'confine-92-1', 'conjecture-29.5', 'conjecture-29.5-1', 'conjecture-29.5-2', 'consider-29.9', 'consider-29.9-1', 'consider-29.9-1-1', 'consider-29.9-1-1-1', 'consider-29.9-2', 'conspire-71', 'consume-66', 'consume-66-1', 'contiguous_location-47.8', 'contiguous_location-47.8-1', 'contiguous_location-47.8-2', 'continue-55.3', 'contribute-13.2', 'contribute-13.2-1', 'contribute-13.2-1-1', 'contribute-13.2-1-1-1', 'contribute-13.2-2', 'contribute-13.2-2-1', 'convert-26.6.2', 'convert-26.6.2-1', 'cooking-45.3', 'cooperate-73', 'cooperate-73-1', 'cooperate-73-2', 'cooperate-73-3', 'cope-83', 'cope-83-1', 'cope-83-1-1', 'correlate-86', 'correspond-36.1', 'correspond-36.1-1', 'correspond-36.1-1-1', 'cost-54.2', 'crane-40.3.2', 'create-26.4', 'create-26.4-1', 'curtsey-40.3.3', 'cut-21.1', 'cut-21.1-1', 'debone-10.8', 'declare-29.4', 'declare-29.4-1', 'declare-29.4-1-1', 'declare-29.4-1-1-1', 'declare-29.4-1-1-2', 'declare-29.4-1-1-3', 'declare-29.4-2', 'dedicate-79', 'defend-85', 'destroy-44', 'devour-39.4', 'devour-39.4-1', 'devour-39.4-2', 'differ-23.4', 'dine-39.5', 'disappearance-48.2', 'disassemble-23.3', 'discover-84', 'discover-84-1', 'discover-84-1-1', 'dress-41.1.1', 'dressing_well-41.3.2', 'drive-11.5', 'drive-11.5-1', 'dub-29.3', 'dub-29.3-1', 'eat-39.1', 'eat-39.1-1', 'eat-39.1-2', 'enforce-63', 'engender-27', 'entity_specific_cos-45.5', 'entity_specific_modes_being-47.2', 'equip-13.4.2', 'equip-13.4.2-1', 'equip-13.4.2-1-1', 'escape-51.1', 'escape-51.1-1', 'escape-51.1-2', 'escape-51.1-2-1', 'exceed-90', 'exchange-13.6', 'exchange-13.6-1', 'exchange-13.6-1-1', 'exhale-40.1.3', 'exhale-40.1.3-1', 'exhale-40.1.3-2', 'exist-47.1', 'exist-47.1-1', 'exist-47.1-1-1', 'feeding-39.7', 'ferret-35.6', 'fill-9.8', 'fill-9.8-1', 'fit-54.3', 'flinch-40.5', 'floss-41.2.1', 'focus-87', 'forbid-67', 'force-59', 'force-59-1', 'free-80', 'free-80-1', 'fulfilling-13.4.1', 'fulfilling-13.4.1-1', 'fulfilling-13.4.1-2', 'funnel-9.3', 'funnel-9.3-1', 'funnel-9.3-2', 'funnel-9.3-2-1', 'future_having-13.3', 'get-13.5.1', 'get-13.5.1-1', 'give-13.1', 'give-13.1-1', 'gobble-39.3', 'gobble-39.3-1', 'gobble-39.3-2', 'gorge-39.6', 'groom-41.1.2', 'grow-26.2', 'help-72', 'help-72-1', 'herd-47.5.2', 'hiccup-40.1.1', 'hit-18.1', 'hit-18.1-1', 'hold-15.1', 'hold-15.1-1', 'hunt-35.1', 'hurt-40.8.3', 'hurt-40.8.3-1', 'hurt-40.8.3-1-1', 'hurt-40.8.3-2', 'illustrate-25.3', 'image_impression-25.1', 'indicate-78', 'indicate-78-1', 'indicate-78-1-1', 'inquire-37.1.2', 'instr_communication-37.4', 'investigate-35.4', 'judgement-33', 'keep-15.2', 'knead-26.5', 'learn-14', 'learn-14-1', 'learn-14-2', 'learn-14-2-1', 'leave-51.2', 'leave-51.2-1', 'lecture-37.11', 'lecture-37.11-1', 'lecture-37.11-1-1', 'lecture-37.11-2', 'light_emission-43.1', 'limit-76', 'linger-53.1', 'linger-53.1-1', 'lodge-46', 'long-32.2', 'long-32.2-1', 'long-32.2-2', 'manner_speaking-37.3', 'marry-36.2', 'marvel-31.3', 'marvel-31.3-1', 'marvel-31.3-2', 'marvel-31.3-3', 'marvel-31.3-4', 'marvel-31.3-5', 'marvel-31.3-6', 'marvel-31.3-7', 'marvel-31.3-8', 'marvel-31.3-9', 'masquerade-29.6', 'masquerade-29.6-1', 'masquerade-29.6-2', 'matter-91', 'meander-47.7', 'meet-36.3', 'meet-36.3-1', 'meet-36.3-2', 'mine-10.9', 'mix-22.1', 'mix-22.1-1', 'mix-22.1-1-1', 'mix-22.1-2', 'mix-22.1-2-1', 'modes_of_being_with_motion-47.3', 'murder-42.1', 'murder-42.1-1', 'neglect-75', 'neglect-75-1', 'neglect-75-1-1', 'neglect-75-2', 'nonvehicle-51.4.2', 'nonverbal_expression-40.2', 'obtain-13.5.2', 'obtain-13.5.2-1', 'occurrence-48.3', 'order-60', 'order-60-1', 'orphan-29.7', 'other_cos-45.4', 'pain-40.8.1', 'pay-68', 'peer-30.3', 'pelt-17.2', 'performance-26.7', 'performance-26.7-1', 'performance-26.7-1-1', 'performance-26.7-2', 'performance-26.7-2-1', 'pit-10.7', 'pocket-9.10', 'pocket-9.10-1', 'poison-42.2', 'poke-19', 'pour-9.5', 'preparing-26.3', 'preparing-26.3-1', 'preparing-26.3-2', 'price-54.4', 'push-12', 'push-12-1', 'push-12-1-1', 'put-9.1', 'put-9.1-1', 'put-9.1-2', 'put_direction-9.4', 'put_spatial-9.2', 'put_spatial-9.2-1', 'reach-51.8', 'reflexive_appearance-48.1.2', 'refrain-69', 'register-54.1', 'rely-70', 'remove-10.1', 'risk-94', 'risk-94-1', 'roll-51.3.1', 'rummage-35.5', 'run-51.3.2', 'rush-53.2', 'say-37.7', 'say-37.7-1', 'say-37.7-1-1', 'say-37.7-2', 'scribble-25.2', 'search-35.2', 'see-30.1', 'see-30.1-1', 'see-30.1-1-1', 'send-11.1', 'send-11.1-1', 'separate-23.1', 'separate-23.1-1', 'separate-23.1-2', 'settle-89', 'shake-22.3', 'shake-22.3-1', 'shake-22.3-1-1', 'shake-22.3-2', 'shake-22.3-2-1', 'sight-30.2', 'simple_dressing-41.3.1', 'slide-11.2', 'slide-11.2-1-1', 'smell_emission-43.3', 'snooze-40.4', 'sound_emission-43.2', 'sound_existence-47.4', 'spank-18.3', 'spatial_configuration-47.6', 'split-23.2', 'spray-9.7', 'spray-9.7-1', 'spray-9.7-1-1', 'spray-9.7-2', 'stalk-35.3', 'steal-10.5', 'stimulus_subject-30.4', 'stop-55.4', 'stop-55.4-1', 'substance_emission-43.4', 'succeed-74', 'succeed-74-1', 'succeed-74-1-1', 'succeed-74-2', 'suffocate-40.7', 'suspect-81', 'swarm-47.5.1', 'swarm-47.5.1-1', 'swarm-47.5.1-2', 'swarm-47.5.1-2-1', 'swat-18.2', 'talk-37.5', 'tape-22.4', 'tape-22.4-1', 'tell-37.2', 'throw-17.1', 'throw-17.1-1', 'throw-17.1-1-1', 'tingle-40.8.2', 'touch-20', 'touch-20-1', 'transcribe-25.4', 'transfer_mesg-37.1.1', 'transfer_mesg-37.1.1-1', 'transfer_mesg-37.1.1-1-1', 'try-61', 'turn-26.6.1', 'turn-26.6.1-1', 'urge-58', 'vehicle-51.4.1', 'vehicle-51.4.1-1', 'waltz-51.5', 'want-32.1', 'want-32.1-1', 'want-32.1-1-1', 'weather-57', 'weekend-56', 'wink-40.3.1', 'wink-40.3.1-1', 'wipe_instr-10.4.2', 'wipe_instr-10.4.2-1', 'wipe_manner-10.4.1', 'wipe_manner-10.4.1-1', 'wish-62', 'withdraw-82', 'withdraw-82-1', 'withdraw-82-2', 'withdraw-82-3']
985
+
986
+ The primary object in the lexicon is a class record, which is stored
987
+ as an ElementTree xml object. The class record for a given class
988
+ identifier is returned by the `vnclass()` method:
989
+
990
+ >>> verbnet.vnclass('remove-10.1') # doctest: +ELLIPSIS
991
+ <Element 'VNCLASS' at ...>
992
+
993
+ The `vnclass()` method also accepts "short" identifiers, such as '10.1':
994
+
995
+ >>> verbnet.vnclass('10.1') # doctest: +ELLIPSIS
996
+ <Element 'VNCLASS' at ...>
997
+
998
+ See the Verbnet documentation, or the Verbnet files, for information
999
+ about the structure of this xml. As an example, we can retrieve a
1000
+ list of thematic roles for a given Verbnet class:
1001
+
1002
+ >>> vn_31_2 = verbnet.vnclass('admire-31.2')
1003
+ >>> for themrole in vn_31_2.findall('THEMROLES/THEMROLE'):
1004
+ ... print(themrole.attrib['type'], end=' ')
1005
+ ... for selrestr in themrole.findall('SELRESTRS/SELRESTR'):
1006
+ ... print('[%(Value)s%(type)s]' % selrestr.attrib, end=' ')
1007
+ ... print()
1008
+ Theme
1009
+ Experiencer [+animate]
1010
+ Predicate
1011
+
1012
+ The Verbnet corpus also provides a variety of pretty printing
1013
+ functions that can be used to display the xml contents in a more
1014
+ concise form. The simplest such method is `pprint()`:
1015
+
1016
+ >>> print(verbnet.pprint('57'))
1017
+ weather-57
1018
+ Subclasses: (none)
1019
+ Members: blow clear drizzle fog freeze gust hail howl lightning mist
1020
+ mizzle pelt pour precipitate rain roar shower sleet snow spit spot
1021
+ sprinkle storm swelter teem thaw thunder
1022
+ Thematic roles:
1023
+ * Theme[+concrete +force]
1024
+ Frames:
1025
+ Intransitive (Expletive Subject)
1026
+ Example: It's raining.
1027
+ Syntax: LEX[it] LEX[[+be]] VERB
1028
+ Semantics:
1029
+ * weather(during(E), Weather_type, ?Theme)
1030
+ NP (Expletive Subject, Theme Object)
1031
+ Example: It's raining cats and dogs.
1032
+ Syntax: LEX[it] LEX[[+be]] VERB NP[Theme]
1033
+ Semantics:
1034
+ * weather(during(E), Weather_type, Theme)
1035
+ PP (Expletive Subject, Theme-PP)
1036
+ Example: It was pelting with rain.
1037
+ Syntax: LEX[it[+be]] VERB PREP[with] NP[Theme]
1038
+ Semantics:
1039
+ * weather(during(E), Weather_type, Theme)
1040
+
1041
+ Verbnet gives us frames that link the syntax and semantics using an example.
1042
+ These frames are part of the corpus and we can use `frames()` to get a frame
1043
+ for a given verbnet class.
1044
+
1045
+ >>> frame = verbnet.frames('57')
1046
+ >>> frame == [{'semantics': [{'arguments': [{'value': 'during(E)', 'type': 'Event'}, {'value': 'Weather_type', 'type': 'VerbSpecific'}, {'value': '?Theme', 'type': 'ThemRole'}], 'predicate_value': 'weather'}], 'example': "It's raining.", 'syntax': [{'pos_tag': 'LEX', 'modifiers': {'value': 'it', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'LEX', 'modifiers': {'value': '[+be]', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'VERB', 'modifiers': {'value': '', 'synrestrs': [], 'selrestrs': []}}], 'description': {'primary': 'Intransitive', 'secondary': 'Expletive Subject'}}, {'semantics': [{'arguments': [{'value': 'during(E)', 'type': 'Event'}, {'value': 'Weather_type', 'type': 'VerbSpecific'}, {'value': 'Theme', 'type': 'ThemRole'}], 'predicate_value': 'weather'}], 'example': "It's raining cats and dogs.", 'syntax': [{'pos_tag': 'LEX', 'modifiers': {'value': 'it', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'LEX', 'modifiers': {'value': '[+be]', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'VERB', 'modifiers': {'value': '', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'NP', 'modifiers': {'value': 'Theme', 'synrestrs': [], 'selrestrs': []}}], 'description': {'primary': 'NP', 'secondary': 'Expletive Subject, Theme Object'}}, {'semantics': [{'arguments': [{'value': 'during(E)', 'type': 'Event'}, {'value': 'Weather_type', 'type': 'VerbSpecific'}, {'value': 'Theme', 'type': 'ThemRole'}], 'predicate_value': 'weather'}], 'example': 'It was pelting with rain.', 'syntax': [{'pos_tag': 'LEX', 'modifiers': {'value': 'it[+be]', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'VERB', 'modifiers': {'value': '', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'PREP', 'modifiers': {'value': 'with', 'synrestrs': [], 'selrestrs': []}}, {'pos_tag': 'NP', 'modifiers': {'value': 'Theme', 'synrestrs': [], 'selrestrs': []}}], 'description': {'primary': 'PP', 'secondary': 'Expletive Subject, Theme-PP'}}]
1047
+ True
1048
+
1049
+ Verbnet corpus lets us access thematic roles individually using `themroles()`.
1050
+
1051
+ >>> themroles = verbnet.themroles('57')
1052
+ >>> themroles == [{'modifiers': [{'type': 'concrete', 'value': '+'}, {'type': 'force', 'value': '+'}], 'type': 'Theme'}]
1053
+ True
1054
+
1055
+ Verbnet classes may also have subclasses sharing similar syntactic and semantic properties
1056
+ while having differences with the superclass. The Verbnet corpus allows us to access these
1057
+ subclasses using `subclasses()`.
1058
+
1059
+ >>> print(verbnet.subclasses('9.1')) #Testing for 9.1 since '57' does not have subclasses
1060
+ ['put-9.1-1', 'put-9.1-2']
1061
+
1062
+
1063
+ nps_chat
1064
+ --------
1065
+
1066
+ The NPS Chat Corpus, Release 1.0 consists of over 10,000 posts in age-specific
1067
+ chat rooms, which have been anonymized, POS-tagged and dialogue-act tagged.
1068
+
1069
+ >>> print(nltk.corpus.nps_chat.words())
1070
+ ['now', 'im', 'left', 'with', 'this', 'gay', ...]
1071
+ >>> print(nltk.corpus.nps_chat.tagged_words())
1072
+ [('now', 'RB'), ('im', 'PRP'), ('left', 'VBD'), ...]
1073
+ >>> print(nltk.corpus.nps_chat.tagged_posts()) # doctest: +NORMALIZE_WHITESPACE
1074
+ [[('now', 'RB'), ('im', 'PRP'), ('left', 'VBD'), ('with', 'IN'),
1075
+ ('this', 'DT'), ('gay', 'JJ'), ('name', 'NN')], [(':P', 'UH')], ...]
1076
+
1077
+ We can access the XML elements corresponding to individual posts. These elements
1078
+ have ``class`` and ``user`` attributes that we can access using ``p.attrib['class']``
1079
+ and ``p.attrib['user']``. They also have text content, accessed using ``p.text``.
1080
+
1081
+ >>> print(nltk.corpus.nps_chat.xml_posts()) # doctest: +ELLIPSIS
1082
+ [<Element 'Post' at 0...>, <Element 'Post' at 0...>, ...]
1083
+ >>> posts = nltk.corpus.nps_chat.xml_posts()
1084
+ >>> sorted(nltk.FreqDist(p.attrib['class'] for p in posts).keys())
1085
+ ['Accept', 'Bye', 'Clarify', 'Continuer', 'Emotion', 'Emphasis',
1086
+ 'Greet', 'Other', 'Reject', 'Statement', 'System', 'nAnswer',
1087
+ 'whQuestion', 'yAnswer', 'ynQuestion']
1088
+ >>> posts[0].text
1089
+ 'now im left with this gay name'
1090
+
1091
+ In addition to the above methods for accessing tagged text, we can navigate
1092
+ the XML structure directly, as follows:
1093
+
1094
+ >>> tokens = posts[0].findall('terminals/t')
1095
+ >>> [t.attrib['pos'] + "/" + t.attrib['word'] for t in tokens]
1096
+ ['RB/now', 'PRP/im', 'VBD/left', 'IN/with', 'DT/this', 'JJ/gay', 'NN/name']
1097
+
1098
+ multext_east
1099
+ ------------
1100
+
1101
+ The Multext-East Corpus consists of POS-tagged versions of George Orwell's book
1102
+ 1984 in 12 languages: English, Czech, Hungarian, Macedonian, Slovenian, Serbian,
1103
+ Slovak, Romanian, Estonian, Farsi, Bulgarian and Polish.
1104
+ The corpus can be accessed using the usual methods for tagged corpora. The tagset
1105
+ can be transformed from the Multext-East specific MSD tags to the Universal tagset
1106
+ using the "tagset" parameter of all functions returning tagged parts of the corpus.
1107
+
1108
+ >>> print(nltk.corpus.multext_east.words("oana-en.xml"))
1109
+ ['It', 'was', 'a', 'bright', ...]
1110
+ >>> print(nltk.corpus.multext_east.tagged_words("oana-en.xml"))
1111
+ [('It', '#Pp3ns'), ('was', '#Vmis3s'), ('a', '#Di'), ...]
1112
+ >>> print(nltk.corpus.multext_east.tagged_sents("oana-en.xml", "universal"))
1113
+ [[('It', 'PRON'), ('was', 'VERB'), ('a', 'DET'), ...]
1114
+
1115
+
1116
+
1117
+ ---------------------
1118
+ Corpus Reader Classes
1119
+ ---------------------
1120
+
1121
+ NLTK's *corpus reader* classes are used to access the contents of a
1122
+ diverse set of corpora. Each corpus reader class is specialized to
1123
+ handle a specific corpus format. Examples include the
1124
+ `PlaintextCorpusReader`, which handles corpora that consist of a set
1125
+ of unannotated text files, and the `BracketParseCorpusReader`, which
1126
+ handles corpora that consist of files containing
1127
+ parenthesis-delineated parse trees.
1128
+
1129
+ Automatically Created Corpus Reader Instances
1130
+ =============================================
1131
+
1132
+ When the `nltk.corpus` module is imported, it automatically creates a
1133
+ set of corpus reader instances that can be used to access the corpora
1134
+ in the NLTK data distribution. Here is a small sample of those
1135
+ corpus reader instances:
1136
+
1137
+ >>> import nltk
1138
+ >>> nltk.corpus.brown # doctest: +ELLIPSIS
1139
+ <CategorizedTaggedCorpusReader ...>
1140
+ >>> nltk.corpus.treebank # doctest: +ELLIPSIS
1141
+ <BracketParseCorpusReader ...>
1142
+ >>> nltk.corpus.names # doctest: +ELLIPSIS
1143
+ <WordListCorpusReader ...>
1144
+ >>> nltk.corpus.genesis # doctest: +ELLIPSIS
1145
+ <PlaintextCorpusReader ...>
1146
+ >>> nltk.corpus.inaugural # doctest: +ELLIPSIS
1147
+ <PlaintextCorpusReader ...>
1148
+
1149
+ This sample illustrates that different corpus reader classes are used
1150
+ to read different corpora; but that the same corpus reader class may
1151
+ be used for more than one corpus (e.g., ``genesis`` and ``inaugural``).
1152
+
1153
+ Creating New Corpus Reader Instances
1154
+ ====================================
1155
+
1156
+ Although the `nltk.corpus` module automatically creates corpus reader
1157
+ instances for the corpora in the NLTK data distribution, you may
1158
+ sometimes need to create your own corpus reader. In particular, you
1159
+ would need to create your own corpus reader if you want...
1160
+
1161
+ - To access a corpus that is not included in the NLTK data
1162
+ distribution.
1163
+
1164
+ - To access a full copy of a corpus for which the NLTK data
1165
+ distribution only provides a sample.
1166
+
1167
+ - To access a corpus using a customized corpus reader (e.g., with
1168
+ a customized tokenizer).
1169
+
1170
+ To create a new corpus reader, you will first need to look up the
1171
+ signature for that corpus reader's constructor. Different corpus
1172
+ readers have different constructor signatures, but most of the
1173
+ constructor signatures have the basic form::
1174
+
1175
+ SomeCorpusReader(root, files, ...options...)
1176
+
1177
+ Where ``root`` is an absolute path to the directory containing the
1178
+ corpus data files; ``files`` is either a list of file names (relative
1179
+ to ``root``) or a regexp specifying which files should be included;
1180
+ and ``options`` are additional reader-specific options. For example,
1181
+ we can create a customized corpus reader for the genesis corpus that
1182
+ uses a different sentence tokenizer as follows:
1183
+
1184
+ >>> # Find the directory where the corpus lives.
1185
+ >>> genesis_dir = nltk.data.find('corpora/genesis')
1186
+ >>> # Create our custom sentence tokenizer.
1187
+ >>> my_sent_tokenizer = nltk.RegexpTokenizer('[^.!?]+')
1188
+ >>> # Create the new corpus reader object.
1189
+ >>> my_genesis = nltk.corpus.PlaintextCorpusReader(
1190
+ ... genesis_dir, '.*\.txt', sent_tokenizer=my_sent_tokenizer)
1191
+ >>> # Use the new corpus reader object.
1192
+ >>> print(my_genesis.sents('english-kjv.txt')[0]) # doctest: +NORMALIZE_WHITESPACE
1193
+ ['In', 'the', 'beginning', 'God', 'created', 'the', 'heaven',
1194
+ 'and', 'the', 'earth']
1195
+
1196
+ If you wish to read your own plaintext corpus, which is stored in the
1197
+ directory '/usr/share/some-corpus', then you can create a corpus
1198
+ reader for it with::
1199
+
1200
+ >>> my_corpus = nltk.corpus.PlaintextCorpusReader(
1201
+ ... '/usr/share/some-corpus', '.*\.txt') # doctest: +SKIP
1202
+
1203
+ For a complete list of corpus reader subclasses, see the API
1204
+ documentation for `nltk.corpus.reader`.
1205
+
1206
+ Corpus Types
1207
+ ============
1208
+
1209
+ Corpora vary widely in the types of content they include. This is
1210
+ reflected in the fact that the base class `CorpusReader` only defines
1211
+ a few general-purpose methods for listing and accessing the files that
1212
+ make up a corpus. It is up to the subclasses to define *data access
1213
+ methods* that provide access to the information in the corpus.
1214
+ However, corpus reader subclasses should be consistent in their
1215
+ definitions of these data access methods wherever possible.
1216
+
1217
+ At a high level, corpora can be divided into three basic types:
1218
+
1219
+ - A *token corpus* contains information about specific occurences of
1220
+ language use (or linguistic tokens), such as dialogues or written
1221
+ texts. Examples of token corpora are collections of written text
1222
+ and collections of speech.
1223
+
1224
+ - A *type corpus*, or *lexicon*, contains information about a coherent
1225
+ set of lexical items (or linguistic types). Examples of lexicons
1226
+ are dictionaries and word lists.
1227
+
1228
+ - A *language description corpus* contains information about a set of
1229
+ non-lexical linguistic constructs, such as grammar rules.
1230
+
1231
+ However, many individual corpora blur the distinctions between these
1232
+ types. For example, corpora that are primarily lexicons may include
1233
+ token data in the form of example sentences; and corpora that are
1234
+ primarily token corpora may be accompanied by one or more word lists
1235
+ or other lexical data sets.
1236
+
1237
+ Because corpora vary so widely in their information content, we have
1238
+ decided that it would not be wise to use separate corpus reader base
1239
+ classes for different corpus types. Instead, we simply try to make
1240
+ the corpus readers consistent wherever possible, but let them differ
1241
+ where the underlying data itself differs.
1242
+
1243
+ Common Corpus Reader Methods
1244
+ ============================
1245
+
1246
+ As mentioned above, there are only a handful of methods that all
1247
+ corpus readers are guaranteed to implement. These methods provide
1248
+ access to the files that contain the corpus data. Every corpus is
1249
+ assumed to consist of one or more files, all located in a common root
1250
+ directory (or in subdirectories of that root directory). The absolute
1251
+ path to the root directory is stored in the ``root`` property:
1252
+
1253
+ >>> import os
1254
+ >>> str(nltk.corpus.genesis.root).replace(os.path.sep,'/') # doctest: +ELLIPSIS
1255
+ '.../nltk_data/corpora/genesis'
1256
+
1257
+ Each file within the corpus is identified by a platform-independent
1258
+ identifier, which is basically a path string that uses ``/`` as the
1259
+ path separator. I.e., this identifier can be converted to a relative
1260
+ path as follows:
1261
+
1262
+ >>> some_corpus_file_id = nltk.corpus.reuters.fileids()[0]
1263
+ >>> import os.path
1264
+ >>> os.path.normpath(some_corpus_file_id).replace(os.path.sep,'/')
1265
+ 'test/14826'
1266
+
1267
+ To get a list of all data files that make up a corpus, use the
1268
+ ``fileids()`` method. In some corpora, these files will not all contain
1269
+ the same type of data; for example, for the ``nltk.corpus.timit``
1270
+ corpus, ``fileids()`` will return a list including text files, word
1271
+ segmentation files, phonetic transcription files, sound files, and
1272
+ metadata files. For corpora with diverse file types, the ``fileids()``
1273
+ method will often take one or more optional arguments, which can be
1274
+ used to get a list of the files with a specific file type:
1275
+
1276
+ >>> nltk.corpus.timit.fileids() # doctest: +ELLIPSIS
1277
+ ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa1.txt', 'dr1-fvmh0/sa1.wav', ...]
1278
+ >>> nltk.corpus.timit.fileids('phn') # doctest: +ELLIPSIS
1279
+ ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa2.phn', 'dr1-fvmh0/si1466.phn', ...]
1280
+
1281
+ In some corpora, the files are divided into distinct categories. For
1282
+ these corpora, the ``fileids()`` method takes an optional argument,
1283
+ which can be used to get a list of the files within a specific category:
1284
+
1285
+ >>> nltk.corpus.brown.fileids('hobbies') # doctest: +ELLIPSIS
1286
+ ['ce01', 'ce02', 'ce03', 'ce04', 'ce05', 'ce06', 'ce07', ...]
1287
+
1288
+ The ``abspath()`` method can be used to find the absolute path to a
1289
+ corpus file, given its file identifier:
1290
+
1291
+ >>> str(nltk.corpus.brown.abspath('ce06')).replace(os.path.sep,'/') # doctest: +ELLIPSIS
1292
+ '.../corpora/brown/ce06'
1293
+
1294
+ The ``abspaths()`` method can be used to find the absolute paths for
1295
+ one corpus file, a list of corpus files, or (if no fileids are specified),
1296
+ all corpus files.
1297
+
1298
+ This method is mainly useful as a helper method when defining corpus
1299
+ data access methods, since data access methods can usually be called
1300
+ with a string argument (to get a view for a specific file), with a
1301
+ list argument (to get a view for a specific list of files), or with no
1302
+ argument (to get a view for the whole corpus).
1303
+
1304
+ Data Access Methods
1305
+ ===================
1306
+
1307
+ Individual corpus reader subclasses typically extend this basic set of
1308
+ file-access methods with one or more *data access methods*, which provide
1309
+ easy access to the data contained in the corpus. The signatures for
1310
+ data access methods often have the basic form::
1311
+
1312
+ corpus_reader.some_data access(fileids=None, ...options...)
1313
+
1314
+ Where ``fileids`` can be a single file identifier string (to get a view
1315
+ for a specific file); a list of file identifier strings (to get a view
1316
+ for a specific list of files); or None (to get a view for the entire
1317
+ corpus). Some of the common data access methods, and their return
1318
+ types, are:
1319
+
1320
+ - I{corpus}.words(): list of str
1321
+ - I{corpus}.sents(): list of (list of str)
1322
+ - I{corpus}.paras(): list of (list of (list of str))
1323
+ - I{corpus}.tagged_words(): list of (str,str) tuple
1324
+ - I{corpus}.tagged_sents(): list of (list of (str,str))
1325
+ - I{corpus}.tagged_paras(): list of (list of (list of (str,str)))
1326
+ - I{corpus}.chunked_sents(): list of (Tree w/ (str,str) leaves)
1327
+ - I{corpus}.parsed_sents(): list of (Tree with str leaves)
1328
+ - I{corpus}.parsed_paras(): list of (list of (Tree with str leaves))
1329
+ - I{corpus}.xml(): A single xml ElementTree
1330
+ - I{corpus}.raw(): str (unprocessed corpus contents)
1331
+
1332
+ For example, the `words()` method is supported by many different
1333
+ corpora, and returns a flat list of word strings:
1334
+
1335
+ >>> nltk.corpus.brown.words()
1336
+ ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
1337
+ >>> nltk.corpus.treebank.words()
1338
+ ['Pierre', 'Vinken', ',', '61', 'years', 'old', ...]
1339
+ >>> nltk.corpus.conll2002.words()
1340
+ [u'Sao', u'Paulo', u'(', u'Brasil', u')', u',', u'23', ...]
1341
+ >>> nltk.corpus.genesis.words()
1342
+ [u'In', u'the', u'beginning', u'God', u'created', ...]
1343
+
1344
+ On the other hand, the `tagged_words()` method is only supported by
1345
+ corpora that include part-of-speech annotations:
1346
+
1347
+ >>> nltk.corpus.brown.tagged_words()
1348
+ [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
1349
+ >>> nltk.corpus.treebank.tagged_words()
1350
+ [('Pierre', 'NNP'), ('Vinken', 'NNP'), ...]
1351
+ >>> nltk.corpus.conll2002.tagged_words()
1352
+ [(u'Sao', u'NC'), (u'Paulo', u'VMI'), (u'(', u'Fpa'), ...]
1353
+ >>> nltk.corpus.genesis.tagged_words()
1354
+ Traceback (most recent call last):
1355
+ ...
1356
+ AttributeError: 'PlaintextCorpusReader' object has no attribute 'tagged_words'
1357
+
1358
+ Although most corpus readers use file identifiers to index their
1359
+ content, some corpora use different identifiers instead. For example,
1360
+ the data access methods for the ``timit`` corpus uses *utterance
1361
+ identifiers* to select which corpus items should be returned:
1362
+
1363
+ >>> nltk.corpus.timit.utteranceids() # doctest: +ELLIPSIS
1364
+ ['dr1-fvmh0/sa1', 'dr1-fvmh0/sa2', 'dr1-fvmh0/si1466', ...]
1365
+ >>> nltk.corpus.timit.words('dr1-fvmh0/sa2')
1366
+ ["don't", 'ask', 'me', 'to', 'carry', 'an', 'oily', 'rag', 'like', 'that']
1367
+
1368
+ Attempting to call ``timit``\ 's data access methods with a file
1369
+ identifier will result in an exception:
1370
+
1371
+ >>> nltk.corpus.timit.fileids() # doctest: +ELLIPSIS
1372
+ ['dr1-fvmh0/sa1.phn', 'dr1-fvmh0/sa1.txt', 'dr1-fvmh0/sa1.wav', ...]
1373
+ >>> nltk.corpus.timit.words('dr1-fvmh0/sa1.txt') # doctest: +SKIP
1374
+ Traceback (most recent call last):
1375
+ ...
1376
+ IOError: No such file or directory: '.../dr1-fvmh0/sa1.txt.wrd'
1377
+
1378
+ As another example, the ``propbank`` corpus defines the ``roleset()``
1379
+ method, which expects a roleset identifier, not a file identifier:
1380
+
1381
+ >>> roleset = nltk.corpus.propbank.roleset('eat.01')
1382
+ >>> from xml.etree import ElementTree as ET
1383
+ >>> print(ET.tostring(roleset).decode('utf8')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1384
+ <roleset id="eat.01" name="consume" vncls="39.1">
1385
+ <roles>
1386
+ <role descr="consumer, eater" n="0">...</role>...
1387
+ </roles>...
1388
+ </roleset>...
1389
+
1390
+ Stream Backed Corpus Views
1391
+ ==========================
1392
+ An important feature of NLTK's corpus readers is that many of them
1393
+ access the underlying data files using "corpus views." A *corpus
1394
+ view* is an object that acts like a simple data structure (such as a
1395
+ list), but does not store the data elements in memory; instead, data
1396
+ elements are read from the underlying data files on an as-needed
1397
+ basis.
1398
+
1399
+ By only loading items from the file on an as-needed basis, corpus
1400
+ views maintain both memory efficiency and responsiveness. The memory
1401
+ efficiency of corpus readers is important because some corpora contain
1402
+ very large amounts of data, and storing the entire data set in memory
1403
+ could overwhelm many machines. The responsiveness is important when
1404
+ experimenting with corpora in interactive sessions and in in-class
1405
+ demonstrations.
1406
+
1407
+ The most common corpus view is the `StreamBackedCorpusView`, which
1408
+ acts as a read-only list of tokens. Two additional corpus view
1409
+ classes, `ConcatenatedCorpusView` and `LazySubsequence`, make it
1410
+ possible to create concatenations and take slices of
1411
+ `StreamBackedCorpusView` objects without actually storing the
1412
+ resulting list-like object's elements in memory.
1413
+
1414
+ In the future, we may add additional corpus views that act like other
1415
+ basic data structures, such as dictionaries.
1416
+
1417
+ Writing New Corpus Readers
1418
+ ==========================
1419
+
1420
+ In order to add support for new corpus formats, it is necessary to
1421
+ define new corpus reader classes. For many corpus formats, writing
1422
+ new corpus readers is relatively straight-forward. In this section,
1423
+ we'll describe what's involved in creating a new corpus reader. If
1424
+ you do create a new corpus reader, we encourage you to contribute it
1425
+ back to the NLTK project.
1426
+
1427
+ Don't Reinvent the Wheel
1428
+ ------------------------
1429
+ Before you start writing a new corpus reader, you should check to be
1430
+ sure that the desired format can't be read using an existing corpus
1431
+ reader with appropriate constructor arguments. For example, although
1432
+ the `TaggedCorpusReader` assumes that words and tags are separated by
1433
+ ``/`` characters by default, an alternative tag-separation character
1434
+ can be specified via the ``sep`` constructor argument. You should
1435
+ also check whether the new corpus format can be handled by subclassing
1436
+ an existing corpus reader, and tweaking a few methods or variables.
1437
+
1438
+ Design
1439
+ ------
1440
+ If you decide to write a new corpus reader from scratch, then you
1441
+ should first decide which data access methods you want the reader to
1442
+ provide, and what their signatures should be. You should look at
1443
+ existing corpus readers that process corpora with similar data
1444
+ contents, and try to be consistent with those corpus readers whenever
1445
+ possible.
1446
+
1447
+ You should also consider what sets of identifiers are appropriate for
1448
+ the corpus format. Where it's practical, file identifiers should be
1449
+ used. However, for some corpora, it may make sense to use additional
1450
+ sets of identifiers. Each set of identifiers should have a distinct
1451
+ name (e.g., fileids, utteranceids, rolesets); and you should be consistent
1452
+ in using that name to refer to that identifier. Do not use parameter
1453
+ names like ``id``, which leave it unclear what type of identifier is
1454
+ required.
1455
+
1456
+ Once you've decided what data access methods and identifiers are
1457
+ appropriate for your corpus, you should decide if there are any
1458
+ customizable parameters that you'd like the corpus reader to handle.
1459
+ These parameters make it possible to use a single corpus reader to
1460
+ handle a wider variety of corpora. The ``sep`` argument for
1461
+ `TaggedCorpusReader`, mentioned above, is an example of a customizable
1462
+ corpus reader parameter.
1463
+
1464
+ Implementation
1465
+ --------------
1466
+
1467
+ Constructor
1468
+ ~~~~~~~~~~~
1469
+ If your corpus reader implements any customizable parameters, then
1470
+ you'll need to override the constructor. Typically, the new
1471
+ constructor will first call its base class's constructor, and then
1472
+ store the customizable parameters. For example, the
1473
+ `ConllChunkCorpusReader`\ 's constructor is defined as follows:
1474
+
1475
+ def __init__(self, root, fileids, chunk_types, encoding='utf8',
1476
+ tagset=None, separator=None):
1477
+ ConllCorpusReader.__init__(
1478
+ self, root, fileids, ('words', 'pos', 'chunk'),
1479
+ chunk_types=chunk_types, encoding=encoding,
1480
+ tagset=tagset, separator=separator)
1481
+
1482
+ If your corpus reader does not implement any customization parameters,
1483
+ then you can often just inherit the base class's constructor.
1484
+
1485
+ Data Access Methods
1486
+ ~~~~~~~~~~~~~~~~~~~
1487
+
1488
+ The most common type of data access method takes an argument
1489
+ identifying which files to access, and returns a view covering those
1490
+ files. This argument may be a single file identifier string (to get a
1491
+ view for a specific file); a list of file identifier strings (to get a
1492
+ view for a specific list of files); or None (to get a view for the
1493
+ entire corpus). The method's implementation converts this argument to
1494
+ a list of path names using the `abspaths()` method, which handles all
1495
+ three value types (string, list, and None):
1496
+
1497
+ >>> print(str(nltk.corpus.brown.abspaths()).replace('\\\\','/')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1498
+ [FileSystemPathPointer('.../corpora/brown/ca01'),
1499
+ FileSystemPathPointer('.../corpora/brown/ca02'), ...]
1500
+ >>> print(str(nltk.corpus.brown.abspaths('ce06')).replace('\\\\','/')) # doctest: +ELLIPSIS
1501
+ [FileSystemPathPointer('.../corpora/brown/ce06')]
1502
+ >>> print(str(nltk.corpus.brown.abspaths(['ce06', 'ce07'])).replace('\\\\','/')) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1503
+ [FileSystemPathPointer('.../corpora/brown/ce06'),
1504
+ FileSystemPathPointer('.../corpora/brown/ce07')]
1505
+
1506
+ An example of this type of method is the `words()` method, defined by
1507
+ the `PlaintextCorpusReader` as follows:
1508
+
1509
+ >>> def words(self, fileids=None):
1510
+ ... return concat([self.CorpusView(fileid, self._read_word_block)
1511
+ ... for fileid in self.abspaths(fileids)])
1512
+
1513
+ This method first uses `abspaths()` to convert ``fileids`` to a list of
1514
+ absolute paths. It then creates a corpus view for each file, using
1515
+ the `PlaintextCorpusReader._read_word_block()` method to read elements
1516
+ from the data file (see the discussion of corpus views below).
1517
+ Finally, it combines these corpus views using the
1518
+ `nltk.corpus.reader.util.concat()` function.
1519
+
1520
+ When writing a corpus reader for a corpus that is never expected to be
1521
+ very large, it can sometimes be appropriate to read the files
1522
+ directly, rather than using a corpus view. For example, the
1523
+ `WordListCorpusView` class defines its `words()` method as follows:
1524
+
1525
+ >>> def words(self, fileids=None):
1526
+ ... return concat([[w for w in open(fileid).read().split('\n') if w]
1527
+ ... for fileid in self.abspaths(fileids)])
1528
+
1529
+ (This is usually more appropriate for lexicons than for token corpora.)
1530
+
1531
+ If the type of data returned by a data access method is one for which
1532
+ NLTK has a conventional representation (e.g., words, tagged words, and
1533
+ parse trees), then you should use that representation. Otherwise, you
1534
+ may find it necessary to define your own representation. For data
1535
+ structures that are relatively corpus-specific, it's usually best to
1536
+ define new classes for these elements. For example, the ``propbank``
1537
+ corpus defines the `PropbankInstance` class to store the semantic role
1538
+ labeling instances described by the corpus; and the ``ppattach``
1539
+ corpus defines the `PPAttachment` class to store the prepositional
1540
+ attachment instances described by the corpus.
1541
+
1542
+ Corpus Views
1543
+ ~~~~~~~~~~~~
1544
+ .. (Much of the content for this section is taken from the
1545
+ StreamBackedCorpusView docstring.)
1546
+
1547
+ The heart of a `StreamBackedCorpusView` is its *block reader*
1548
+ function, which reads zero or more tokens from a stream, and returns
1549
+ them as a list. A very simple example of a block reader is:
1550
+
1551
+ >>> def simple_block_reader(stream):
1552
+ ... return stream.readline().split()
1553
+
1554
+ This simple block reader reads a single line at a time, and returns a
1555
+ single token (consisting of a string) for each whitespace-separated
1556
+ substring on the line. A `StreamBackedCorpusView` built from this
1557
+ block reader will act like a read-only list of all the
1558
+ whitespace-separated tokens in an underlying file.
1559
+
1560
+ When deciding how to define the block reader for a given corpus,
1561
+ careful consideration should be given to the size of blocks handled by
1562
+ the block reader. Smaller block sizes will increase the memory
1563
+ requirements of the corpus view's internal data structures (by 2
1564
+ integers per block). On the other hand, larger block sizes may
1565
+ decrease performance for random access to the corpus. (But note that
1566
+ larger block sizes will *not* decrease performance for iteration.)
1567
+
1568
+ Internally, the `StreamBackedCorpusView` class maintains a partial
1569
+ mapping from token index to file position, with one entry per block.
1570
+ When a token with a given index *i* is requested, the corpus view
1571
+ constructs it as follows:
1572
+
1573
+ 1. First, it searches the toknum/filepos mapping for the token index
1574
+ closest to (but less than or equal to) *i*.
1575
+
1576
+ 2. Then, starting at the file position corresponding to that index, it
1577
+ reads one block at a time using the block reader until it reaches
1578
+ the requested token.
1579
+
1580
+ The toknum/filepos mapping is created lazily: it is initially empty,
1581
+ but every time a new block is read, the block's initial token is added
1582
+ to the mapping. (Thus, the toknum/filepos map has one entry per
1583
+ block.)
1584
+
1585
+ You can create your own corpus view in one of two ways:
1586
+
1587
+ 1. Call the `StreamBackedCorpusView` constructor, and provide your
1588
+ block reader function via the ``block_reader`` argument.
1589
+
1590
+ 2. Subclass `StreamBackedCorpusView`, and override the
1591
+ `read_block()` method.
1592
+
1593
+ The first option is usually easier, but the second option can allow
1594
+ you to write a single `read_block` method whose behavior can be
1595
+ customized by different parameters to the subclass's constructor. For
1596
+ an example of this design pattern, see the `TaggedCorpusView` class,
1597
+ which is used by `TaggedCorpusView`.
1598
+
1599
+ ----------------
1600
+ Regression Tests
1601
+ ----------------
1602
+
1603
+ The following helper functions are used to create and then delete
1604
+ testing corpora that are stored in temporary directories. These
1605
+ testing corpora are used to make sure the readers work correctly.
1606
+
1607
+ >>> import tempfile, os.path, textwrap
1608
+ >>> def make_testcorpus(ext='', **fileids):
1609
+ ... root = tempfile.mkdtemp()
1610
+ ... for fileid, contents in fileids.items():
1611
+ ... fileid += ext
1612
+ ... f = open(os.path.join(root, fileid), 'w')
1613
+ ... f.write(textwrap.dedent(contents))
1614
+ ... f.close()
1615
+ ... return root
1616
+ >>> def del_testcorpus(root):
1617
+ ... for fileid in os.listdir(root):
1618
+ ... os.remove(os.path.join(root, fileid))
1619
+ ... os.rmdir(root)
1620
+
1621
+ Plaintext Corpus Reader
1622
+ =======================
1623
+ The plaintext corpus reader is used to access corpora that consist of
1624
+ unprocessed plaintext data. It assumes that paragraph breaks are
1625
+ indicated by blank lines. Sentences and words can be tokenized using
1626
+ the default tokenizers, or by custom tokenizers specified as
1627
+ parameters to the constructor.
1628
+
1629
+ >>> root = make_testcorpus(ext='.txt',
1630
+ ... a="""\
1631
+ ... This is the first sentence. Here is another
1632
+ ... sentence! And here's a third sentence.
1633
+ ...
1634
+ ... This is the second paragraph. Tokenization is currently
1635
+ ... fairly simple, so the period in Mr. gets tokenized.
1636
+ ... """,
1637
+ ... b="""This is the second file.""")
1638
+
1639
+ >>> from nltk.corpus.reader.plaintext import PlaintextCorpusReader
1640
+
1641
+ The list of documents can be specified explicitly, or implicitly (using a
1642
+ regexp). The ``ext`` argument specifies a file extension.
1643
+
1644
+ >>> corpus = PlaintextCorpusReader(root, ['a.txt', 'b.txt'])
1645
+ >>> corpus.fileids()
1646
+ ['a.txt', 'b.txt']
1647
+ >>> corpus = PlaintextCorpusReader(root, '.*\.txt')
1648
+ >>> corpus.fileids()
1649
+ ['a.txt', 'b.txt']
1650
+
1651
+ The directory containing the corpus is corpus.root:
1652
+
1653
+ >>> str(corpus.root) == str(root)
1654
+ True
1655
+
1656
+ We can get a list of words, or the raw string:
1657
+
1658
+ >>> corpus.words()
1659
+ ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1660
+ >>> corpus.raw()[:40]
1661
+ 'This is the first sentence. Here is ano'
1662
+
1663
+ Check that reading individual documents works, and reading all documents at
1664
+ once works:
1665
+
1666
+ >>> len(corpus.words()), [len(corpus.words(d)) for d in corpus.fileids()]
1667
+ (46, [40, 6])
1668
+ >>> corpus.words('a.txt')
1669
+ ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1670
+ >>> corpus.words('b.txt')
1671
+ ['This', 'is', 'the', 'second', 'file', '.']
1672
+ >>> corpus.words()[:4], corpus.words()[-4:]
1673
+ (['This', 'is', 'the', 'first'], ['the', 'second', 'file', '.'])
1674
+
1675
+ We're done with the test corpus:
1676
+
1677
+ >>> del_testcorpus(root)
1678
+
1679
+ Test the plaintext corpora that come with nltk:
1680
+
1681
+ >>> from nltk.corpus import abc, genesis, inaugural
1682
+ >>> from nltk.corpus import state_union, webtext
1683
+ >>> for corpus in (abc, genesis, inaugural, state_union,
1684
+ ... webtext):
1685
+ ... print(str(corpus).replace('\\\\','/'))
1686
+ ... print(' ', repr(corpus.fileids())[:60])
1687
+ ... print(' ', repr(corpus.words()[:10])[:60])
1688
+ <PlaintextCorpusReader in '.../nltk_data/corpora/ab...'>
1689
+ ['rural.txt', 'science.txt']
1690
+ ['PM', 'denies', 'knowledge', 'of', 'AWB', ...
1691
+ <PlaintextCorpusReader in '.../nltk_data/corpora/genesi...'>
1692
+ ['english-kjv.txt', 'english-web.txt', 'finnish.txt', ...
1693
+ ['In', 'the', 'beginning', 'God', 'created', 'the', ...
1694
+ <PlaintextCorpusReader in '.../nltk_data/corpora/inaugura...'>
1695
+ ['1789-Washington.txt', '1793-Washington.txt', ...
1696
+ ['Fellow', '-', 'Citizens', 'of', 'the', 'Senate', ...
1697
+ <PlaintextCorpusReader in '.../nltk_data/corpora/state_unio...'>
1698
+ ['1945-Truman.txt', '1946-Truman.txt', ...
1699
+ ['PRESIDENT', 'HARRY', 'S', '.', 'TRUMAN', "'", ...
1700
+ <PlaintextCorpusReader in '.../nltk_data/corpora/webtex...'>
1701
+ ['firefox.txt', 'grail.txt', 'overheard.txt', ...
1702
+ ['Cookie', 'Manager', ':', '"', 'Don', "'", 't', ...
1703
+
1704
+
1705
+ Tagged Corpus Reader
1706
+ ====================
1707
+ The Tagged Corpus reader can give us words, sentences, and paragraphs,
1708
+ each tagged or untagged. All of the read methods can take one item
1709
+ (in which case they return the contents of that file) or a list of
1710
+ documents (in which case they concatenate the contents of those files).
1711
+ By default, they apply to all documents in the corpus.
1712
+
1713
+ >>> root = make_testcorpus(
1714
+ ... a="""\
1715
+ ... This/det is/verb the/det first/adj sentence/noun ./punc
1716
+ ... Here/det is/verb another/adj sentence/noun ./punc
1717
+ ... Note/verb that/comp you/pron can/verb use/verb \
1718
+ ... any/noun tag/noun set/noun
1719
+ ...
1720
+ ... This/det is/verb the/det second/adj paragraph/noun ./punc
1721
+ ... word/n without/adj a/det tag/noun :/: hello ./punc
1722
+ ... """,
1723
+ ... b="""\
1724
+ ... This/det is/verb the/det second/adj file/noun ./punc
1725
+ ... """)
1726
+
1727
+ >>> from nltk.corpus.reader.tagged import TaggedCorpusReader
1728
+ >>> corpus = TaggedCorpusReader(root, list('ab'))
1729
+ >>> corpus.fileids()
1730
+ ['a', 'b']
1731
+ >>> str(corpus.root) == str(root)
1732
+ True
1733
+ >>> corpus.words()
1734
+ ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1735
+ >>> corpus.sents() # doctest: +ELLIPSIS
1736
+ [['This', 'is', 'the', 'first', ...], ['Here', 'is', 'another'...], ...]
1737
+ >>> corpus.paras() # doctest: +ELLIPSIS
1738
+ [[['This', ...], ['Here', ...], ...], [['This', ...], ...], ...]
1739
+ >>> corpus.tagged_words() # doctest: +ELLIPSIS
1740
+ [('This', 'DET'), ('is', 'VERB'), ('the', 'DET'), ...]
1741
+ >>> corpus.tagged_sents() # doctest: +ELLIPSIS
1742
+ [[('This', 'DET'), ('is', 'VERB'), ...], [('Here', 'DET'), ...], ...]
1743
+ >>> corpus.tagged_paras() # doctest: +ELLIPSIS
1744
+ [[[('This', 'DET'), ...], ...], [[('This', 'DET'), ...], ...], ...]
1745
+ >>> corpus.raw()[:40]
1746
+ 'This/det is/verb the/det first/adj sente'
1747
+ >>> len(corpus.words()), [len(corpus.words(d)) for d in corpus.fileids()]
1748
+ (38, [32, 6])
1749
+ >>> len(corpus.sents()), [len(corpus.sents(d)) for d in corpus.fileids()]
1750
+ (6, [5, 1])
1751
+ >>> len(corpus.paras()), [len(corpus.paras(d)) for d in corpus.fileids()]
1752
+ (3, [2, 1])
1753
+ >>> print(corpus.words('a'))
1754
+ ['This', 'is', 'the', 'first', 'sentence', '.', ...]
1755
+ >>> print(corpus.words('b'))
1756
+ ['This', 'is', 'the', 'second', 'file', '.']
1757
+ >>> del_testcorpus(root)
1758
+
1759
+ The Brown Corpus uses the tagged corpus reader:
1760
+
1761
+ >>> from nltk.corpus import brown
1762
+ >>> brown.fileids() # doctest: +ELLIPSIS
1763
+ ['ca01', 'ca02', 'ca03', 'ca04', 'ca05', 'ca06', 'ca07', ...]
1764
+ >>> brown.categories() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
1765
+ ['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor',
1766
+ 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']
1767
+ >>> print(repr(brown.root).replace('\\\\','/')) # doctest: +ELLIPSIS
1768
+ FileSystemPathPointer('.../corpora/brown')
1769
+ >>> brown.words()
1770
+ ['The', 'Fulton', 'County', 'Grand', 'Jury', ...]
1771
+ >>> brown.sents() # doctest: +ELLIPSIS
1772
+ [['The', 'Fulton', 'County', 'Grand', ...], ...]
1773
+ >>> brown.paras() # doctest: +ELLIPSIS
1774
+ [[['The', 'Fulton', 'County', ...]], [['The', 'jury', ...]], ...]
1775
+ >>> brown.tagged_words() # doctest: +ELLIPSIS
1776
+ [('The', 'AT'), ('Fulton', 'NP-TL'), ...]
1777
+ >>> brown.tagged_sents() # doctest: +ELLIPSIS
1778
+ [[('The', 'AT'), ('Fulton', 'NP-TL'), ('County', 'NN-TL'), ...], ...]
1779
+ >>> brown.tagged_paras() # doctest: +ELLIPSIS
1780
+ [[[('The', 'AT'), ...]], [[('The', 'AT'), ...]], ...]
1781
+
1782
+ Verbnet Corpus Reader
1783
+ =====================
1784
+
1785
+ Make sure we're picking up the right number of elements:
1786
+
1787
+ >>> from nltk.corpus import verbnet
1788
+ >>> len(verbnet.lemmas())
1789
+ 3621
1790
+ >>> len(verbnet.wordnetids())
1791
+ 4953
1792
+ >>> len(verbnet.classids())
1793
+ 429
1794
+
1795
+ Selecting classids based on various selectors:
1796
+
1797
+ >>> verbnet.classids(lemma='take') # doctest: +NORMALIZE_WHITESPACE
1798
+ ['bring-11.3', 'characterize-29.2', 'convert-26.6.2', 'cost-54.2',
1799
+ 'fit-54.3', 'performance-26.7-2', 'steal-10.5']
1800
+ >>> verbnet.classids(wordnetid='lead%2:38:01')
1801
+ ['accompany-51.7']
1802
+ >>> verbnet.classids(fileid='approve-77.xml')
1803
+ ['approve-77']
1804
+ >>> verbnet.classids(classid='admire-31.2') # subclasses
1805
+ ['admire-31.2-1']
1806
+
1807
+ vnclass() accepts filenames, long ids, and short ids:
1808
+
1809
+ >>> a = ElementTree.tostring(verbnet.vnclass('admire-31.2.xml'))
1810
+ >>> b = ElementTree.tostring(verbnet.vnclass('admire-31.2'))
1811
+ >>> c = ElementTree.tostring(verbnet.vnclass('31.2'))
1812
+ >>> a == b == c
1813
+ True
1814
+
1815
+ fileids() can be used to get files based on verbnet class ids:
1816
+
1817
+ >>> verbnet.fileids('admire-31.2')
1818
+ ['admire-31.2.xml']
1819
+ >>> verbnet.fileids(['admire-31.2', 'obtain-13.5.2'])
1820
+ ['admire-31.2.xml', 'obtain-13.5.2.xml']
1821
+ >>> verbnet.fileids('badidentifier')
1822
+ Traceback (most recent call last):
1823
+ . . .
1824
+ ValueError: vnclass identifier 'badidentifier' not found
1825
+
1826
+ longid() and shortid() can be used to convert identifiers:
1827
+
1828
+ >>> verbnet.longid('31.2')
1829
+ 'admire-31.2'
1830
+ >>> verbnet.longid('admire-31.2')
1831
+ 'admire-31.2'
1832
+ >>> verbnet.shortid('31.2')
1833
+ '31.2'
1834
+ >>> verbnet.shortid('admire-31.2')
1835
+ '31.2'
1836
+ >>> verbnet.longid('badidentifier')
1837
+ Traceback (most recent call last):
1838
+ . . .
1839
+ ValueError: vnclass identifier 'badidentifier' not found
1840
+ >>> verbnet.shortid('badidentifier')
1841
+ Traceback (most recent call last):
1842
+ . . .
1843
+ ValueError: vnclass identifier 'badidentifier' not found
1844
+
1845
+ Corpus View Regression Tests
1846
+ ============================
1847
+
1848
+ Select some corpus files to play with:
1849
+
1850
+ >>> import nltk.data
1851
+ >>> # A very short file (160 chars):
1852
+ >>> f1 = nltk.data.find('corpora/inaugural/README')
1853
+ >>> # A relatively short file (791 chars):
1854
+ >>> f2 = nltk.data.find('corpora/inaugural/1793-Washington.txt')
1855
+ >>> # A longer file (32k chars):
1856
+ >>> f3 = nltk.data.find('corpora/inaugural/1909-Taft.txt')
1857
+ >>> fileids = [f1, f2, f3]
1858
+
1859
+
1860
+ Concatenation
1861
+ -------------
1862
+ Check that concatenation works as intended.
1863
+
1864
+ >>> from nltk.corpus.reader.util import *
1865
+
1866
+ >>> c1 = StreamBackedCorpusView(f1, read_whitespace_block, encoding='utf-8')
1867
+ >>> c2 = StreamBackedCorpusView(f2, read_whitespace_block, encoding='utf-8')
1868
+ >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block, encoding='utf-8')
1869
+ >>> c123 = c1+c2+c3
1870
+ >>> print(c123)
1871
+ ['C-Span', 'Inaugural', 'Address', 'Corpus', 'US', ...]
1872
+
1873
+ >>> l1 = f1.open(encoding='utf-8').read().split()
1874
+ >>> l2 = f2.open(encoding='utf-8').read().split()
1875
+ >>> l3 = f3.open(encoding='utf-8').read().split()
1876
+ >>> l123 = l1+l2+l3
1877
+
1878
+ >>> list(c123) == l123
1879
+ True
1880
+
1881
+ >>> (c1+c2+c3)[100] == l123[100]
1882
+ True
1883
+
1884
+ Slicing
1885
+ -------
1886
+ First, do some tests with fairly small slices. These will all
1887
+ generate tuple values.
1888
+
1889
+ >>> from nltk.util import LazySubsequence
1890
+ >>> c1 = StreamBackedCorpusView(f1, read_whitespace_block, encoding='utf-8')
1891
+ >>> l1 = f1.open(encoding='utf-8').read().split()
1892
+ >>> print(len(c1))
1893
+ 21
1894
+ >>> len(c1) < LazySubsequence.MIN_SIZE
1895
+ True
1896
+
1897
+ Choose a list of indices, based on the length, that covers the
1898
+ important corner cases:
1899
+
1900
+ >>> indices = [-60, -30, -22, -21, -20, -1,
1901
+ ... 0, 1, 10, 20, 21, 22, 30, 60]
1902
+
1903
+ Test slicing with explicit start & stop value:
1904
+
1905
+ >>> for s in indices:
1906
+ ... for e in indices:
1907
+ ... assert list(c1[s:e]) == l1[s:e]
1908
+
1909
+ Test slicing with stop=None:
1910
+
1911
+ >>> for s in indices:
1912
+ ... assert list(c1[s:]) == l1[s:]
1913
+
1914
+ Test slicing with start=None:
1915
+
1916
+ >>> for e in indices:
1917
+ ... assert list(c1[:e]) == l1[:e]
1918
+
1919
+ Test slicing with start=stop=None:
1920
+
1921
+ >>> list(c1[:]) == list(l1[:])
1922
+ True
1923
+
1924
+ Next, we'll do some tests with much longer slices. These will
1925
+ generate LazySubsequence objects.
1926
+
1927
+ >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block, encoding='utf-8')
1928
+ >>> l3 = f3.open(encoding='utf-8').read().split()
1929
+ >>> print(len(c3))
1930
+ 5430
1931
+ >>> len(c3) > LazySubsequence.MIN_SIZE*2
1932
+ True
1933
+
1934
+ Choose a list of indices, based on the length, that covers the
1935
+ important corner cases:
1936
+
1937
+ >>> indices = [-12000, -6000, -5431, -5430, -5429, -3000, -200, -1,
1938
+ ... 0, 1, 200, 3000, 5000, 5429, 5430, 5431, 6000, 12000]
1939
+
1940
+ Test slicing with explicit start & stop value:
1941
+
1942
+ >>> for s in indices:
1943
+ ... for e in indices:
1944
+ ... assert list(c3[s:e]) == l3[s:e]
1945
+
1946
+ Test slicing with stop=None:
1947
+
1948
+ >>> for s in indices:
1949
+ ... assert list(c3[s:]) == l3[s:]
1950
+
1951
+ Test slicing with start=None:
1952
+
1953
+ >>> for e in indices:
1954
+ ... assert list(c3[:e]) == l3[:e]
1955
+
1956
+ Test slicing with start=stop=None:
1957
+
1958
+ >>> list(c3[:]) == list(l3[:])
1959
+ True
1960
+
1961
+ Multiple Iterators
1962
+ ------------------
1963
+ If multiple iterators are created for the same corpus view, their
1964
+ iteration can be interleaved:
1965
+
1966
+ >>> c3 = StreamBackedCorpusView(f3, read_whitespace_block)
1967
+ >>> iterators = [c3.iterate_from(n) for n in [0,15,30,45]]
1968
+ >>> for i in range(15):
1969
+ ... for iterator in iterators:
1970
+ ... print('%-15s' % next(iterator), end=' ')
1971
+ ... print()
1972
+ My a duties in
1973
+ fellow heavy of a
1974
+ citizens: weight the proper
1975
+ Anyone of office sense
1976
+ who responsibility. upon of
1977
+ has If which the
1978
+ taken not, he obligation
1979
+ the he is which
1980
+ oath has about the
1981
+ I no to oath
1982
+ have conception enter, imposes.
1983
+ just of or The
1984
+ taken the he office
1985
+ must powers is of
1986
+ feel and lacking an
1987
+
1988
+ SeekableUnicodeStreamReader
1989
+ ===========================
1990
+
1991
+ The file-like objects provided by the ``codecs`` module unfortunately
1992
+ suffer from a bug that prevents them from working correctly with
1993
+ corpus view objects. In particular, although the expose ``seek()``
1994
+ and ``tell()`` methods, those methods do not exhibit the expected
1995
+ behavior, because they are not synchronized with the internal buffers
1996
+ that are kept by the file-like objects. For example, the ``tell()``
1997
+ method will return the file position at the end of the buffers (whose
1998
+ contents have not yet been returned by the stream); and therefore this
1999
+ file position can not be used to return to the 'current' location in
2000
+ the stream (since ``seek()`` has no way to reconstruct the buffers).
2001
+
2002
+ To get around these problems, we define a new class,
2003
+ `SeekableUnicodeStreamReader`, to act as a file-like interface to
2004
+ files containing encoded unicode data. This class is loosely based on
2005
+ the ``codecs.StreamReader`` class. To construct a new reader, we call
2006
+ the constructor with an underlying stream and an encoding name:
2007
+
2008
+ >>> from io import StringIO, BytesIO
2009
+ >>> from nltk.data import SeekableUnicodeStreamReader
2010
+ >>> stream = BytesIO(b"""\
2011
+ ... This is a test file.
2012
+ ... It is encoded in ascii.
2013
+ ... """.decode('ascii').encode('ascii'))
2014
+ >>> reader = SeekableUnicodeStreamReader(stream, 'ascii')
2015
+
2016
+ `SeekableUnicodeStreamReader`\ s support all of the normal operations
2017
+ supplied by a read-only stream. Note that all of the read operations
2018
+ return ``unicode`` objects (not ``str`` objects).
2019
+
2020
+ >>> reader.read() # read the entire file.
2021
+ u'This is a test file.\nIt is encoded in ascii.\n'
2022
+ >>> reader.seek(0) # rewind to the start.
2023
+ >>> reader.read(5) # read at most 5 bytes.
2024
+ u'This '
2025
+ >>> reader.readline() # read to the end of the line.
2026
+ u'is a test file.\n'
2027
+ >>> reader.seek(0) # rewind to the start.
2028
+ >>> for line in reader:
2029
+ ... print(repr(line)) # iterate over lines
2030
+ u'This is a test file.\n'
2031
+ u'It is encoded in ascii.\n'
2032
+ >>> reader.seek(0) # rewind to the start.
2033
+ >>> reader.readlines() # read a list of line strings
2034
+ [u'This is a test file.\n', u'It is encoded in ascii.\n']
2035
+ >>> reader.close()
2036
+
2037
+ Size argument to ``read()``
2038
+ ---------------------------
2039
+ The ``size`` argument to ``read()`` specifies the maximum number of
2040
+ *bytes* to read, not the maximum number of *characters*. Thus, for
2041
+ encodings that use multiple bytes per character, it may return fewer
2042
+ characters than the ``size`` argument:
2043
+
2044
+ >>> stream = BytesIO(b"""\
2045
+ ... This is a test file.
2046
+ ... It is encoded in utf-16.
2047
+ ... """.decode('ascii').encode('utf-16'))
2048
+ >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2049
+ >>> reader.read(10)
2050
+ u'This '
2051
+
2052
+ If a read block ends in the middle of the byte string encoding a
2053
+ single character, then that byte string is stored in an internal
2054
+ buffer, and re-used on the next call to ``read()``. However, if the
2055
+ size argument is too small to read even a single character, even
2056
+ though at least one character is available, then the ``read()`` method
2057
+ will read additional bytes until it can return a single character.
2058
+ This ensures that the ``read()`` method does not return an empty
2059
+ string, which could be mistaken for indicating the end of the file.
2060
+
2061
+ >>> reader.seek(0) # rewind to the start.
2062
+ >>> reader.read(1) # we actually need to read 4 bytes
2063
+ u'T'
2064
+ >>> int(reader.tell())
2065
+ 4
2066
+
2067
+ The ``readline()`` method may read more than a single line of text, in
2068
+ which case it stores the text that it does not return in a buffer. If
2069
+ this buffer is not empty, then its contents will be included in the
2070
+ value returned by the next call to ``read()``, regardless of the
2071
+ ``size`` argument, since they are available without reading any new
2072
+ bytes from the stream:
2073
+
2074
+ >>> reader.seek(0) # rewind to the start.
2075
+ >>> reader.readline() # stores extra text in a buffer
2076
+ u'This is a test file.\n'
2077
+ >>> print(reader.linebuffer) # examine the buffer contents
2078
+ [u'It is encoded i']
2079
+ >>> reader.read(0) # returns the contents of the buffer
2080
+ u'It is encoded i'
2081
+ >>> print(reader.linebuffer) # examine the buffer contents
2082
+ None
2083
+
2084
+ Seek and Tell
2085
+ -------------
2086
+ In addition to these basic read operations,
2087
+ `SeekableUnicodeStreamReader` also supports the ``seek()`` and
2088
+ ``tell()`` operations. However, some care must still be taken when
2089
+ using these operations. In particular, the only file offsets that
2090
+ should be passed to ``seek()`` are ``0`` and any offset that has been
2091
+ returned by ``tell``.
2092
+
2093
+ >>> stream = BytesIO(b"""\
2094
+ ... This is a test file.
2095
+ ... It is encoded in utf-16.
2096
+ ... """.decode('ascii').encode('utf-16'))
2097
+ >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2098
+ >>> reader.read(20)
2099
+ u'This is a '
2100
+ >>> pos = reader.tell(); print(pos)
2101
+ 22
2102
+ >>> reader.read(20)
2103
+ u'test file.'
2104
+ >>> reader.seek(pos) # rewind to the position from tell.
2105
+ >>> reader.read(20)
2106
+ u'test file.'
2107
+
2108
+ The ``seek()`` and ``tell()`` methods work property even when
2109
+ ``readline()`` is used.
2110
+
2111
+ >>> stream = BytesIO(b"""\
2112
+ ... This is a test file.
2113
+ ... It is encoded in utf-16.
2114
+ ... """.decode('ascii').encode('utf-16'))
2115
+ >>> reader = SeekableUnicodeStreamReader(stream, 'utf-16')
2116
+ >>> reader.readline()
2117
+ u'This is a test file.\n'
2118
+ >>> pos = reader.tell(); print(pos)
2119
+ 44
2120
+ >>> reader.readline()
2121
+ u'It is encoded in utf-16.\n'
2122
+ >>> reader.seek(pos) # rewind to the position from tell.
2123
+ >>> reader.readline()
2124
+ u'It is encoded in utf-16.\n'
2125
+
2126
+
2127
+ Squashed Bugs
2128
+ =============
2129
+
2130
+ svn 5276 fixed a bug in the comment-stripping behavior of
2131
+ parse_sexpr_block.
2132
+
2133
+ >>> from io import StringIO
2134
+ >>> from nltk.corpus.reader.util import read_sexpr_block
2135
+ >>> f = StringIO(b"""
2136
+ ... (a b c)
2137
+ ... # This line is a comment.
2138
+ ... (d e f\ng h)""".decode('ascii'))
2139
+ >>> print(read_sexpr_block(f, block_size=38, comment_char='#'))
2140
+ ['(a b c)']
2141
+ >>> print(read_sexpr_block(f, block_size=38, comment_char='#'))
2142
+ ['(d e f\ng h)']
2143
+
2144
+ svn 5277 fixed a bug in parse_sexpr_block, which would cause it to
2145
+ enter an infinite loop if a file ended mid-sexpr, or ended with a
2146
+ token that was not followed by whitespace. A related bug caused
2147
+ an infinite loop if the corpus ended in an unmatched close paren --
2148
+ this was fixed in svn 5279
2149
+
2150
+ >>> f = StringIO(b"""
2151
+ ... This file ends mid-sexpr
2152
+ ... (hello (world""".decode('ascii'))
2153
+ >>> for i in range(3): print(read_sexpr_block(f))
2154
+ ['This', 'file', 'ends', 'mid-sexpr']
2155
+ ['(hello (world']
2156
+ []
2157
+
2158
+ >>> f = StringIO(b"This file has no trailing whitespace.".decode('ascii'))
2159
+ >>> for i in range(3): print(read_sexpr_block(f))
2160
+ ['This', 'file', 'has', 'no', 'trailing']
2161
+ ['whitespace.']
2162
+ []
2163
+
2164
+ >>> # Bug fixed in 5279:
2165
+ >>> f = StringIO(b"a b c)".decode('ascii'))
2166
+ >>> for i in range(3): print(read_sexpr_block(f))
2167
+ ['a', 'b']
2168
+ ['c)']
2169
+ []
2170
+
2171
+
2172
+ svn 5624 & 5265 fixed a bug in ConcatenatedCorpusView, which caused it
2173
+ to return the wrong items when indexed starting at any index beyond
2174
+ the first file.
2175
+
2176
+ >>> import nltk
2177
+ >>> sents = nltk.corpus.brown.sents()
2178
+ >>> print(sents[6000])
2179
+ ['Cholesterol', 'and', 'thyroid']
2180
+ >>> print(sents[6000])
2181
+ ['Cholesterol', 'and', 'thyroid']
2182
+
2183
+ svn 5728 fixed a bug in Categorized*CorpusReader, which caused them
2184
+ to return words from *all* files when just one file was specified.
2185
+
2186
+ >>> from nltk.corpus import reuters
2187
+ >>> reuters.words('training/13085')
2188
+ ['SNYDER', '&', 'lt', ';', 'SOI', '>', 'MAKES', ...]
2189
+ >>> reuters.words('training/5082')
2190
+ ['SHEPPARD', 'RESOURCES', 'TO', 'MERGE', 'WITH', ...]
2191
+
2192
+ svn 7227 fixed a bug in the qc corpus reader, which prevented
2193
+ access to its tuples() method
2194
+
2195
+ >>> from nltk.corpus import qc
2196
+ >>> qc.tuples('test.txt')
2197
+ [('NUM:dist', 'How far is it from Denver to Aspen ?'), ('LOC:city', 'What county is Modesto , California in ?'), ...]
2198
+
2199
+
2200
+