<jupyter_start><jupyter_text>Copyright 2021 <NAME> and made available under [CC BY-SA](https://creativecommons.org/licenses/by-sa/4.0) for text and [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) for code.  Preprocessing textIn preparing text for analysis, we can make a distinction between general preprocessing of text and specific transformations we might do to it later.This preprocessing typically consists of two kinds of **tokenization**, word tokenization and sentence tokenization.Tokenization is the process of deciding where, in a sequence of characters, *text of interest* starts and stops, e.g. where a word starts and stops or sentence starts and stops.Equivalently, we can think of tokenization as identifying particular *boundaries* in the text.  What you will learnYou will learn about tokenization at the word and sentence levels and how this can help you prepare text for later analysis.  We will cover:- Raw, word-tokenized, and sentence-tokenized text- Techniques for word and sentence tokenization  When to use tokenizationTokenization is a common first step in text analysis.Often it is practical to do tokenization up front and use the resulting data in future analyses, rather than repeating tokenization every time.Use tokenization unless you are working with software libraries that automatically do tokenization when they build a model.  Three views of textLet's begin by looking at the end product of tokenization to better understand the goal.We'll use NLTK, a well-known software library for teaching NLP that is paired with a [free book](https://www.nltk.org/book/).If you haven't already downloaded the `book` data, execute the following code and select `book` from the download menu.Once you are done, simply close the window to continue.<jupyter_code>import sys
import nltk
sys.argv=['']
nltk.download()<jupyter_output>showing info https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/index.xml<jupyter_text>Before we proceed, let's define some terms.A **corpus** is a collection of text. Corpora is the plural of corpus.Typically corpora are created for a particular purpose. For example, if I'm interested in Twitter, I might create a corpus of tweets. Therefore there isn't a single all-purpose corpus, unless you consider the Internet to be a corpus.NLTK has preprocessed many common corpora, and their structure serves as a nice model of what preprocessing should look like.We will take a look before moving on to preparing our own corpora.Here is the general structure for NLTK corpora:- Each corpus is a collection of files which have `fileids`- Each corpus can be read `raw`, and `fileids` can be read raw. Raw means you get the original text.- Each corpus can be read as `words`, and `fileids` can be read as `words`. That means it will give you each word in order.- Each corpus can be read as `sents`, and `fileids` can be read as `sents`. That means it will give you each sentence in order.Raw, words, and sentences are three views of text useful from a preprocessing perspective.Let's import the `gutenberg` corpus. This is a collection of books out of copyright. - from `nltk.corpus` import `gutenberg`<jupyter_code>from nltk.corpus import gutenberg

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="importFrom" id="XD9YVa/m9vX;ax-@^}(K" x="16" y="64"><field name="libraryName">nltk.corpus</field><field name="libraryAlias" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field></block></xml><jupyter_output><empty_output><jupyter_text>Let's start by getting a list of fileids:- with `gutenberg` do `fileids`<jupyter_code>gutenberg.fileids()

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="varDoMethod" id="tLR@!_zful,@toy1e3E(" x="26" y="476"><field name="VAR" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field><field name="MEMBER">fileids</field><data>gutenberg:fileids</data></block></xml><jupyter_output><empty_output><jupyter_text>Each one of these is a file containing the text of a book, e.g. [<NAME>'s Emma](https://en.wikipedia.org/wiki/Emma_(novel).  RawLet's take `'austen-emma.txt'` and look at the raw form of it:- set `emma` to with `gutenberg` do `raw` using `'austen-emma.txt'` - in text `emma` get substring from `first letter` to letter  `477`<jupyter_code>emma = gutenberg.raw('austen-emma.txt')

emma[ : 477]

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="~{Lr[.?oEVR{TA827|}Z">emma</variable><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="variables_set" id="8U[%/(,=7*1d(PKaMDtN" x="-7" y="402"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field><value name="VALUE"><block type="varDoMethod" id="t(78BFv`F9G)$Ewv`Y6]"><field name="VAR" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field><field name="MEMBER">raw</field><data>gutenberg:raw</data><value name="INPUT"><block type="text" id="}/De;X%+0y3nz/Ii$B`w"><field name="TEXT">austen-emma.txt</field></block></value></block></value></block><block type="text_getSubstring" id="T6I]|jqY2V[AT5dEzF9X" x="-12" y="458"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="STRING"><block type="variables_get" id="_5j@],RYC?A)PFN)buGZ"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field></block></value><value name="AT2"><block type="math_number" id="|=MueZ1H5an*lY}XX1lq"><field name="NUM">477</field></block></value></block></xml><jupyter_output><empty_output><jupyter_text>Compare this to the [plain text available at Project Gutenberg](https://www.gutenberg.org/cache/epub/158/pg158.txt):...> VOLUME I>>>>> CHAPTER I>>> <NAME>oodhouse, handsome, clever, and rich, with a comfortable home and> happy disposition, seemed to unite some of the best blessings of> existence; and had lived nearly twenty-one years in the world with very> little to distress or vex her.>> She was the youngest of the two daughters of a most affectionate,> indulgent father; and had, in consequence of her sister’s marriage,> been mistress of his house from a very early period. We can see that this is a mostly faithful representation of the source text, except for some differences in newlines (`\n`).Most importantly, we see that the result is a continuous sequence of characters, or *string*, with no explicit boundaries between words or sentences.  WordsLet's look at the same text, but this time in words:- set `emmaWords` to with `gutenberg` do `words` using `'austen-emma.txt'` - in list `emmaWords` get sublist from `first` to  `99`<jupyter_code>emmaWords = gutenberg.words('austen-emma.txt')

emmaWords[ : 99]

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="Xqgp6t-PV4#yzg[[zMob">emmaWords</variable><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="variables_set" id="3OifKIg*V}`wTrVr-U+I" x="38" y="246"><field name="VAR" id="Xqgp6t-PV4#yzg[[zMob">emmaWords</field><value name="VALUE"><block type="varDoMethod" id="t(78BFv`F9G)$Ewv`Y6]"><field name="VAR" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field><field name="MEMBER">words</field><data>gutenberg:words</data><value name="INPUT"><block type="text" id="}/De;X%+0y3nz/Ii$B`w"><field name="TEXT">austen-emma.txt</field></block></value></block></value></block><block type="lists_getSublist" id="hcUX-ml_?56X#302Hu+~" x="160" y="316"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="K0%9m4`F(HvgI0YB@1l%"><field name="VAR" id="Xqgp6t-PV4#yzg[[zMob">emmaWords</field></block></value><value name="AT2"><block type="math_number" id="Q9K)qPl.,-KFM}ZRFJ3f"><field name="NUM">99</field></block></value></block></xml><jupyter_output><empty_output><jupyter_text>The result this time is a list of tokens, which includes both words and *punctuation*.The newline characters are completely gone.Notice in particular how compound words like `twenty-one` have been handled, as have possessives like `sister's` - both have been decomposed into constituent elements.These are examples of some of the subtle issues that arise in word tokenization.Let's consider the possessive handling a bit more closely - why break it up into constituent elements?Well, if we are counting occurrences of `sister`, breaking `sister's` into `sister`, `'`, and `s` will prevent us from overlooking possessive forms of `sister`.Similarly, if we are looking at possessives, breaking things apart could make it easier to analyze them, because possessive marking (i.e. the `'` and `s`) has been unbound from the base word.The same idea applies to treating punctuation as it's own token - we don't want to treat `her.` differently from `her` just because it is at the end of the sentence.  SentencesLet's look again at this text, but as sentences:- set `emmaSents` to with `gutenberg` do `sents` using `'austen-emma.txt'` - in list `emmaSents` get sublist from `first` to  `5`<jupyter_code>emmaSents = gutenberg.sents('austen-emma.txt')

emmaSents[ : 5]

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="dAM-/@sFPVu5R?$h[.lk">emmaSents</variable><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="variables_set" id="]kZqQLAcFQ}sq5~yofrj" x="-12" y="391"><field name="VAR" id="dAM-/@sFPVu5R?$h[.lk">emmaSents</field><value name="VALUE"><block type="varDoMethod" id="t(78BFv`F9G)$Ewv`Y6]"><field name="VAR" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field><field name="MEMBER">sents</field><data>gutenberg:sents</data><value name="INPUT"><block type="text" id="}/De;X%+0y3nz/Ii$B`w"><field name="TEXT">austen-emma.txt</field></block></value></block></value></block><block type="lists_getSublist" id="h;d!0,b!=].To}2fLmGI" x="-10" y="462"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="?UJ[[J=fEuk}dk2z`1G9"><field name="VAR" id="dAM-/@sFPVu5R?$h[.lk">emmaSents</field></block></value><value name="AT2"><block type="math_number" id="g25x1,DzoN6uz)KnIK-`"><field name="NUM">6</field></block></value></block></xml><jupyter_output><empty_output><jupyter_text>This time we get a **list of lists** of tokens, rather than a list of tokens.Each inner list corresponds to the tokens in a sentence.So really this is no different than what we got with word tokenization, except that now we have additionally grouped tokens by sentences.  Tokenizing manuallyAs nice as NLTK's preprocessed corpora are (check out the [full list here](https://www.nltk.org/nltk_data/)]), chances are the text you want to study is not already in NLTK.Therefore, you're going to need to do the preprocessing yourself.We're going to keep working with NLTK, but you can do tokenization with just about any NLP library; a current popular alternative is [spaCy](https://spacy.io/usage/spacy-101).In the examples that follow, we'll use the same text as above, but this time load it manually:- import `nltk` as `nltk`- set `emma` to    - read text from file (see I/O) connected to    - with `gutenberg` do `abspath` using `austen-emma.txt`    You could read any arbitrary file then same way - `gutenberg.abspath('austen-emma.txt')` is just the file path to `austen-emma.txt` in the NLTK storage folder.<jupyter_code>import nltk as nltk

emma = open((gutenberg.abspath('austen-emma.txt')),encoding='utf-8').read()

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="~{Lr[.?oEVR{TA827|}Z">emma</variable><variable id="]HJ?tF]9lV9p9(|h{fmK">nltk</variable><variable id="`$^y`^v4:G8DO1QCBCw8">gutenberg</variable></variables><block type="importAs" id="$o8RA~*8X9Q|cbW?zr;E" x="71" y="81"><field name="libraryName">nltk</field><field name="libraryAlias" id="]HJ?tF]9lV9p9(|h{fmK">nltk</field></block><block type="variables_set" id="BjKkWY`m(S98Nd):#J=V" x="59" y="155"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field><value name="VALUE"><block type="textFromFile" id="GI())F?=o,*MK.I%*`ks"><value name="FILENAME"><shadow type="text" id="~*D.|b9xA7[NmQgY-H^1"><field name="TEXT">name of file</field></shadow><block type="varDoMethod" id="jfx_*M4zaU~HuQbXM|oC"><field name="VAR" id="`$^y`^v4:G8DO1QCBCw8">gutenberg</field><field name="MEMBER">abspath</field><data>emmaSents:</data><value name="INPUT"><block type="text" id="0II}$K#u5Zv@_=/(*:5["><field name="TEXT">austen-emma.txt</field></block></value></block></value></block></value></block></xml><jupyter_output><empty_output><jupyter_text>Tokenizing wordsNLTK has a handy function called `word_tokenize`. Let's use it and compare to the original we got directly from NLTK:- set `emmaWords2` to with `nltk` do `word_tokenize` using `emma`- print in list `emmaWords` get sublist from `first` to  `99`- print in list `emmaWords2` get sublist from `first` to  `99`<jupyter_code>emmaWords2 = nltk.word_tokenize(emma)
print(emmaWords[ : 99])
print(emmaWords2[ : 99])

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="K,0]PBDLVIX*%3xW%U}7">emmaWords2</variable><variable id="]HJ?tF]9lV9p9(|h{fmK">nltk</variable><variable id="~{Lr[.?oEVR{TA827|}Z">emma</variable><variable id="Xqgp6t-PV4#yzg[[zMob">emmaWords</variable></variables><block type="variables_set" id="aU`_G5Z/zt~N{AO*g::M" x="86" y="164"><field name="VAR" id="K,0]PBDLVIX*%3xW%U}7">emmaWords2</field><value name="VALUE"><block type="varDoMethod" id="4w-PTl0Y*;o5k:Cqzu6Y"><field name="VAR" id="]HJ?tF]9lV9p9(|h{fmK">nltk</field><field name="MEMBER">word_tokenize</field><data>nltk:word_tokenize</data><value name="INPUT"><block type="variables_get" id="__(y#:Q,Y4P)$8|u*+%Y"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field></block></value></block></value><next><block type="text_print" id="Gj/{Q?NFnH1ICV_[Qu7R"><value name="TEXT"><shadow type="text" id="T%?w2b@h1c)y%Jw}3f5X"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KUp-K(cJm1okZ?L=_5OC"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="rq~%1IJ~yvXiI]`)0Vu["><field name="VAR" id="Xqgp6t-PV4#yzg[[zMob">emmaWords</field></block></value><value name="AT2"><block type="math_number" id="H=6./b%q+OqNC)CH;~,N"><field name="NUM">99</field></block></value></block></value><next><block type="text_print" id="4wt`aU/QlG+j?5~BjZ9^"><value name="TEXT"><shadow type="text"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KV(L4I}c|510m]g(ukTf"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="}DiVK@bY%ZxK(KzOA(sh"><field name="VAR" id="K,0]PBDLVIX*%3xW%U}7">emmaWords2</field></block></value><value name="AT2"><block type="math_number" id=".?_iG5|BNQ|Z|E_[n-1n"><field name="NUM">99</field></block></value></block></value></block></next></block></next></block></xml><jupyter_output>['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ']', 'VOLUME', 'I', 'CHAPTER', 'I', 'Emma', 'Woodhouse', ',', 'handsome', ',', 'clever', ',', 'and', 'rich', ',', 'with', 'a', 'comfortable', 'home', 'and', 'happy', 'disposition', ',', 'seemed', 'to', 'unite', 'some', 'of', 'the', 'best', 'blessings', 'of', 'existence', ';', 'and', 'had', 'lived', 'nearly', 'twenty', '-', 'one', 'years', 'in', 'the', 'world', 'with', 'very', 'little', 'to', 'distress', 'or', 'vex', 'her', '.', 'She', 'was', 'the', 'youngest', 'of', 'the', 'two', 'daughters', 'of', 'a', 'most', 'affectionate', ',', 'indulgent', 'father', ';', 'and', 'had', ',', 'in', 'consequence', 'of', 'her', 'sister', "'", 's', 'marriage', ',', 'been', 'mistress', 'of', 'his', 'house', 'from', 'a', 'very', 'early', 'period', '.']
['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ']', 'VOLUME', 'I', 'CHAPTER', 'I', 'Emma', 'Woodhouse', ',', 'handsome', ',', 'clever', ',', 'and', 'rich', ',', 'with', 'a', 'comfortable', 'home', 'and', 'happy',[...]<jupyter_text>**Notice we have some differences.** In the tokenization we just did, `twenty-one` has not been decomposed, and `'s` has been treated as a single unit (this is PennTreebank style).Again, there are subtle distinctions in tokenization styles, and different styles may be preferred depending on your analysis. Or, you may just prefer to get very familiar with a particular style so you aren't surprised by the decisions it makes.A list of styles for available in NLTK can be found [here](https://www.nltk.org/api/nltk.tokenize.htmlsubmodules).  Tokenizing sentencesLet's manually tokenize sentences using NLTK's `sent_tokenize`:- set `emmaSents2` to with `nltk` do `sent_tokenize` using `emma`- print in list `emmaSents` get sublist from `first` to  `5`- print in list `emmaSents2` get sublist from `first` to  `5`<jupyter_code>emmaSents2 = nltk.sent_tokenize(emma)
print(emmaSents[ : 5])
print(emmaSents2[ : 5])

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="V:qE@zR0KPo88fkuJ}ht">emmaSents2</variable><variable id="]HJ?tF]9lV9p9(|h{fmK">nltk</variable><variable id="~{Lr[.?oEVR{TA827|}Z">emma</variable><variable id="dAM-/@sFPVu5R?$h[.lk">emmaSents</variable></variables><block type="variables_set" id="aU`_G5Z/zt~N{AO*g::M" x="86" y="164"><field name="VAR" id="V:qE@zR0KPo88fkuJ}ht">emmaSents2</field><value name="VALUE"><block type="varDoMethod" id="4w-PTl0Y*;o5k:Cqzu6Y"><field name="VAR" id="]HJ?tF]9lV9p9(|h{fmK">nltk</field><field name="MEMBER">sent_tokenize</field><data>nltk:sent_tokenize</data><value name="INPUT"><block type="variables_get" id="__(y#:Q,Y4P)$8|u*+%Y"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field></block></value></block></value><next><block type="text_print" id="Gj/{Q?NFnH1ICV_[Qu7R"><value name="TEXT"><shadow type="text" id="T%?w2b@h1c)y%Jw}3f5X"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KUp-K(cJm1okZ?L=_5OC"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="rq~%1IJ~yvXiI]`)0Vu["><field name="VAR" id="dAM-/@sFPVu5R?$h[.lk">emmaSents</field></block></value><value name="AT2"><block type="math_number" id="H=6./b%q+OqNC)CH;~,N"><field name="NUM">5</field></block></value></block></value><next><block type="text_print" id="4wt`aU/QlG+j?5~BjZ9^"><value name="TEXT"><shadow type="text"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KV(L4I}c|510m]g(ukTf"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="}DiVK@bY%ZxK(KzOA(sh"><field name="VAR" id="V:qE@zR0KPo88fkuJ}ht">emmaSents2</field></block></value><value name="AT2"><block type="math_number" id=".?_iG5|BNQ|Z|E_[n-1n"><field name="NUM">5</field></block></value></block></value></block></next></block></next></block></xml><jupyter_output>[['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ']'], ['VOLUME', 'I'], ['CHAPTER', 'I'], ['Emma', 'Woodhouse', ',', 'handsome', ',', 'clever', ',', 'and', 'rich', ',', 'with', 'a', 'comfortable', 'home', 'and', 'happy', 'disposition', ',', 'seemed', 'to', 'unite', 'some', 'of', 'the', 'best', 'blessings', 'of', 'existence', ';', 'and', 'had', 'lived', 'nearly', 'twenty', '-', 'one', 'years', 'in', 'the', 'world', 'with', 'very', 'little', 'to', 'distress', 'or', 'vex', 'her', '.'], ['She', 'was', 'the', 'youngest', 'of', 'the', 'two', 'daughters', 'of', 'a', 'most', 'affectionate', ',', 'indulgent', 'father', ';', 'and', 'had', ',', 'in', 'consequence', 'of', 'her', 'sister', "'", 's', 'marriage', ',', 'been', 'mistress', 'of', 'his', 'house', 'from', 'a', 'very', 'early', 'period', '.']]
['[Emma by <NAME> 1816]\n\nVOLUME I\n\nCHAPTER I\n\n\nEmma Woodhouse, handsome, clever, and rich, with a comfortable home\nand happy disposition, seemed to unite some of the best blessings\nof exi[...]<jupyter_text>This time the differences are more severe.What happened?If you look closely, you'll see that the manual sentence tokenization returned each sentence as a sequence of characters, or *string*, rather than as a list of word tokens.Also notice that the title and headings were not separated from the first sentence.If we want both words and sentences tokenized together, we can combine the two operations.Let's look at how to do this using **comprehensions**.A comprehension is basically a list generator.In other words, instead of having a `for` loop that adds elements to a list, we can define a list by specifying how to generate each element in the list.Comprehensions are pretty useful for NLP.Let's try it:- Create `emmaSents3` and set to    - a list with one element containing        - for each item `i` in list with `nltk` do `sent_tokenize` using `emma` (see LOOPS)            - yield with `nltk` do `word_tokenize` using `i`- print in list `emmaSents` get sublist from `first` to  `5`- print in list `emmaSents3` get sublist from `first` to  `5`<jupyter_code>emmaSents3 = [(nltk.word_tokenize(i)) for i in (nltk.sent_tokenize(emma))]
print(emmaSents[ : 5])
print(emmaSents3[ : 5])

#<xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="SS`8(eF^8i7x|~c%g!go">emmaSents3</variable><variable id="vm#^l?f3f{nfc06H7ta7">i</variable><variable id="dAM-/@sFPVu5R?$h[.lk">emmaSents</variable><variable id="]HJ?tF]9lV9p9(|h{fmK">nltk</variable><variable id="~{Lr[.?oEVR{TA827|}Z">emma</variable></variables><block type="variables_set" id="aU`_G5Z/zt~N{AO*g::M" x="29" y="204"><field name="VAR" id="SS`8(eF^8i7x|~c%g!go">emmaSents3</field><value name="VALUE"><block type="lists_create_with" id="he+/o3bmtQnCkPO)M4_T"><mutation items="1"></mutation><value name="ADD0"><block type="comprehensionForEach" id="o;W2uLos,hSk20@(p7y1"><field name="VAR" id="vm#^l?f3f{nfc06H7ta7">i</field><value name="LIST"><block type="varDoMethod" id="4w-PTl0Y*;o5k:Cqzu6Y"><field name="VAR" id="]HJ?tF]9lV9p9(|h{fmK">nltk</field><field name="MEMBER">sent_tokenize</field><data>nltk:sent_tokenize</data><value name="INPUT"><block type="variables_get" id="__(y#:Q,Y4P)$8|u*+%Y"><field name="VAR" id="~{Lr[.?oEVR{TA827|}Z">emma</field></block></value></block></value><value name="YIELD"><block type="varDoMethod" id="#s*EXxByy$-41LlvlrHk"><field name="VAR" id="]HJ?tF]9lV9p9(|h{fmK">nltk</field><field name="MEMBER">word_tokenize</field><data>nltk:word_tokenize</data><value name="INPUT"><block type="variables_get" id="{8R3$6Qk=2$li.9UOoI2"><field name="VAR" id="vm#^l?f3f{nfc06H7ta7">i</field></block></value></block></value></block></value></block></value><next><block type="text_print" id="Gj/{Q?NFnH1ICV_[Qu7R"><value name="TEXT"><shadow type="text" id="T%?w2b@h1c)y%Jw}3f5X"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KUp-K(cJm1okZ?L=_5OC"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="rq~%1IJ~yvXiI]`)0Vu["><field name="VAR" id="dAM-/@sFPVu5R?$h[.lk">emmaSents</field></block></value><value name="AT2"><block type="math_number" id="H=6./b%q+OqNC)CH;~,N"><field name="NUM">5</field></block></value></block></value><next><block type="text_print" id="4wt`aU/QlG+j?5~BjZ9^"><value name="TEXT"><shadow type="text"><field name="TEXT">abc</field></shadow><block type="lists_getSublist" id="KV(L4I}c|510m]g(ukTf"><mutation at1="false" at2="true"></mutation><field name="WHERE1">FIRST</field><field name="WHERE2">FROM_START</field><value name="LIST"><block type="variables_get" id="}DiVK@bY%ZxK(KzOA(sh"><field name="VAR" id="SS`8(eF^8i7x|~c%g!go">emmaSents3</field></block></value><value name="AT2"><block type="math_number" id=".?_iG5|BNQ|Z|E_[n-1n"><field name="NUM">5</field></block></value></block></value></block></next></block></next></block></xml><jupyter_output>[['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ']'], ['VOLUME', 'I'], ['CHAPTER', 'I'], ['Emma', 'Woodhouse', ',', 'handsome', ',', 'clever', ',', 'and', 'rich', ',', 'with', 'a', 'comfortable', 'home', 'and', 'happy', 'disposition', ',', 'seemed', 'to', 'unite', 'some', 'of', 'the', 'best', 'blessings', 'of', 'existence', ';', 'and', 'had', 'lived', 'nearly', 'twenty', '-', 'one', 'years', 'in', 'the', 'world', 'with', 'very', 'little', 'to', 'distress', 'or', 'vex', 'her', '.'], ['She', 'was', 'the', 'youngest', 'of', 'the', 'two', 'daughters', 'of', 'a', 'most', 'affectionate', ',', 'indulgent', 'father', ';', 'and', 'had', ',', 'in', 'consequence', 'of', 'her', 'sister', "'", 's', 'marriage', ',', 'been', 'mistress', 'of', 'his', 'house', 'from', 'a', 'very', 'early', 'period', '.']]
[['[', 'Emma', 'by', 'Jane', 'Austen', '1816', ']', 'VOLUME', 'I', 'CHAPTER', 'I', 'Emma', 'Woodhouse', ',', 'handsome', ',', 'clever', ',', 'and', 'rich', ',', 'with', 'a', 'comfortable', 'home', 'and[...]
{'fraction_non_alphanumeric': 0.2083914412081125, 'fraction_numerical': 0.02183527911702594, 'mean_word_length': 7.7115584866365845, 'pattern_counts': {'":': 0, '<': 561, '<?xml version=': 0, '>': 577, 'https://': 17, 'lorem ipsum': 0, 'www.': 5, 'xml': 37}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '299765', 'license': 'Apache-2.0', 'n_tokens_mistral': 9496, 'n_tokens_neox': 9074, 'n_words': 2067, 'path': 'Preprocessing-text.ipynb', 'repo_name': 'aolney/datawhys-content-notebooks-nlp', 'size': '25116'}