<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>nltk on C'est la Z</title><link>https://cestlaz.github.io/cestlaz-old-hugo.github.io/tags/nltk/</link><description>C'est la Z (nltk)</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 25 Nov 2019 05:45:55 -0400</lastBuildDate><atom:link href="https://cestlaz.github.io/cestlaz-old-hugo.github.io/tags/nltk/rss.xml" rel="self" type="application/rss"/><item><title>Working with texts part 3 - word chains</title><link>https://cestlaz.github.io/cestlaz-old-hugo.github.io/post/word-chains/</link><pubDate>Mon, 25 Nov 2019 05:45:55 -0400</pubDate><guid>https://cestlaz.github.io/cestlaz-old-hugo.github.io/post/word-chains/</guid><description>&lt;p>
At this point, we&amp;#39;ve done a fair amount of playing with text so it&amp;#39;s
time for a fun little project. We&amp;#39;re going to generate some text &amp;#34;in
the style&amp;#34; of a source text. The technique we&amp;#39;re going to use is
usually called a Markov Chain text generator. Basically a model where
the next state or word is based entirely on the current state. I don&amp;#39;t
dwell on the math under the hood but in case you&amp;#39;re interested, here
are a few links: &lt;a href="https://en.m.wikipedia.org/wiki/Markov_chain">Wikipedia&lt;/a>, &lt;a href="http://setosa.io/ev/markov-chains/">Explained Visually&lt;/a>, &lt;a href="https://www.math.ucdavis.edu/~daddel/linear_algebra_appl/Applications/MarkovChain/MarkovChain_9_18/MarkovChain_9_18.html">UC Davis Math&lt;/a>. &lt;/p>
&lt;p>
You can motivate this lesson in a number of ways. One is to start by
showing some generated text - for this, a flowery, poetic text like
the Book of Psalms works well. You can generate text a bunch of times
until you get a good result. &lt;/p>
&lt;p>
Here&amp;#39;s the start of the Book of Psalms:&lt;/p>
&lt;blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Blessed is the man that walketh not in the counsel of the
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ungodly, nor standeth in the way of sinners, nor sitteth in
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>the seat of the scornful.&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/blockquote>
&lt;p>
and here&amp;#39;s some generated text:&lt;/p>
&lt;blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>Blessed is the people that delight in war. Princes shall come out of
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Zion, the perfection of beauty god hath shined our god shall come and
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>shall declare thy mighty acts. I will speak of the glory of the lord
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>surely i will not lie unto David.&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/blockquote>
&lt;p>
I added the punctuation as our generator strips it all and converts
the text to lower case.&lt;/p>
&lt;p>
The generated text looks reasonable in some ways but is clearly wrong
in others.&lt;/p>
&lt;p>
This leads to the conversation.&lt;/p>
&lt;p>
If we look at the original text, it starts with &amp;#34;blessed&amp;#34; but if we
look at our bag of words we also can see that &amp;#34;blessed&amp;#34; appears 49
times. What&amp;#39;s interesting for generating text are the words the follow
&amp;#34;blessed&amp;#34; and the number of times they follow it. Here they are
(sorted for convenience):&lt;/p>
&lt;blockquote>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Word&lt;/th>
&lt;th class="align-right">How many times it follows the word &amp;#34;blessed&amp;#34;&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>are&lt;/td>
&lt;td class="align-right">5&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>art&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>be&lt;/td>
&lt;td class="align-right">16&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>blessed&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>depart&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>for&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>his&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>in&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>is&lt;/td>
&lt;td class="align-right">14&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>of&lt;/td>
&lt;td class="align-right">2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>that&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>thee&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>thy&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>upon&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>wealth&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>you&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/blockquote>
&lt;p>
So we&amp;#39;ll have a lot of things like &amp;#34;blessed be the&amp;#34; &amp;#34;blessed be he&amp;#34;
etc. but only one occurrence of &amp;#34;blessed upon….&amp;#34; To generate text, we
can build a dictionary where the keys are the words and the values are
all the words that follow the key. We can build this with a variation
on our bag of words builder:&lt;/p>
&lt;div class="src src-python">
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span> words_raw &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a cleaned string with our text&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> words &lt;span style="color:#f92672">=&lt;/span> words&lt;span style="color:#f92672">.&lt;/span>raw&lt;span style="color:#f92672">.&lt;/span>split()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wordlists &lt;span style="color:#f92672">=&lt;/span> {}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> i &lt;span style="color:#f92672">in&lt;/span> range(len(words)&lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> current_word &lt;span style="color:#f92672">=&lt;/span> words[i]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> next_word &lt;span style="color:#f92672">=&lt;/span> words[i&lt;span style="color:#f92672">+&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wordlists&lt;span style="color:#f92672">.&lt;/span>setdefault(current_word,[])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wordlists&lt;span style="color:#f92672">.&lt;/span>[current_word]&lt;span style="color:#f92672">.&lt;/span>append(next_word)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
Note that we need a counting loop rather than just iterating over the
list since we need both the current item and the one after it in each
iteration.&lt;/p>
&lt;p>
The (partial) value for the wordlists for the Book of Psalms would be:&lt;/p>
&lt;div class="src src-python">
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span> wordlists &lt;span style="color:#f92672">=&lt;/span> {&lt;span style="color:#f92672">...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;blessed&amp;#39;&lt;/span> : [&lt;span style="color:#e6db74">&amp;#39;are&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;are&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;are&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;are&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;are&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;art&amp;#39;&lt;/span>, &lt;span style="color:#e6db74">&amp;#39;be&amp;#39;&lt;/span>, &lt;span style="color:#f92672">...&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;wealth&amp;#39;&lt;/span> : [&lt;span style="color:#e6db74">&amp;#39;and&amp;#39;&lt;/span>,&lt;span style="color:#e6db74">&amp;#39;and&amp;#39;&lt;/span>,&lt;span style="color:#e6db74">&amp;#39;by&amp;#39;&lt;/span>,&lt;span style="color:#e6db74">&amp;#39;to&amp;#39;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
At this point, generating text is easy. &lt;/p>
&lt;ol>
&lt;li>Start with a word&lt;/li>
&lt;li>Add the word to yoru story.&lt;/li>
&lt;li>Look it up in your wordlists dictionary.&lt;/li>
&lt;li>select a random word from that words dictionary entry (it&amp;#39;s list).&lt;/li>
&lt;li>That becomes the word for the next iteration&lt;/li>
&lt;li>Repeat until you have enough words.&lt;/li>
&lt;/ol>
&lt;p>This won&amp;#39;t add any punctuation and it will crash when it gets to the
last word in the original text (as it can&amp;#39;t find any &amp;#34;next words&amp;#34; but
basically it will work. Here&amp;#39;s the code:&lt;/p>
&lt;div class="src src-python">
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># assume wordlists is the dictionary built as specified above&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># and that we&amp;#39;re starting with the word &amp;#34;blessed&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> current_word &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;blessed&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> storylist &lt;span style="color:#f92672">=&lt;/span> []
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> i &lt;span style="color:#f92672">in&lt;/span> range(storylength):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> story&lt;span style="color:#f92672">.&lt;/span>append(current_word)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> current_word &lt;span style="color:#f92672">=&lt;/span> random&lt;span style="color:#f92672">.&lt;/span>choice(wordlists[current_word])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> story &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34; &amp;#34;&lt;/span>&lt;span style="color:#f92672">.&lt;/span>join(storylist)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
The &lt;code>random.choice()&lt;/code> randomly selects a word from a list. This is
perfect for us since words that follow our key more frequently will
have more entries in the list and thus appear more often. I decided to
build a list of words and then use the &lt;code>&amp;#34; &amp;#34;.join()&lt;/code> to turn it all
into a space separated string.&lt;/p>
&lt;p>
This is pretty fun but the students will note that it really doesn&amp;#39;t
work that well. This can lead to increasing our sample. Instead of
using a single word as our key and having chain links based on two
words (key, random choice from value), we can use three word
links. Use a two word tuple for the key and the same list of words as
the value.&lt;/p>
&lt;p>
For example, a partial dictionary based on this idea from Macbeth Act
1 Scene 1 could be:&lt;/p>
&lt;div class="src src-python">
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># source -&amp;gt; &amp;#34;when shall we three meet again&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> tuple_dict &lt;span style="color:#f92672">=&lt;/span> { (&lt;span style="color:#e6db74">&amp;#34;when&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;shall&amp;#34;&lt;/span>) : [&lt;span style="color:#e6db74">&amp;#34;we&amp;#34;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#e6db74">&amp;#34;shall&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;we&amp;#34;&lt;/span>) : [&lt;span style="color:#e6db74">&amp;#34;three&amp;#34;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#e6db74">&amp;#34;we&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;three&amp;#34;&lt;/span>) : [&lt;span style="color:#e6db74">&amp;#34;meet&amp;#34;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> (&lt;span style="color:#e6db74">&amp;#34;tree&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;meet&amp;#34;&lt;/span>) : [&lt;span style="color:#e6db74">&amp;#34;again&amp;#34;&lt;/span>]}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
This takes a bit more work to build and also a bit more work to
generate text but it&amp;#39;s eminently doable and the result is
better. What about three word keys? Four? These aren&amp;#39;t hard to write
and ambitious students can write a generic dicitonary builder and
story generator routine so as to be able to use any key lenght.&lt;/p>
&lt;p>
Students will find that the longer the key, the better the resultant
story. They&amp;#39;ll also notice that at some point, all you&amp;#39;ll ever
generate is the original back again. This is a great time to talk
about over-training.&lt;/p>
&lt;p>
This can be a fun unit and / or assignment. I used source materials
that I like but any text will work.&lt;/p></description></item><item><title>Working with texts part 2 - bag of words</title><link>https://cestlaz.github.io/cestlaz-old-hugo.github.io/post/bag-of-words/</link><pubDate>Wed, 20 Nov 2019 08:15:41 -0400</pubDate><guid>https://cestlaz.github.io/cestlaz-old-hugo.github.io/post/bag-of-words/</guid><description>&lt;p>
Following up on a &lt;a href="https://cestlaz.github.io/post/cleaning-textx/">previous post&lt;/a>, we&amp;#39;re going to continue to talk about
playing with text. This time, building and working with a bag of words
from a text. &lt;/p>
&lt;p>
A bag of words is a simple language processing model where you just
consider individual words in a text. What they are and how many times
they occur. This is a pretty simple model but you can still have a
good bit of fun with your students with it.&lt;/p>
&lt;p>
For example, if you take a text like this:&lt;/p>
&lt;blockquote>
&lt;p>This land is your land
this land is my land&lt;/p>
&lt;/blockquote>
&lt;p>
Once you clean the a data as per the previous post you get the
following bag:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>word&lt;/th>
&lt;th class="align-right">Count&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>is&lt;/td>
&lt;td class="align-right">2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>land&lt;/td>
&lt;td class="align-right">4&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>my&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>this&lt;/td>
&lt;td class="align-right">2&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>your&lt;/td>
&lt;td class="align-right">1&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
Not too interesting but it gets more interesting on a larger text. We
used:&lt;/p>
&lt;ul>
&lt;li>Act 1 Scene 1 from Macbeth (for testing - it&amp;#39;s only 13 lines)&lt;/li>
&lt;li>Cyrano de Bergerac (because it&amp;#39;s my favorite play)&lt;/li>
&lt;li>Moby Dick (chapter 1)&lt;/li>
&lt;li>Moby Dick (full text)&lt;/li>
&lt;li>The Book of Psalms&lt;/li>
&lt;/ul>
&lt;p>Assuming a cleaned string with all the text, building the bag is
pretty easy:&lt;/p>
&lt;p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>cleaned_text &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a string with all the cleaned text&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span>bag&lt;span style="color:#f92672">=&lt;/span>{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> word &lt;span style="color:#f92672">in&lt;/span> cleaned_text&lt;span style="color:#f92672">.&lt;/span>split():
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span> bag&lt;span style="color:#f92672">.&lt;/span>setdefault(word,&lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5&lt;/span>&lt;span> bag[word] &lt;span style="color:#f92672">=&lt;/span> bag[word] &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;p>
The &lt;code>setdefault&lt;/code> in line three says that if &lt;code>word&lt;/code> isn&amp;#39;t a key in the
dictionary then insert it with a value of 0, otherwise, if &lt;code>word&lt;/code> &lt;strong>is&lt;/strong>
already a key in the dictionary do nothing. This saves us from
constructs like:&lt;/p>
&lt;p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> word &lt;span style="color:#f92672">not&lt;/span> &lt;span style="color:#f92672">in&lt;/span> bag:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span> bag[word]&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span> bag[word] &lt;span style="color:#f92672">=&lt;/span> bag[word] &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;p>
Once we have our bag we can do some explorations. Take out all the
values using &lt;code>bag.values()&lt;/code> and sort them. Ask &amp;#34;what words are going
to occur most frequently?&amp;#34; It&amp;#39;s easy to guess that it will be words
like &lt;strong>the&lt;/strong>, &lt;strong>of&lt;/strong>, &lt;strong>and&lt;/strong> etc.. Words that don&amp;#39;t really tell us anything
about the text. It&amp;#39;s a fun puzzle to figure out where the
&amp;#34;interesting&amp;#34; words start and even the question of what might make a
word in a text &amp;#34;interesting.&amp;#34; Words like &lt;strong>the&lt;/strong>, *and&amp;#34;, etc. are known
as &lt;a href="http://xpo6.com/list-of-english-stop-words/">stop words&lt;/a>. Depending on the application, you might want ot remove
them. Then again, you might not.&lt;/p>
&lt;p>
Usually we take a bit of time just to play with the bag, looking at
the types of words in various count ranges. Sometimes we&amp;#39;ll make bags
for different chapters of books and compare them. This is also when I
cover Python list comprehensions which make experimenting on bags of
words much cleaner. Say, for instance you want to find all the words
that occur between 50 and 100 times. Without list comprehensions you
might write:&lt;/p>
&lt;p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1&lt;/span>&lt;span>result &lt;span style="color:#f92672">=&lt;/span> []
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2&lt;/span>&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> word &lt;span style="color:#f92672">in&lt;/span> bag:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3&lt;/span>&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> bag[word] &lt;span style="color:#f92672">&amp;gt;=&lt;/span> &lt;span style="color:#ae81ff">50&lt;/span> &lt;span style="color:#f92672">and&lt;/span> bag[word] &lt;span style="color:#f92672">&amp;lt;=&lt;/span> &lt;span style="color:#ae81ff">100&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4&lt;/span>&lt;span> result&lt;span style="color:#f92672">.&lt;/span>append(word) &lt;span style="color:#75715e"># or (word,count) or whatever&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;p>
While with the comprehension it&amp;#39;s:&lt;/p>
&lt;p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>result &lt;span style="color:#f92672">=&lt;/span> [ word &lt;span style="color:#66d9ef">for&lt;/span> word &lt;span style="color:#f92672">in&lt;/span> bag &lt;span style="color:#66d9ef">if&lt;/span> bag[word] &lt;span style="color:#f92672">&amp;gt;=&lt;/span> &lt;span style="color:#ae81ff">50&lt;/span> &lt;span style="color:#f92672">and&lt;/span> bag[word] &lt;span style="color:#f92672">&amp;lt;=&lt;/span> &lt;span style="color:#ae81ff">100&lt;/span>]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/p>
&lt;p>
Besides basic exploring, what else can you do? You can make word
vectors, that is a list or vector where an element is 1 if the word is
present and 0 otherwise. Then you can do simple document
comparisons. You can kick this up a notch if you calculate word
frequencies based on the bag counts and use these. &lt;/p>
&lt;p>
You can also do basic sentiment analysis. Download a list of
&amp;#34;positive&amp;#34; and &amp;#34;negative&amp;#34; words and then check bags against them. You
can check to see how many negative or positive words are in a bag or
you can work with frequencies. You can also use other categories. &lt;/p>
&lt;p>
While we were discussing this at our PD, some teachers thought that
their classes might ahve a hard time doing all of this from scratch
but thought that they could provide either the cleaning code or the
bag building code and have the students build experiments off of the
base. I thought it was a great idea.&lt;/p>
&lt;p>
At the end of our session we all agreed to think about how we might
build a lesson or unit out of this bag of words idea. I&amp;#39;ll leave you
all with some web sites that use these ideas in what I think are
interesting ways:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://davidamackenzie.com/tmbg_lyrics/">They Might Be Giants Lyrics&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://blogs.sap.com/2014/01/07/measuring-word-use-frequency-in-rap-song-lyrics/">Word use in rap lyrics&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://genius.com/Sameoldshawn-rap-stats-breaking-down-the-words-in-rap-lyrics-over-time-annotated">Another analysis of rap lyrics&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://towardsdatascience.com/text-analysis-of-successful-song-lyrics-e41a4ccb26f5">Analysis of succesful song lyrics&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>
Enjoy!&lt;/p></description></item></channel></rss>