Photo Source, Social media is another great source of text-data
Text-as-Data Approach: Example 4
Different applications show that Ngram data correlates strongly with similar data from well-respected sources.
Ngrams has content validity – i.e., good proxy
Source: Richey S, Taylor JB. Google Books Ngrams and Political Science: Two Validity Tests for a Novel Data. PS: Political Science & Politics. 2020; 53(1):72-77. doi:10.1017/S1049096519001318
Analyzing a straw of hay: close reading, understanding the meaning of a sentence
Humans are great at it! But computers struggle
Organizing the haystack: describing, classifying, scaling texts
Humans struggle. But computers are great at it!
Principles of quantitative text analysis (Grimmer & Stewart, 2013)
All quantitative models are wrong – but some are useful
Quantitative methods for text amplify resources and augment humans
There is no globally best method for automated text analysis
Validate, validate, validate (i.e., to ensure that what is to be measured (i.e., the numerical scores assigned to texts) correspond to the true nature of the construct being studied)
Overview of text as data methods
Figure 1 in Grimmer and Stewart (2013)
Ideological scaling
Lauderdale, B. E., & Herzog, A. (2016). Measuring political positions from legislative speech. Political Analysis, 24(3), 374-394.
Ideological scaling – explanation
analysis of the U.S. Senate, we use all debates from January 1995 to the end of October 2014, covering the 104th to the 113th Senate
partisan polarization of Senators apparent from the increased degree to which the scores correlate with party
In contrast, in the 112th, there is much cleaner separation between the parties
Descriptive text analysis
Benoit, K., Munger, K., & Spirling, A. (2019). Measuring and Explaining Political Sophistication through Textual Complexity. American Journal of Political Science, 63(2), 491–508.
Document classification into unknown categories
Bauer, Barbera et al, Political Behavior, 2016.
Data: General Social Survey (2008) in Germany
Responses to questions: Would you please tell me what you associate with the term “left”? and would you please tell me what you associate with the term “right”?
Open-ended questions minimize priming and potential interviewer effects
Automated text analysis to discover unknown categories and classify responses
Document classification into unknown categories
Bauer, P. C., Barberá, P., Ackermann, K., & Venetz, A. (2017). Is the left-right scale a valid measure of ideology? Individual-level variation in associations with “left” and “right” and left-right self-placement. Political Behavior, 39(3), 553-583.
Document classification into unknown categories
Bauer, P. C., Barberá, P., Ackermann, K., & Venetz, A. (2017). Is the left-right scale a valid measure of ideology? Individual-level variation in associations with “left” and “right” and left-right self-placement. Political Behavior, 39(3), 553-583.
Quantitative text analysis requires assumptions
Texts represent an observable implication of some underlying characteristic of interest
An attribute of the author
A sentiment or emotion
Salience of a political issue
Texts can be represented through extracting their features
most common is the bag of words assumption
many other possible definitions of “features” (e.g. word embeddings)
A document-feature matrix can be analyzed using quantitative methods to produce meaningful and valid estimates of the underlying characteristic of interest
Key feature of quantitative text analysis
Selecting texts: Defining the corpus
Conversion of texts into a common electronic format
Defining documents: deciding what will be the documentary unit of analysis
Key feature of quantitative text analysis (cont.)
Defining features: These can take a variety of forms, including tokens, equivalence classes of tokens (dictionaries), selected phrases, human-coded segments (of possibly variable length), linguistic features, and more.
Conversion of textual features into a quantitative matrix
A quantitative or statistical procedure to extract information from the quantitative matrix
Summary and interpretation of the quantitative results
Some key basic concepts
(text) corpus a large and structured set of texts for analysis
document each of the units of the corpus
tokens any word – so token count is total words
e.g. A corpus is a set of documents. A corpus can be 2 documents, where each document is a sentence. The first document has 7 tokens. The second has 8 tokens. (We ignore punctuation for now.)
stems words with suffixes removed (using set of rules, i.e., playing is play)
lemmas canonical word form (the base form of a word that has the same meaning even when different suffixes or prefixes are attached)
word: win winning wins won winner
stem: win win win won winner
lemma: win win win win win
“key” words Words selected because of special attributes, meanings, or rates of occurrence
stop words Words that are designated for exclusion from any analysis of a text
Preprocessing text
Preprocessing helps us to go from words to numbers:
Preprocess text: lowercase, remove stopwords and punctuation, stem, tokenize into unigrams and bigrams (bag-of-words assumption)
Preprocessing text in R
# Example text datatexts <-c("Hello world! This is an example text.","Text preprocessing is essential for NLP tasks.","R provides multiple tools for cleaning and analyzing text.")# Step 1: Create a corpus and preprocess using pipesclean_dfm <- texts %>%# Convert to corpuscorpus() %>%# Convert corpus to tokens (individual words)tokens(remove_punct =TRUE, # Remove punctuationremove_numbers =TRUE# Remove numbers ) %>%# Convert to lowercasetokens_tolower() %>%# Remove stopwordstokens_remove(stopwords("english")) %>%# Optional: stem wordstokens_wordstem() %>%# Convert tokens to document-feature matrix (DFM)dfm()
Preprocessing text in R
# View the cleaned DFMprint(clean_dfm)
Document-feature matrix of: 3 documents, 14 features (61.90% sparse) and 0 docvars.
features
docs hello world exampl text preprocess essenti nlp task r provid
text1 1 1 1 1 0 0 0 0 0 0
text2 0 0 0 1 1 1 1 1 0 0
text3 0 0 0 1 0 0 0 0 1 1
[ reached max_nfeat ... 4 more features ]
# Step 2: Optional - get top features/wordstop_words <-textstat_frequency(clean_dfm) %>%head(10) # Top 10 most frequent wordsprint(top_words)
feature frequency rank docfreq group
1 text 3 1 3 all
2 hello 1 2 1 all
3 world 1 2 1 all
4 exampl 1 2 1 all
5 preprocess 1 2 1 all
6 essenti 1 2 1 all
7 nlp 1 2 1 all
8 task 1 2 1 all
9 r 1 2 1 all
10 provid 1 2 1 all
Word frequencies and their properties
Bag-of-words approach disregards grammar and word order and uses word frequencies as features. Why?
Context is often uninformative, conditional on presence of words
Individual word usage tends to be associated with a particular degree of affect, position, etc. without regard to context of word usage
Common English stop words
But no list should be considered universal! Also, not all languages are the same!
Where to get text data?
Some tips…
Existing datasets, e.g. UCD’s EuroParl project Hansard Archive of parliamentary debates in UK Media archives (newspaper articles, TV transcripts…) at LexisNexis, ProQuest, Factiva… Academic articles (JSTOR Data for Research) Open-ended responses to survey questions
Collect your own data: From social media (Twitter, FB) and blogs Scraping other websites
Digitize your own text data using OCR (optical character recognition) software Use AI to improve digital texts into machine-readible version options: Tesseract (open-source), Abbyy FineReader
Chris Bail’s course: https://cbail.github.io/textasdata/Text_as_Data.html
sentimentr: https://github.com/trinker/sentimentr
Sentiment Analysis
Sentiment analysis (also known as opinion mining) is a natural language processing (NLP) technique used to determine the emotional tone behind a body of text.
It classifies text as: Positive, Negative, Neutral
More advanced systems can detect emotions (e.g., joy, anger, sadness) or intensity (e.g., mildly positive vs. strongly positive).
Process in a nutshell
Source: https://www.tidytextmining.com/dtm
Sentiment Analysis Examples
sentimentr package using Presidential debates
quanteda approach using Trump vs Clinton tweets
sentimentr package – basic functions
# library(dplyr)# library(sentimentr)# Sample texttext <-"This workshop is awesome but the instructor is boring!"text2 <-"This workshop is awesome. But, the instructor is boring!"# The main function is sentimentsentiment(text)
# library(dplyr)# library(sentimentr)# Sample texttext2 <-"This workshop is awesome. But, the instructor is boring!"# The main function is sentimentsentiment(text2)
# Let's use the presidential debate data in sentimentrdebates <- presidential_debates_2012 # Let's create positive, negative, and neutral sentimentsdebates_with_pol <- debates |>get_sentences() |>sentiment() |>mutate(polarity_level =ifelse(sentiment <0.2, "Negative",ifelse(sentiment >0.2, "Positive","Neutral")))# Let's check negative sentencesdebates_with_pol |>filter(polarity_level =="Negative") |>head()
person tot time role
<fctr> <char> <fctr> <fctr>
1: ROMNEY 2.1 time 1 candidate
2: ROMNEY 2.2 time 1 candidate
3: LEHRER 3.1 time 1 moderator
4: ROMNEY 4.1 time 1 candidate
5: ROMNEY 4.2 time 1 candidate
6: ROMNEY 4.4 time 1 candidate
dialogue
<get_sentences>
1: What I support is no change for current retirees and near retirees to Medicare.
2: And the president supports taking dollar seven hundred sixteen billion out of that program.
3: And what about the vouchers?
4: So that's that's number one.
5: Number two is for people coming along that are young, what I do to make sure that we can keep Medicare in place for them is to allow them either to choose the current Medicare program or a private plan.
6: They get to choose and they'll have at least two plans that will be entirely at no cost to them.
element_id sentence_id word_count sentiment polarity_level
<int> <int> <int> <num> <char>
1: 3 1 14 -0.1336306 Negative
2: 4 1 14 0.1336306 Negative
3: 5 1 5 0.0000000 Negative
4: 6 1 5 0.0000000 Negative
5: 7 1 40 0.1343968 Negative
6: 9 1 20 0.0000000 Negative
sentimentr package – Presidential debates
# Let's look at candidates' sentimentsdebates |>get_sentences() |>sentiment() |>ggplot() +geom_boxplot(aes(y = person, x = sentiment))
# My expectation is that overall presidential debates are neutraldebates |>get_sentences() |>sentiment_by(by =NULL) |>#View()ggplot() +geom_density(aes(ave_sentiment))
Trump vs Clinton Example – Let’s start by loading packages and data