<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/"></div></div><div><a data-url="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/" data-counturl="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/" data-count="horizontal" data-text="Term Frequency and tf-idf Using Tidy Data Principles" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://juliasilge.com/blog/Term-Frequency-tf-idf/"> data science ish</a></strong>, and kindly contributed to <a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>At the end of last week, <a target="_blank" href="http://varianceexplained.org/">Dave Robinson</a> and I released a new version of <a target="_blank" href="https://cran.r-project.org/web/packages/tidytext/index.html">tidytext on CRAN</a>, our R package for text mining using tidy data principles. You can check out <a target="_blank" href="http://juliasilge.com/blog/Life-Changing-Magic/">my first blog post about tidytext</a> to learn a bit about the philosophy of the package and see some of the ways to use it, or <a target="_blank" href="https://github.com/juliasilge/tidytext">see the package on GitHub</a>. In this new release (tidytext 0.1.1), we have added more documentation, fixed some bugs, developed better testing/CI, and added some new functionality. One of the things I am most excited about is an implementation of tf-idf using a tidy data framework; learning about and using tf-idf has been one of my goals recently and I am so happy with the work we’ve done.</p>
<p>A central question in text mining and natural language processing is how to quantify what a document is about. Can we do this by looking at the words that make up the document? One way to approach how important a word can be is its <em>term frequency</em> (tf), how frequently a word occurs in a document. There are words in a document, though, that occur many times but may not be important; in English, these are probably words like “the”, “is”, “of”, and so forth. You might take the approach of adding words like these to a list of stop words and removing them before analysis, but it is possible that some of these words might be more important in some documents than others. A list of stop words is not a sophisticated approach to adjusting term frequency for commonly used words.</p>
<p>Another approach is to look at a term’s <em>inverse document frequency</em> (idf), which decreases the weight for commonly used words and increases the weight for words that are not used very much in a collection of documents. This can be combined with term frequency to calculate a term’s <em>tf-idf</em>, the frequency of a term adjusted for how rarely it is used. It is intended to measure how important a word is to a document in a collection (or corpus) of documents. It is a rule-of-thumb or heuristic quantity; while it has proved useful in text mining, search engines, etc., its theoretical foundations are considered less than firm by information theory experts. The inverse document frequency for any given term is defined as</p>
<p></p>
<p>We can use tidy data principles to approach tf-idf analysis and use consistent, effective tools to quantify how important various terms are in a document that is part of a collection.</p>
<h2>Jane Austen Again (YES, AGAIN)</h2>
<p>Let’s start by looking at the published novels of Jane Austen and examine first term frequency, then tf-idf. We can start just by using dplyr verbs such as <code>group_by</code> and <code>join</code>. What are the most commonly used words in Jane Austen’s novels? (Let’s also calculate the total words in each novel here, for later use.)</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>dplyr</span><span>)</span>
<span>library</span><span>(</span><span>janeaustenr</span><span>)</span>
<span>library</span><span>(</span><span>tidytext</span><span>)</span>
<span>book_words</span> <span>&lt;-</span> <span>austen_books</span><span>()</span> <span>%>%</span>
        <span>unnest_tokens</span><span>(</span><span>word</span><span>,</span> <span>text</span><span>)</span> <span>%>%</span>
        <span>count</span><span>(</span><span>book</span><span>,</span> <span>word</span><span>,</span> <span>sort</span> <span>=</span> <span>TRUE</span><span>)</span> <span>%>%</span>
        <span>ungroup</span><span>()</span>

<span>total_words</span> <span>&lt;-</span> <span>book_words</span> <span>%>%</span> <span>group_by</span><span>(</span><span>book</span><span>)</span> <span>%>%</span> <span>summarize</span><span>(</span><span>total</span> <span>=</span> <span>sum</span><span>(</span><span>n</span><span>))</span>
<span>book_words</span> <span>&lt;-</span> <span>left_join</span><span>(</span><span>book_words</span><span>,</span> <span>total_words</span><span>)</span>
<span>book_words</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Source: local data frame [40,379 x 4]
## 
##                 book  word     n  total
##               &lt;fctr> &lt;chr> &lt;int>  &lt;int>
## 1     Mansfield Park   the  6206 160460
## 2     Mansfield Park    to  5475 160460
## 3     Mansfield Park   and  5438 160460
## 4               Emma    to  5239 160996
## 5               Emma   the  5201 160996
## 6               Emma   and  4896 160996
## 7     Mansfield Park    of  4778 160460
## 8  Pride &amp; Prejudice   the  4331 122204
## 9               Emma    of  4291 160996
## 10 Pride &amp; Prejudice    to  4162 122204
## ..               ...   ...   ...    ...</code></pre>
</figure>
<p>The usual suspects are here, “the”, “and”, “to”, and so forth. Let’s look at the distribution of <code>n/total</code> for each novel, the number of times a word appears in a novel divided by the total number of terms (words) in that novel. This is exactly what term frequency is.</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>ggplot2</span><span>)</span>
<span>library</span><span>(</span><span>viridis</span><span>)</span>
<span>ggplot</span><span>(</span><span>book_words</span><span>,</span> <span>aes</span><span>(</span><span>n</span><span>/</span><span>total</span><span>,</span> <span>fill</span> <span>=</span> <span>book</span><span>))</span> <span>+</span>
        <span>geom_histogram</span><span>(</span><span>alpha</span> <span>=</span> <span>0.8</span><span>,</span> <span>show.legend</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>xlim</span><span>(</span><span>NA</span><span>,</span> <span>0.0009</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Term Frequency Distribution in Jane Austen's Novels&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>&quot;Count&quot;</span><span>)</span> <span>+</span>
        <span>facet_wrap</span><span>(</span><span>~</span><span>book</span><span>,</span> <span>ncol</span> <span>=</span> <span>2</span><span>,</span> <span>scales</span> <span>=</span> <span>&quot;free_y&quot;</span><span>)</span> <span>+</span>
        <span>theme_minimal</span><span>(</span><span>base_size</span> <span>=</span> <span>13</span><span>)</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.85</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span><span>=</span><span>element_text</span><span>(</span><span>hjust</span><span>=</span><span>0</span><span>))</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span> <span>=</span> <span>element_text</span><span>(</span><span>face</span> <span>=</span> <span>&quot;italic&quot;</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i2.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-3-1.png?w=456" data-recalc-dims="1"></p>
<p>There are very long tails to the right for these novels (those extremely common words!) that I have not shown in these plots. These plots exhibit similar distributions for all the novels, with many words that occur rarely and fewer words that occur frequently. The idea of tf-idf is to find the important words for the content of each document by decreasing the weight for commonly used words and increasing the weight for words that are not used very much in a collection or corpus of documents, in this case, the group of Jane Austen’s novels as a whole. Calculating tf-idf attempts to find the words that are important (i.e., common) in a text, but not <em>too</em> common. Let’s do that now.</p>
<figure>
<pre><code data-lang="r"><span>book_words</span> <span>&lt;-</span> <span>book_words</span> <span>%>%</span>
        <span>bind_tf_idf</span><span>(</span><span>word</span><span>,</span> <span>book</span><span>,</span> <span>n</span><span>)</span>
<span>book_words</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Source: local data frame [40,379 x 7]
## 
##                 book  word     n  total         tf   idf tf_idf
##               &lt;fctr> &lt;chr> &lt;int>  &lt;int>      &lt;dbl> &lt;dbl>  &lt;dbl>
## 1     Mansfield Park   the  6206 160460 0.03867631     0      0
## 2     Mansfield Park    to  5475 160460 0.03412065     0      0
## 3     Mansfield Park   and  5438 160460 0.03389007     0      0
## 4               Emma    to  5239 160996 0.03254118     0      0
## 5               Emma   the  5201 160996 0.03230515     0      0
## 6               Emma   and  4896 160996 0.03041069     0      0
## 7     Mansfield Park    of  4778 160460 0.02977689     0      0
## 8  Pride &amp; Prejudice   the  4331 122204 0.03544074     0      0
## 9               Emma    of  4291 160996 0.02665284     0      0
## 10 Pride &amp; Prejudice    to  4162 122204 0.03405780     0      0
## ..               ...   ...   ...    ...        ...   ...    ...</code></pre>
</figure>
<p>Notice that idf and thus tf-idf are zero for these extremely common words. These are all words that appear in all six of Jane Austen’s novels, so the idf term (which will then be the natural log of 1) is zero. The inverse document frequency (and thus tf-idf) is very low (near zero) for words that occur in many of the documents in a collection; this is how this approach decreases the weight for common words. The inverse document frequency will be a higher number for words that occur in fewer of the documents in the collection. Let’s look at terms with high tf-idf in Jane Austen’s works.</p>
<figure>
<pre><code data-lang="r"><span>book_words</span> <span>%>%</span>
        <span>select</span><span>(</span><span>-</span><span>total</span><span>)</span> <span>%>%</span>
        <span>arrange</span><span>(</span><span>desc</span><span>(</span><span>tf_idf</span><span>))</span> </code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Source: local data frame [40,379 x 6]
## 
##                   book      word     n          tf      idf      tf_idf
##                 &lt;fctr>     &lt;chr> &lt;int>       &lt;dbl>    &lt;dbl>       &lt;dbl>
## 1  Sense &amp; Sensibility    elinor   623 0.005193528 1.791759 0.009305552
## 2  Sense &amp; Sensibility  marianne   492 0.004101470 1.791759 0.007348847
## 3       Mansfield Park  crawford   493 0.003072417 1.791759 0.005505032
## 4    Pride &amp; Prejudice     darcy   373 0.003052273 1.791759 0.005468939
## 5           Persuasion    elliot   254 0.003036207 1.791759 0.005440153
## 6                 Emma      emma   786 0.004882109 1.098612 0.005363545
## 7     Northanger Abbey    tilney   196 0.002519928 1.791759 0.004515105
## 8                 Emma    weston   389 0.002416209 1.791759 0.004329266
## 9    Pride &amp; Prejudice    bennet   294 0.002405813 1.791759 0.004310639
## 10          Persuasion wentworth   191 0.002283132 1.791759 0.004090824
## ..                 ...       ...   ...         ...      ...         ...</code></pre>
</figure>
<p>Here we see all proper nouns, names that are in fact important in these novels. None of them occur in all of novels, and they are important, characteristic words for each text. Some of the values for idf are the same for different terms because there are 6 documents in this corpus and we are seeing the numerical value for ln(6/1), ln(6/2), etc. Let’s look at a visualization for these high tf-idf words.</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>ggstance</span><span>)</span>
<span>library</span><span>(</span><span>ggthemes</span><span>)</span>
<span>plot_austen</span> <span>&lt;-</span> <span>book_words</span> <span>%>%</span>
        <span>arrange</span><span>(</span><span>desc</span><span>(</span><span>tf_idf</span><span>))</span> <span>%>%</span>
        <span>mutate</span><span>(</span><span>word</span> <span>=</span> <span>factor</span><span>(</span><span>word</span><span>,</span> <span>levels</span> <span>=</span> <span>rev</span><span>(</span><span>unique</span><span>(</span><span>word</span><span>))))</span>
<span>ggplot</span><span>(</span><span>plot_austen</span><span>[</span><span>1</span><span>:</span><span>20</span><span>,],</span> <span>aes</span><span>(</span><span>tf_idf</span><span>,</span> <span>word</span><span>,</span> <span>fill</span> <span>=</span> <span>book</span><span>,</span> <span>alpha</span> <span>=</span> <span>tf_idf</span><span>))</span> <span>+</span>
        <span>geom_barh</span><span>(</span><span>stat</span> <span>=</span> <span>&quot;identity&quot;</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Highest tf-idf words in Jane Austen's Novels&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>NULL</span><span>,</span> <span>x</span> <span>=</span> <span>&quot;tf-idf&quot;</span><span>)</span> <span>+</span>
        <span>theme_tufte</span><span>(</span><span>base_family</span> <span>=</span> <span>&quot;Arial&quot;</span><span>,</span> <span>base_size</span> <span>=</span> <span>13</span><span>,</span> <span>ticks</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_alpha_continuous</span><span>(</span><span>range</span> <span>=</span> <span>c</span><span>(</span><span>0.6</span><span>,</span> <span>1</span><span>),</span> <span>guide</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_x_continuous</span><span>(</span><span>expand</span><span>=</span><span>c</span><span>(</span><span>0</span><span>,</span><span>0</span><span>))</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.85</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>legend.title</span><span>=</span><span>element_blank</span><span>())</span> <span>+</span>
        <span>theme</span><span>(</span><span>legend.justification</span><span>=</span><span>c</span><span>(</span><span>1</span><span>,</span><span>0</span><span>),</span> <span>legend.position</span><span>=</span><span>c</span><span>(</span><span>1</span><span>,</span><span>0</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i0.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-6-1.png?w=456" data-recalc-dims="1"></p>
<p>Let’s look at the novels individually.</p>
<figure>
<pre><code data-lang="r"><span>plot_austen</span> <span>&lt;-</span> <span>plot_austen</span> <span>%>%</span> <span>group_by</span><span>(</span><span>book</span><span>)</span> <span>%>%</span> <span>top_n</span><span>(</span><span>15</span><span>)</span> <span>%>%</span> <span>ungroup</span>
<span>ggplot</span><span>(</span><span>plot_austen</span><span>,</span> <span>aes</span><span>(</span><span>tf_idf</span><span>,</span> <span>word</span><span>,</span> <span>fill</span> <span>=</span> <span>book</span><span>,</span> <span>alpha</span> <span>=</span> <span>tf_idf</span><span>))</span> <span>+</span>
        <span>geom_barh</span><span>(</span><span>stat</span> <span>=</span> <span>&quot;identity&quot;</span><span>,</span> <span>show.legend</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Highest tf-idf words in Jane Austen's Novels&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>NULL</span><span>,</span> <span>x</span> <span>=</span> <span>&quot;tf-idf&quot;</span><span>)</span> <span>+</span>
        <span>facet_wrap</span><span>(</span><span>~</span><span>book</span><span>,</span> <span>ncol</span> <span>=</span> <span>2</span><span>,</span> <span>scales</span> <span>=</span> <span>&quot;free&quot;</span><span>)</span> <span>+</span>
        <span>theme_tufte</span><span>(</span><span>base_family</span> <span>=</span> <span>&quot;Arial&quot;</span><span>,</span> <span>base_size</span> <span>=</span> <span>13</span><span>,</span> <span>ticks</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_alpha_continuous</span><span>(</span><span>range</span> <span>=</span> <span>c</span><span>(</span><span>0.6</span><span>,</span> <span>1</span><span>))</span> <span>+</span>
        <span>scale_x_continuous</span><span>(</span><span>expand</span><span>=</span><span>c</span><span>(</span><span>0</span><span>,</span><span>0</span><span>))</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.85</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span><span>=</span><span>element_text</span><span>(</span><span>hjust</span><span>=</span><span>0</span><span>))</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span> <span>=</span> <span>element_text</span><span>(</span><span>face</span> <span>=</span> <span>&quot;italic&quot;</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i1.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-7-1.png?w=456" data-recalc-dims="1"></p>
<p>Still all proper nouns! These words are, as measured by tf-idf, the most important to each novel and most readers would likely agree.</p>
<p><iframe height="204" width="480" allowfullscreen src="http://giphy.com/embed/y5dASMYqZwS2s"></iframe></p>
<p><a target="_blank" href="http://giphy.com/gifs/vintage-pale-colin-firth-y5dASMYqZwS2s">via GIPHY</a></p>
<h2>A Different Corpus</h2>
<p>Let’s work with another corpus of documents, to see what terms are important in a different set of works. In fact, let’s leave the world of fiction and narrative entirely. My background is in physics, so let’s download some classic physics texts from Project Gutenberg and see what terms are important in these works, as measured by tf-idf. Let’s download <a target="_blank" href="http://www.gutenberg.org/ebooks/37729"><em>Discourse on Floating Bodies</em> by Galileo Galilei</a>, <a target="_blank" href="http://www.gutenberg.org/ebooks/14725"><em>Treatise on Light</em> by Christiaan Huygens</a>, <a target="_blank" href="http://www.gutenberg.org/ebooks/13476"><em>Experiments with Alternate Currents of High Potential and High Frequency</em> by Nikola Tesla</a>, and <a target="_blank" href="http://www.gutenberg.org/ebooks/5001"><em>Relativity: The Special and General Theory</em> by Albert Einstein</a>.</p>
<p>This is a pretty diverse bunch. They may all be physics classics, but they were written across a 300-year timespan, and some of them were first written in other languages and then translated to English. Perfectly homogeneous these are not, but that doesn’t stop this from being an interesting exercise!</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>gutenbergr</span><span>)</span>
<span>physics</span> <span>&lt;-</span> <span>gutenberg_download</span><span>(</span><span>c</span><span>(</span><span>37729</span><span>,</span> <span>14725</span><span>,</span> <span>13476</span><span>,</span> <span>5001</span><span>),</span> 
                              <span>meta_fields</span> <span>=</span> <span>&quot;author&quot;</span><span>)</span>
<span>physics_words</span> <span>&lt;-</span> <span>physics</span> <span>%>%</span>
        <span>unnest_tokens</span><span>(</span><span>word</span><span>,</span> <span>text</span><span>)</span> <span>%>%</span>
        <span>count</span><span>(</span><span>author</span><span>,</span> <span>word</span><span>,</span> <span>sort</span> <span>=</span> <span>TRUE</span><span>)</span> <span>%>%</span>
        <span>ungroup</span><span>()</span>
<span>physics_words</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## Source: local data frame [12,592 x 3]
## 
##                 author  word     n
##                  &lt;chr> &lt;chr> &lt;int>
## 1     Galilei, Galileo   the  3760
## 2        Tesla, Nikola   the  3604
## 3  Huygens, Christiaan   the  3553
## 4     Einstein, Albert   the  2994
## 5     Galilei, Galileo    of  2049
## 6     Einstein, Albert    of  2030
## 7        Tesla, Nikola    of  1737
## 8  Huygens, Christiaan    of  1708
## 9  Huygens, Christiaan    to  1207
## 10       Tesla, Nikola     a  1176
## ..                 ...   ...   ...</code></pre>
</figure>
<p>Here we see just the raw counts, and of course these documents are all very different lengths. Let’s go ahead and calculate tf-idf.</p>
<figure>
<pre><code data-lang="r"><span>physics_words</span> <span>&lt;-</span> <span>physics_words</span> <span>%>%</span>
        <span>bind_tf_idf</span><span>(</span><span>word</span><span>,</span> <span>author</span><span>,</span> <span>n</span><span>)</span> 
<span>plot_physics</span> <span>&lt;-</span> <span>physics_words</span> <span>%>%</span>
        <span>arrange</span><span>(</span><span>desc</span><span>(</span><span>tf_idf</span><span>))</span> <span>%>%</span>
        <span>mutate</span><span>(</span><span>word</span> <span>=</span> <span>factor</span><span>(</span><span>word</span><span>,</span> <span>levels</span> <span>=</span> <span>rev</span><span>(</span><span>unique</span><span>(</span><span>word</span><span>))))</span> <span>%>%</span>
        <span>mutate</span><span>(</span><span>author</span> <span>=</span> <span>factor</span><span>(</span><span>author</span><span>,</span> <span>levels</span> <span>=</span> <span>c</span><span>(</span><span>&quot;Galilei, Galileo&quot;</span><span>,</span>
                                                  <span>&quot;Huygens, Christiaan&quot;</span><span>,</span>
                                                  <span>&quot;Tesla, Nikola&quot;</span><span>,</span>
                                                  <span>&quot;Einstein, Albert&quot;</span><span>)))</span>

<span>ggplot</span><span>(</span><span>plot_physics</span><span>[</span><span>1</span><span>:</span><span>20</span><span>,],</span> <span>aes</span><span>(</span><span>tf_idf</span><span>,</span> <span>word</span><span>,</span> <span>fill</span> <span>=</span> <span>author</span><span>,</span> <span>alpha</span> <span>=</span> <span>tf_idf</span><span>))</span> <span>+</span>
        <span>geom_barh</span><span>(</span><span>stat</span> <span>=</span> <span>&quot;identity&quot;</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Highest tf-idf words in Classic Physics Texts&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>NULL</span><span>,</span> <span>x</span> <span>=</span> <span>&quot;tf-idf&quot;</span><span>)</span> <span>+</span>
        <span>theme_tufte</span><span>(</span><span>base_family</span> <span>=</span> <span>&quot;Arial&quot;</span><span>,</span> <span>base_size</span> <span>=</span> <span>13</span><span>,</span> <span>ticks</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_alpha_continuous</span><span>(</span><span>range</span> <span>=</span> <span>c</span><span>(</span><span>0.6</span><span>,</span> <span>1</span><span>),</span> <span>guide</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_x_continuous</span><span>(</span><span>expand</span><span>=</span><span>c</span><span>(</span><span>0</span><span>,</span><span>0</span><span>))</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.6</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>legend.title</span><span>=</span><span>element_blank</span><span>())</span> <span>+</span>
        <span>theme</span><span>(</span><span>legend.justification</span><span>=</span><span>c</span><span>(</span><span>1</span><span>,</span><span>0</span><span>),</span> <span>legend.position</span><span>=</span><span>c</span><span>(</span><span>1</span><span>,</span><span>0</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i2.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-9-1.png?w=456" data-recalc-dims="1"></p>
<p>Nice! Let’s look at each text individually.</p>
<figure>
<pre><code data-lang="r"><span>plot_physics</span> <span>&lt;-</span> <span>plot_physics</span> <span>%>%</span> <span>group_by</span><span>(</span><span>author</span><span>)</span> <span>%>%</span> 
        <span>top_n</span><span>(</span><span>15</span><span>,</span> <span>tf_idf</span><span>)</span> <span>%>%</span> 
        <span>mutate</span><span>(</span><span>word</span> <span>=</span> <span>reorder</span><span>(</span><span>word</span><span>,</span> <span>tf_idf</span><span>))</span>
<span>ggplot</span><span>(</span><span>plot_physics</span><span>,</span> <span>aes</span><span>(</span><span>tf_idf</span><span>,</span> <span>word</span><span>,</span> <span>fill</span> <span>=</span> <span>author</span><span>,</span> <span>alpha</span> <span>=</span> <span>tf_idf</span><span>))</span> <span>+</span>
        <span>geom_barh</span><span>(</span><span>stat</span> <span>=</span> <span>&quot;identity&quot;</span><span>,</span> <span>show.legend</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Highest tf-idf words in Classic Physics Texts&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>NULL</span><span>,</span> <span>x</span> <span>=</span> <span>&quot;tf-idf&quot;</span><span>)</span> <span>+</span>
        <span>facet_wrap</span><span>(</span><span>~</span><span>author</span><span>,</span> <span>ncol</span> <span>=</span> <span>2</span><span>,</span> <span>scales</span> <span>=</span> <span>&quot;free&quot;</span><span>)</span> <span>+</span>
        <span>theme_tufte</span><span>(</span><span>base_family</span> <span>=</span> <span>&quot;Arial&quot;</span><span>,</span> <span>base_size</span> <span>=</span> <span>13</span><span>,</span> <span>ticks</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_alpha_continuous</span><span>(</span><span>range</span> <span>=</span> <span>c</span><span>(</span><span>0.6</span><span>,</span> <span>1</span><span>))</span> <span>+</span>
        <span>scale_x_continuous</span><span>(</span><span>expand</span><span>=</span><span>c</span><span>(</span><span>0</span><span>,</span><span>0</span><span>))</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.6</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span><span>=</span><span>element_text</span><span>(</span><span>hjust</span><span>=</span><span>0</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i1.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-10-1.png?w=456" data-recalc-dims="1"></p>
<p>Very interesting indeed. One thing I saw here that I wanted to understand was what was going on with “gif” in the Einstein text?!</p>
<figure>
<pre><code data-lang="r"><span>grep</span><span>(</span><span>&quot;gif&quot;</span><span>,</span> <span>physics</span><span>$</span><span>text</span><span>,</span> <span>value</span> <span>=</span> <span>TRUE</span><span>)[</span><span>1</span><span>:</span><span>10</span><span>]</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##  [1] &quot;                       Fig. 01: file fig01.gif&quot;
##  [2] &quot;                         eq. 1: file eq01.gif&quot; 
##  [3] &quot;                         eq. 2: file eq02.gif&quot; 
##  [4] &quot;                         eq. 3: file eq03.gif&quot; 
##  [5] &quot;                         eq. 4: file eq04.gif&quot; 
##  [6] &quot;                       eq. 05a: file eq05a.gif&quot;
##  [7] &quot;                       eq. 05b: file eq05b.gif&quot;
##  [8] &quot;                        eq. 07: file eq07.gif&quot; 
##  [9] &quot;                        eq. 08: file eq08.gif&quot; 
## [10] &quot;                        eq. 09: file eq09.gif&quot;</code></pre>
</figure>
<p>Some cleaning up of the text might be in order. The same thing is true for “eq”, obviously here. “K1” is the name of a coordinate system for Einstein:</p>
<figure>
<pre><code data-lang="r"><span>grep</span><span>(</span><span>&quot;K1&quot;</span><span>,</span> <span>physics</span><span>$</span><span>text</span><span>,</span> <span>value</span> <span>=</span> <span>TRUE</span><span>)[</span><span>1</span><span>]</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] &quot;to a second co-ordinate system K1 provided that the latter is&quot;</code></pre>
</figure>
<p>Also notice that in this line we have “co-ordinate”, which explains why there are separate “co” and “ordinate” items in the high tf-idf words for the Einstein text. “AB”, “RC”, and so forth are names of rays, circles, angles, and so forth for Huygens.</p>
<figure>
<pre><code data-lang="r"><span>grep</span><span>(</span><span>&quot;AK&quot;</span><span>,</span> <span>physics</span><span>$</span><span>text</span><span>,</span> <span>value</span> <span>=</span> <span>TRUE</span><span>)[</span><span>1</span><span>]</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## [1] &quot;Now let us assume that the ray has come from A to C along AK, KC; the&quot;</code></pre>
</figure>
<p>Let’s remove some of these less meaningful words to make a better plot to end on.</p>
<figure>
<pre><code data-lang="r"><span>mystopwords</span> <span>&lt;-</span> <span>data_frame</span><span>(</span><span>word</span> <span>=</span> <span>c</span><span>(</span><span>&quot;gif&quot;</span><span>,</span> <span>&quot;eq&quot;</span><span>,</span> <span>&quot;co&quot;</span><span>,</span> <span>&quot;rc&quot;</span><span>,</span> <span>&quot;ac&quot;</span><span>,</span> <span>&quot;ak&quot;</span><span>,</span> <span>&quot;bn&quot;</span><span>,</span> 
                                   <span>&quot;fig&quot;</span><span>,</span> <span>&quot;file&quot;</span><span>,</span> <span>&quot;cg&quot;</span><span>,</span> <span>&quot;cb&quot;</span><span>))</span>
<span>physics_words</span> <span>&lt;-</span> <span>anti_join</span><span>(</span><span>physics_words</span><span>,</span> <span>mystopwords</span><span>,</span> <span>by</span> <span>=</span> <span>&quot;word&quot;</span><span>)</span>
<span>plot_physics</span> <span>&lt;-</span> <span>physics_words</span> <span>%>%</span>
        <span>arrange</span><span>(</span><span>desc</span><span>(</span><span>tf_idf</span><span>))</span> <span>%>%</span>
        <span>mutate</span><span>(</span><span>word</span> <span>=</span> <span>factor</span><span>(</span><span>word</span><span>,</span> <span>levels</span> <span>=</span> <span>rev</span><span>(</span><span>unique</span><span>(</span><span>word</span><span>))))</span> <span>%>%</span>
        <span>group_by</span><span>(</span><span>author</span><span>)</span> <span>%>%</span> 
        <span>top_n</span><span>(</span><span>15</span><span>,</span> <span>tf_idf</span><span>)</span> <span>%>%</span>
        <span>ungroup</span> <span>%>%</span>
        <span>mutate</span><span>(</span><span>author</span> <span>=</span> <span>factor</span><span>(</span><span>author</span><span>,</span> <span>levels</span> <span>=</span> <span>c</span><span>(</span><span>&quot;Galilei, Galileo&quot;</span><span>,</span>
                                                  <span>&quot;Huygens, Christiaan&quot;</span><span>,</span>
                                                  <span>&quot;Tesla, Nikola&quot;</span><span>,</span>
                                                  <span>&quot;Einstein, Albert&quot;</span><span>)))</span>

<span>ggplot</span><span>(</span><span>plot_physics</span><span>,</span> <span>aes</span><span>(</span><span>tf_idf</span><span>,</span> <span>word</span><span>,</span> <span>fill</span> <span>=</span> <span>author</span><span>,</span> <span>alpha</span> <span>=</span> <span>tf_idf</span><span>))</span> <span>+</span>
        <span>geom_barh</span><span>(</span><span>stat</span> <span>=</span> <span>&quot;identity&quot;</span><span>,</span> <span>show.legend</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>labs</span><span>(</span><span>title</span> <span>=</span> <span>&quot;Highest tf-idf words in Classic Physics Texts&quot;</span><span>,</span>
             <span>y</span> <span>=</span> <span>NULL</span><span>,</span> <span>x</span> <span>=</span> <span>&quot;tf-idf&quot;</span><span>)</span> <span>+</span>
        <span>facet_wrap</span><span>(</span><span>~</span><span>author</span><span>,</span> <span>ncol</span> <span>=</span> <span>2</span><span>,</span> <span>scales</span> <span>=</span> <span>&quot;free&quot;</span><span>)</span> <span>+</span>
        <span>theme_tufte</span><span>(</span><span>base_family</span> <span>=</span> <span>&quot;Arial&quot;</span><span>,</span> <span>base_size</span> <span>=</span> <span>13</span><span>,</span> <span>ticks</span> <span>=</span> <span>FALSE</span><span>)</span> <span>+</span>
        <span>scale_alpha_continuous</span><span>(</span><span>range</span> <span>=</span> <span>c</span><span>(</span><span>0.6</span><span>,</span> <span>1</span><span>))</span> <span>+</span>
        <span>scale_x_continuous</span><span>(</span><span>expand</span><span>=</span><span>c</span><span>(</span><span>0</span><span>,</span><span>0</span><span>))</span> <span>+</span>
        <span>scale_fill_viridis</span><span>(</span><span>end</span> <span>=</span> <span>0.6</span><span>,</span> <span>discrete</span><span>=</span><span>TRUE</span><span>)</span> <span>+</span>
        <span>theme</span><span>(</span><span>strip.text</span><span>=</span><span>element_text</span><span>(</span><span>hjust</span><span>=</span><span>0</span><span>))</span></code></pre>
</figure>
<p><img alt="center" src="http://i2.wp.com/juliasilge.com/figs/2016-06-27-Term-Frequency-tf-idf/unnamed-chunk-14-1.png?w=456" data-recalc-dims="1"></p>
<p>I feel like we don’t hear enough about ramparts or things being ethereal in physics today.</p>
<h2>The End</h2>
<p>Other notable new functionality in tidytext 0.1.1 includes the ability to tidy LDA objects and approach topic modeling using tidy data principles; check out the <a target="_blank" href="https://cran.r-project.org/web/packages/tidytext/vignettes/topic_modeling.html">topic modeling vignette</a> that is included in the new release for a sad tale of a vandal breaking into a library and tearing apart books. The R Markdown file used to make this blog post is available <a target="_blank" href="https://github.com/juliasilge/juliasilge.github.io/blob/master/_R/2016-06-27-Term-Frequency-tf-idf.Rmd">here</a>. I am very happy to hear feedback or questions!</p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/"></div></div><div><a data-url="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/" data-counturl="http://www.r-bloggers.com/term-frequency-and-tf-idf-using-tidy-data-principles/" data-count="vertical" data-text="Term Frequency and tf-idf Using Tidy Data Principles" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://juliasilge.com/blog/Term-Frequency-tf-idf/"> data science ish</a></strong>.</div>
<hr>
<a rel="nofollow" href="http://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="http://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="http://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="http://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="http://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="http://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="http://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="http://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="http://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="http://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="http://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="http://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="http://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="http://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="http://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="http://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="http://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="http://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="http://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/Cr5nYBoy78g"></a></div>