Loudness in the Novel

AP Research CT [Arts]
​
JulianJacklin
Computational Thinking (CT) modules bridge the gap between students' emerging proficiency in subject-area content, and the their ability to use computers to address complex problems in any field. Computational thinking consists of sets of skill we may use to approach complex problems in a concise, systematic, and reproducible way. Many of these skills are found in computer science: breaking-down a problem into digestible parts, recognizing patterns, filtering out unnecessary information or prioritizing essential data, and designing a set of steps or rules to approach a solution are all skills one cultivates when working with computers; hence, computational thinking. However, this type of problem-solving can be applied to meet challenges of almost any kind. ​
​​
​In this module, you will be discovering trends in the voice and sound of a novel, as discussed in this module's primary document: Loudness in the Novel (Katsma, 2014). Research in the literary arts is a broad group of studies aimed at better understanding human expression and societal, historical structures through written work. Some questions in literary analysis and historical linguistics are too complex or infeasible for a single human or group of humans to figure out on their own. This is where computers—but more crucially, computational thinking—play a role. Throughout the course of this module, you will choose a research subject, calculate metrics from text data, visualize structural pacing, and communicate your findings using evidence from the study.​
​​
​This Computational Thinking module is intended for integration into the AP Research course.
​

Research Question

Background

How might we measure narrative loudness—or how loudly characters are perceived as speaking—in a novel? This is the central question that Katsma (2014) asks in his paper, Loudness in the Novel, and is what will guide much of the work in this module. Instead of choosing a research question, you will choose a subject of study (a text), and follow Katsma's methods to understand the following: ​
​​
​To what extent does the narrative loudness and pacing contour of [TEXT 1] differ from [TEXT 2]?​
​​
​Choose two texts from the following list:​
​​
​ - Alice in Wonderland, by Lewis Carroll​
​ - Dracula, by Bram Stoker​
​ - Hamlet, by William Shakespeare​
​ - Moby Dick, by Herman Melville​
​ - Oedipus the King, by Sophocles​
​ - Oliver Twist, by Charles Dickens​
​ - The Adventures of Huckleberry Finn, by Mark Twain​
​ - The Adventures of Sherlock Holmes, by Arthur Conan Doyle​
​ - The Invisible Man, by H.G. Wells​
​ - The Jungle, by Upton Sinclair​
​ - The Phantom of the Opera, by Gaston Leroux​
​ - The Wonderful Wizard of Oz, by Frank Baum​
​ - Through the Looking Glass, by Lewis Carroll​
​ - Ulysses, by James Joyce

My Question:

Data Collection

Methodology

Unlike other research papers you may have examined, Loudness in the Novel (2014), employs neither an experimental nor observational study. Instead, discoveries are made in the analysis of text. To start, what are the two methods Katsma uses to measure narrative loudness in a text. ​
​​
​​
​After you have identified the two methods, use this excerpt from Pride and Prejudice (1813) to practice using them. What score does each method give to this piece of text? Run the following line of code to view the excerpt.​
​
In[]:=
StringRiffle[TextCases[ResourceData["Pride and Prejudice"],"Paragraph"][[{1110,1113}]]]

Import

To work with our data, we need to first import it into our environment—meaning, we just need to have it on our screen, to be able to work with it. For our purposes, this data will be imported from the Wolfram Data Repository—meaning we have immediate access to it. Use the code below with the titles of your chosen novels to load them in. The titles should be capitalized and spaced as they are in the list above.​
​
In[]:=
text1:=ResourceData["Text1"]​​text2:=ResourceData["Text2"]
To test if you've imported correctly, run the following:​
​
TextCases[text1,"Paragraph"][[25]]​​TextCases[text2,"Paragraph"][[25]]
If you imported correctly, you'll see two excerpts, each from your chosen texts.

Data Visualization

Emulation

To communicate how loud a text is, it may be best practice to visualize these trends using technology. But first, we must compute loudness for a text in order to plot it. Fortunately, Katsma establishes two methods of doing so. To compute a loudness metric for any given text, let us begin by emulating (or copying) Katsma's first method.​
​

Method 1: Speaking Verbs

Speaking verbs are words that typically tell us when a character is speaking in a narrative, and how. Some examples include:​
​​
​ - "I didn't want to go to the park, anyway," she said. ​
​ - He cried after his love, "I will never forgive you!"​
​ - The prince whispered to his council.​
​ - They all gasped and exclaimed: "The killer!"​
​ ​
​ Katsma proposes that by counting the number of speaking verbs in a text, we can measure that text's loudness. Modify the code below to meet this aim:​
​
In[]:=
naiveLoudnessScore[chapter_String]:=​​Module[{neutralVerbs,resonantVerbs,medLoudVerbs,loudVerbs,veryLoudVerbs},​​​​neutralVerbs={"said","replied","observed","rejoined","asked","answered","returned","repeated","remarked","enquired","responded"};​​​​resonantVerbs={"picked up","warmly approved","added","continued","began","started"};​​​​medLoudVerbs={"retorted","interrupted","said sternly","objected","protested","declared","announced"};​​​​loudVerbs={"said loudly","interrupted hotly","called","bawled","vociferated","proclaimed"};​​​​veryLoudVerbs={"shouted","screamed","exclaimed","cried","roared","shrieked"};​​​​verbs={neutralVerbs,resonantVerbs,medLoudVerbs,loudVerbs,veryLoudVerbs};​​​​Sum[Total[StringCount[ToLowerCase[chapter],verbs[[i]]]]*(i-1),{i,5}]​​​​]​​
Now, let's test this function on the except from earlier that we scored ourselves. Run the following line of code to view the excerpt’s loudness score. The higher the score, the louder the narrative. Does it differ from the one you came up with for method 1? Why might this be if so?
naiveLoudnessScore[StringRiffle[TextCases[ResourceData["Pride and Prejudice"],"Paragraph"][[{1110,1113}]]]]
​

Method 2: Grammatical Intensity

Crucially, Katsma argues that rather than simply count speaking verbs, one might gain a better idea of loudness in a novel by measuring the grammar of a scene. He sections his thinking into three to four main structures, which have been partially implemented in the code below. You need not modify anything here— just run the cell.​
​
In[]:=
advLoudnessScore[sentence_String]:=Module[{loudWords,lowerSentence,structure1,structure2,structure3,puncCount,wordCount},​​​​lowerSentence=ToLowerCase[sentence];​​​​structure1=StringCount[lowerSentence,WordCharacter..~~" me"];​​​​structure2=If[StringContainsQ[sentence,"?"]&&StringContainsQ[lowerSentence,{"what","why","how"}],1,0];​​​​​​puncCount=StringCount[sentence,{"!","—","--"}];​​wordCount=StringCount[lowerSentence,{"oh","dear","god","heaven"}];​​structure3=puncCount+wordCount;​​​​structure1+structure2+structure3​​​​]
In your own words, what is this function doing? Or, what are we trying to tell the computer to do?​
​​
​​
​Now, run the code below to compute our new loudness score for the same Pride and Prejudice excerpt. Again, the higher the score, the louder the narrative.
advLoudnessScore[StringRiffle[TextCases[ResourceData["Pride and Prejudice"],"Paragraph"][[{1110,1113}]]]]
​
Does this result differ from the one you came up with for method 2? Why might this be if so?

Graphing

Now that we have a way to compute loudness, lets create some visualizations. Notice that Katsma computes loudness for each sentence, then calculates what is called the moving average over all of the sentences in the novel. The moving average is like your typical average, except it allows us to more clearly see trends over time. Fortunately, we can just use the MovingAverage function in Wolfram Language for this step. ​
​​
​And that's it! Run the following lines of code to visualize.​
​
sentences1=TextSentences[text1];​​sentences2=TextSentences[text2];​​​​ListLinePlot[MovingAverage[advLoudnessScore/@sentences1,40],ColorFunction"",​​FillingBottom,​​FillingStyleDirective[Opacity[0.1]],​​PlotStyleDirective[Thickness[0.004]],​​PlotTheme"Minimal",​​GridLinesAutomatic,​​Epilog{Text[Style["↑ Start of Novel",10,Bold,Black],{-0.15,-0.15},{-1,-1}],Text[Style["End of Novel ↓",10,Bold,Black],{1.25,1.25},{-10.2,-1}]},PlotRangeClippingFalse,​​PlotLabelColumn[{Spacer[{0,10}],Style["Narrative Loudness & Pacing Contour\n in TEXT 1",16,Bold,Black]},AlignmentCenter],AxesTrue,AxesStyleDirective[Black,Thickness[0.001]],TicksStyleDirective[Black,10],AxesLabel{Style["Narrative Timeline",11,Italic,Black],Style["Grammatical Intensity\n(Loudness)",11,Italic,Black]},AspectRatio1/3,ImageSizeLarge,BackgroundWhite,ImagePadding{{60,110},{30,45}}]​​​​ListLinePlot[MovingAverage[advLoudnessScore/@sentences2,40],ColorFunction"",​​FillingBottom,​​FillingStyleDirective[Opacity[0.1]],​​PlotStyleDirective[Thickness[0.004]],​​PlotTheme"Minimal",​​GridLinesAutomatic,​​Epilog{Text[Style["↑ Start of Novel",10,Bold,Black],{-0.15,-0.15},{-1,-1}],Text[Style["End of Novel ↓",10,Bold,Black],{1.25,1.25},{-10.2,-1}]},PlotRangeClippingFalse,​​PlotLabelColumn[{Spacer[{0,10}],Style["Narrative Loudness & Pacing Contour\n in TEXT 2",16,Bold,Black]},AlignmentCenter],AxesTrue,AxesStyleDirective[Black,Thickness[0.001]],TicksStyleDirective[Black,10],AxesLabel{Style["Narrative Timeline",11,Italic,Black],Style["Grammatical Intensity\n(Loudness)",11,Italic,Black]},AspectRatio1/3,ImageSizeLarge,BackgroundWhite,ImagePadding{{60,110},{30,45}}]​​
And voilà! We have got our graphs. Now, choose one of two paths to make them even better:​
​​
​ (1) Edit at least three parts of each graph. This can be changing the name of the title, color of the line, etc. (Use ColorFunction to add even more color to your graph).​
​ ​
​ (2) Use the Show function to combine the graphs into one, and change the colors and/or type of the lines (dashed, dotted) to clearly distinguish which line belongs to which text. ​
​ ​
​ ​
​ ​
​ Hint! Every "something→something else" in the ListLinePlots above are options (like settings) that the plot can take. For instance, "Background→White" make's the plot's background white, and "PlotStyle→Directive[Thickness[0.004]]" controls the appearance of the line. In this case, our line has a thickness of 0.004, with no color or type specified. If I wanted to change the color of the line to red, I would simply add it after a comma: PlotStyle→Directive[Thickness[0.004], Red]​
​ ​
​

Trends

What trends or patterns seem to appear in your data? What might these say about your research question? Do your findings make sense to you intuitively?

Results

While it may seem that we are done with our analysis, we must still support our conclusions empirically, meaning with hard evidence—it is never enough to just look at a graph. Keep in mind that we would essentially like to understand which of our texts is louder. ​
​​
​One idea, may be to calculate the area under the curve of our lines. The code that does this is left below. Which text is louder by this standard?
​
​​
​Based on your work in this module and the graphs above, determine your own method for judging which text is louder. This does not have to be implemented.​
​​
​

Conclusion

Discussion

Given everything you have learned in this module, were you able to answer your research question? If you were able to, detail what empirical evidence you've collected that supports this claim(s). ​
​​
​If you were not able to adequately answer your research question, ask yourself: could I have answered my question using only the data provided? Was there something meaningful you learned about the topic regardless? ​
​

Next Steps

How would you expand on the work of these researchers? Is there a different sample you would consider? A different research focus? Would you change how the research was conducted. Discuss this below.