Loudness in the Novel [TEACHER NB]

AP Research CT [Arts]
​
JulianJacklin
In this lesson, students learn to apply computational thinking to digital humanities and literary data using computational literature pipelines. Aligned with the AP Research QUEST Framework, students will practice generating aligned research questions, evaluating data types, analyzing data distributions, and interpreting empirical results through text mining and narrative architecture modeling.​
​​
​Lesson Overview​
​​
​ - Warm-up: Research Question (10 minutes)​
​ - Activity 1: Data Collection (5 minutes)​
​ - Activity 2: Data Visualization (15 minutes)​
​ - Activity 3: Results (15 minutes)​
​ - Cool-down: Next Steps & Limitations (15 minutes)​
​​
​Teacher-Facing Goals​
​​
​ - Question and Explore (LO 1.1A): Formulate a specific, feasible, and discipline-aligned digital humanities research question using available text and narrative variables.​
​​
​ - Synthesize Ideas (LO 4.2A): Interpret and synthesize quantitative data outputs (moving average windows and linguistic feature extraction) to develop and support an empirical argument regarding narrative form and pacing.​
​​
​Student-Facing Goal​
​​
​Let's use programming code and statistical models to answer our own digital humanities research questions about narrative architecture and structural tension in literature.​
​​
​Learning Target​
​​
​I can design a specific digital humanities research question, choose the best data visualization to show narrative trends, and use data smoothing models (like moving average contours and timeline gradients) to prove my empirical conclusion.​
​​
​Required Materials​
​​
​ - Internet-enabled device.​
​ - Wolfram Language environment (cloud or desktop).​
​
​

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 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​
​ ​
​ ​
​ [TEACHER FACING]​
​​
​By this point, student's should have already read and analyzed the research paper associated with this module. Methods of instruction for that activity are left to the discretion of the educator, as completion of the critical majority of this module does not rely on the primary document. Every module in the AP Research CT series uses its primary document as a backdrop for conducting computational work with real-world applications. The accompaniment of the primary document also allows AP Research instructors to simultaneously satisfy more traditional curricular goals, such as reading and analyzing research papers. ​
​​
​As for creating a question, students should stay firmly to the research question frame above. The two novels they choose don't have to be explicitly related, but it could make sense for students to choose books they are at least vaguely familiar with. ​
​​
​EX: "To what extent does the narrative loudness of Alice in Wonderland differ from Through the Looking Glass?"​
​

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}]]]
[TEACHER FACING]​
​​
​Students should identify that, broadly, Katsma's first method was to count speaking verbs in a text, and his second method was to count grammatical structures indicative of loudness (exclamation marks, "-me" statements, interrogatives, imperatives). The key takeaway here is the notion of robustness. That, if we want to measure loudness in a novel, we must consider increasingly more accurate and precise ways of doing so. For instance, counting speaking verbs might work well in most cases, but one of Katsma's central arguments is that focusing on grammatical intensity works well in just as many cases, if not more. If we are trying to model or estimate something in research, we are often trying to find the most robust way of doing so. ​
​​
​Student answers for the second question will vary dependent upon their criteria for each method. It might be helpful to have student refer directly to the research paper, where loud speaking verbs and grammatical indicators are explicitly provided. This is meant to get students familiar with the research methodology used, and to discover later in this module how computation can make scoring processes like these more efficient. ​
​​
​By running the line of code above, they should get the expert below. Ensure that student do NOT alter the code. It should be ran as is. And for context, this passage in Pride and Prejudice is considered to be quite loud, as it captures Elizabeth's rejection of Mr. Darcy's first proposal—so students should be getting scores above 0 for each method. ​
​
In[]:=
StringRiffle[TextCases[ResourceData["Pride and Prejudice"],"Paragraph"][[{1110,1113}]]]
Out[]=
"Who that knows what his misfortunes have been, can help feeling aninterest in him?" "And this," cried Darcy, as he walked with quick steps across the room,"is your opinion of me! This is the estimation in which you hold me! Ithank you for explaining it so fully. My faults, according to thiscalculation, are heavy indeed! But perhaps," added he, stopping in hiswalk, and turning towards her, "these offences might have beenoverlooked, had not your pride been hurt by my honest confession of thescruples that had long prevented my forming any serious design. Thesebitter accusations might have been suppressed, had I with greater policyconcealed my struggles, and flattered you into the belief of my beingimpelled by unqualified, unalloyed inclination; by reason, byreflection, by every thing. But disguise of every sort is my abhorrence.Nor am I ashamed of the feelings I related. They were natural and just.Could you expect me to rejoice in the inferiority of your connections?To congratulate myself on the hope of relations, whose condition in lifeis so decidedly beneath my own?"

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["TEXT 1"]​​text2:=ResourceData["TEXT 2"]
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.​
​​
​
[TEACHER FACING]​
​​
​Students should be inputting their first and second text as such:​
​
In[]:=
text1:=ResourceData["Alice in Wonderland"]​​text2:=ResourceData["Through the Looking Glass"]​​
Capitalization and spacing matter here. A common error is to accidentally delete something in the line while inputting, or not inputting between the quotes. The next two lines test if we've done this step correctly, and should produce mini excerpts from our first and second novel respectively. Students should NOT alter these lines at all.​
​
In[]:=
TextCases[text1,"Paragraph"][[25]]​​TextCases[text2,"Paragraph"][[25]]
Out[]=
She went on shedding gallons of tears, until there was a large pool all 'round her and reaching half down the hall.
Out[]=
The Queen gasped, and sat down: the rapid journey through the air hadquite taken away her breath and for a minute or two she could do nothingbut hug the little Lily in silence. As soon as she had recovered herbreath a little, she called out to the White King, who was sittingsulkily among the ashes, 'Mind the volcano!'

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={};​​​​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}]]]]
[TEACHER FACING]​
​​
​The task to be done here is identifying that within this chunk of code (a function) we are "telling the computer" what words count as neutral speaking verbs, medium loud speaking verbs, loud speaking verbs, etc. However, the list for very loud verbs is empty. It may take students some time to realize this, but feel free to direct them towards this, and to prompt them as such: "Based on the words in the medium loud and loud lists, which words do you think would tell us something very loud is happening?"​
​​
​IMPORTANT! Ensure that students have at least the words listed below. They can include more than these so long as they are of indeed very loud speaking verbs:​
​
In[]:=
veryLoudVerbs={"shouted","screamed","exclaimed","cried","roared","shrieked"}
So, the final code should look like this:
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}]​​​​]
Students should NOT alter anything else in the code. After running the next line of code, students should observe that they get a positive number as output, meaning the score we've attributed to that earlier passage of Pride and Prejudice. A higher score indicates a louder scene. This is what the code and output should look like. While scores may differ, they should generally lie within a reasonable range. ​
​

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 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.
Does this result differ from the one you came up with for method 2? Why might this be if so?​
​​
​​
​[TEACHER FACING]​
​​
​Students should NOT alter anything about the code in this subsection. Students should identify that the function is emulating Katsma's second method. Specifically, we are measuring loudness via his three structures:​
​​
​ (1) -Me Statements: ​
​ ​
​ structure1=StringCount[lowerSentence ,WordCharacter..~~" me"];​
​ ​
​ (2) - Interrogatives: ​
​ ​
​ structure2 If[StringContainsQ[sentence,"?"] && ​
​ StringContainsQ[lowerSentence,{"what","why","how"}],1,0];​
​ ​
​ (3) - Exclamations and punctuation: ​
​​
​puncCount=StringCount[sentence,{"!","—","--"}];​
​wordCount=StringCount[lowerSentence ,{"oh","dear","god","heaven"}];​
​structure3=puncCount+wordCount;​
​​
​Then, at the very end, we tally the scores by adding them together:​
​​
​structure1+structure2+structure3​
​​
​​
​For the second part, students should run the code without modification. They may notice that this score is different than the one they got by emulating the first method, and that that's intentional. We would like these methods to produce different results, because we truly believe one is better and more robust than the other. If both methods yielded the same results, then neither would have an advantage.

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.​
​
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]​
​ ​
​​
​​
​[TEACHER-FACING]​
​​
​By the end of this activity, student's graphs may vary widely in appearance. Ultimately though, they should be able to successfully interpret the dips or minimums in the graphs as moments of quiet, and peaks or maximums as moments of loudness. Here is an example below, where text 1 is "Alice in Wonderland", and text 2 is "Through the Looking Glass."​
​
Students who have shown a working proficiency or interest in Wolfram Language (or programming generally) should be directed to path 2, while the rest of the students should be directed to path 1.​
​​
​ (1) The aesthetics of a visualization can greatly contribute to its appeal and overall ability to communicate findings. Here are a few different changes students can make to better stylize their plots:​
​ ​
​ - Change the title: ​
​ ​
​ PlotLabel->​
​ Column[{Spacer[{0,10}],​
​ Style["Narrative Loudness & Pacing Contour\n in ALICE IN WONDERLAND",16,Bold,Black]},​
​ Alignment->Center]​
​ ​
​ - Change the background color of the plot: ​
​ ​
​ Background->Darker[Gray,0.6]​
​ ​
​ - Change the color of the line to a color gradient: ​
​ ​
​ ColorFunction->"TemperatureMap"​
​ ​
​ Here is what that code and graph would look like with these modifications (in addition to making all the text and lines white as to not disappear into the darker background):​
​
(2) The Show function is a technical yet elegant solution to an issue that may not be clear in the original graphs: what's is the scale? Our second graph seems to oscillate quite a bit, while the first is more level, but which demonstrates a greater loudness? To examine this, we can plot them on the same graph, as such:​
​​
​
Alice in Wonderland is represented by the red curve (PlotStyle->Directive[Thickness[0.004], Red]) and Through the Looking Glass is represented by the blue curve (PlotStyle->Directive[Thickness[0.004], Blue]).

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?
[TEACHER-FACING]​
​​
​Students' findings should vary, as should their graphs. Ultimately, trends will fall into three main buckets: (1) One text is clearly louder than the other over time, (2) A text either keeps a consistent volume over time, or varies at certain points (chapters, rising actions, etc), (3) It's hard to tell which text is louder based on the graph alone.​
​​
​No matter the response, in the following activity students will be able to support their intuition and observations with empirical evidence.

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.​
​​
​​
​​
​[TEACHER-FACING]​
​​
​The proposed method for determining which text is louder is meant to be an objectively robust one, taking tools from advanced mathematics, such as integration, normalization, and functional interpolation. However, if students have or are taking calculus, they may be familiar with the idea of finding the area under a curve, which is main idea of this method. Students are not expected to understand this method otherwise—after running the code, they should simply receive two scores, see which one is higher, and determine that the "louder" text. Here is an example using "Alice in Wonderland" and "Through the Looking Glass":​
​
Here, it seems that "Through the Looking Glass" is the louder text by this method. ​
​​
​Students should then determine their own methods for comparing loudness. These do not have to be sophisticated, and are just meant to have them grapple with the difficulty of comparing things that are inherently non-quantitative. Some ideas for students to think about:​
​​
​ - The text with the single highest peak is the louder text.​
​ Pro: Intuitive Con: Susceptible to outliers. ​
​- Take the average loudness of the entire text​
​ Pro: Intuitive Con: Susceptible to outliers. ​
​- Score the loudness of each sentence of each text, and compare. The text with the most "louder" sentences is louder. This would be the equivalent of comparing every point on the graph at each X-value, and seeing which is higher. If a graph has more "higher" points, then it represents the louder text. ​
​ Pro: Accounts for outliers Con: Does not account for one text being longer than the other.

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.