Machine Learning for Social Scientists
James Hall
Associate Professor of Psychology of Education:
Southampton Education School, University of Southampton
Deputy Director:
ESRC National Centre for Research Methods
11/7/2025
J.E.Hall@Soton.ac.uk
Aims
To develop attendees’ understanding of:
Content
Part 1: Machine Learning for Social Scientists
Defining Machine Learning (ML)�
A brief history of ML– and how it relates to other disciplines
40s/50s
AI & ML
Statistics
80s
AI
Statistics
ML
90s
AI
Statistics
ML
(statistical data mining)
2010s+
AI
Statistics
ML
(statistical data mining)
Deep processing
GenAI
LLMs
(Where this session focuses)
Why use ML in the Social Sciences?
Why use ML in the Social Sciences?
Data better suited to traditional statistical analysis techniques
Data better suited to ML techniques
Data suited to traditional statistical analysis or ML techniques
Data Conditions (in combination)
Data conditions
How ML differs from traditional inductive statistical methods
Inductive Statistics (e.g., EFA, cluster analysis) | Machine Learning (e.g., k-means, decision trees) |
Data-driven and exploratory | Data-driven & exploratory |
Often used for data exploration & theory development | Often used for automated pattern-finding & prediction |
Grounded in statistical models & assumptions | May use statistical or non-statistical algorithms |
Emphasis on interpretation (e.g., loadings, clusters) | Emphasis on predictive performance & generalisation |
Usually applied to clean, numeric datasets with moderate variable counts | Built to handle very large, high-dimensional, and mixed-type data |
Typically used in single-step analyses | Often part of larger pipelines (e.g., preprocessing, tuning, validation) |
Common Types of ML: Supervised vs. Unsupervised
| Supervised ML | Unsupervised ML |
Goal | Predict a known outcome | Discover hidden patterns or structure |
Needs Outcome Variable? | Yes | No |
Typical Tasks | Classification, prediction | Clustering, dimensionality reduction |
Example Methods | Decision trees, ridge regression, random forests | k-means, PCA, hierarchical clustering |
Output | Prediction model (e.g. who drops out) | Groupings, factors, or visualisable structure |
Common in Social Science For… | Risk modelling, automated scoring, early warning | Segmentation, scale exploration, typologies |
Prevalence of ML in social science research
Supervised ML models
Two ML Methods We’ll Explore Today
Decision Trees
Example ‘real-world’ Decision Tree
Gradient Boosting
Example ‘real-world’ Gradient Boosting
Software for ML
Suggested follow-on reading�
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021).�An Introduction to Statistical Learning (2nd ed.). Springer.
Widely regarded as the best intro to ML for people with a stats background
Uses R; clear explanations; focuses on supervised learning
Kuhn, M., & Johnson, K. (2013).�Applied Predictive Modeling. Springer.
Practical, code-heavy, social-science friendly
Focuses on model tuning, performance, and caret package in R
Great bridge between traditional stats and ML
Efron, B., & Hastie, T. (2016). Computer Age Statistical Inference: Algorithms, Evidence, and Data Science. Cambridge University Press
Broader perspective on how statistical ideas evolved into ML�Mixes theory and algorithms; good for context and reflection�For readers wanting depth, not just recipes
Questions?
15-minute break
Part 2: ML in the R Software Package
Aims for this ML (via RStudio) workshop
Important note:
R needs straight single quote marks ' and not curly quote marks ‘ .
Load required SEM packages
install.packages("rpart")
install.packages("rpart.plot")
install.packages("tidyverse")
library(rpart)
library(rpart.plot)
library(tidyverse)
Screenshot
# Download dataset directly from UC Irvine
temp <- tempfile()
download.file("https://archive.ics.uci.edu/ml/machine-learning-databases/00320/student.zip", temp)
# 2. Unzip and read the math course data
unzip(temp, files = "student-mat.csv")
student <- read.csv("student-mat.csv", sep = ";")
# 3. Clean up temporary file
unlink(temp)
# Create a binary outcome: pass = G3 >= 10 so that our Decision Tree is also a Classification Tree
# Lets us consider a real practical outcome -– risk of failing the grade
student$pass <- ifelse(student$G3 >= 10, "pass", "fail")
student$pass <- as.factor(student$pass)
Screenshot after running: head(student)
Screenshot after running: summary(student)
Run, view, and plot the decision tree ML
# Build a classification tree
tree_model <- rpart(
pass ~ studytime + failures + absences + G1 + G2 + sex + age,
data = student,
method = "class"
)
summary(tree_model)
rpart.plot(tree_model, type = 2, extra = 104, fallen.leaves = TRUE)
Screenshot after running code
Looking more closely at the decision tree output
33% failed, 67% passed the grade
G2<10? 🡪 the first and most important split.
37% of the sample had “G2<10”. Of these 84% failed G3.
Similarly, of those for whom “G2>=10”: 97% of the passed G3.
That’s the predictive power of the “G2<10 split and an intuitive showcase of the utility of this method and ML.
Looking more closely at the output
Info about tree complexity control and ‘pruning’ – too much for this intro session
Matches the tree – variables G2 and then G1 were the strongest predictors of G3 pass/fail
Tells us about the nodes on the tree we just saw (same info)
Get quick feedback on the quality of this model in it’s ‘classification’
pred_tree <- predict(tree_model, type = "class")
confusion <- table(Predicted = pred_tree, Actual = student$pass)
print(confusion)
accuracy <- sum(diag(confusion)) / sum(confusion)
paste("Accuracy:", round(accuracy * 100, 2), "%")
Notes:
A first look at how well the model fits the data (same idea as in SEM – “model fit”)
In real ML, models are (as earlier) not evaluated on the same data they are fitted on
Looking more closely at the output
Clear to see how accurate the predictions were.
This evaluation of the predictive power of the decision tree model is overestimating predictive power because it is applied to the data it was training on.
2. ML method 2: Gradient Boosting
install.packages("xgboost")
install.packages("caret")
install.packages("Matrix")
library(xgboost)
library(caret)
library(Matrix)
Data preparation
# Convert factor outcome to numeric: 1 for pass, 0 for fail
student$pass_numeric <- ifelse(student$pass == "pass", 1, 0)
# Define the predictors and outcome
predictors <- student[, c("studytime", "failures", "absences", "G1", "G2", "age")]
outcome <- student$pass_numeric
# Convert predictors to a matrix for xgboost
x <- as.matrix(predictors)
y <- as.numeric(outcome)
Data fit, prediction, and evalaution
# Basic gradient boosting model
gb_model <- xgboost(data = x,
label = y,
objective = "binary:logistic",
nrounds = 100,
verbose = 0)
# Predict probabilities
gb_pred_probs <- predict(gb_model, x)
# Convert to class predictions: 1 = pass, 0 = fail
gb_pred <- ifelse(gb_pred_probs > 0.5, 1, 0)
# Confusion matrix
conf_matrix <- table(Predicted = gb_pred, Actual = y)
print(conf_matrix)
# Accuracy
gb_accuracy <- sum(diag(conf_matrix)) / sum(conf_matrix)
paste("Accuracy:", round(gb_accuracy * 100, 2), "%")
Looking more closely at the output
Clear to see how accurate the predictions were.
Top is from the decision tree ML.
Bottom is from the Gradient Boosting ML.
Logically, we would expect the Gradient Boosting ML to perform at-least as well as the Decision Tree ML. Here it performs better.
However, this evaluation of the predictive power of the MLs is overestimating predictive power because it is applied to the data it was training on.
Strong risk of “overfitting our data” – lack of ability to predict future new data
What next?