Stereotype-content analysis with fine-tuned DistilBERT models (SADCAT framework)
Project description
SADBERT
Stereotype-content Analysis with DistilBERT — a Python package for identifying and characterising stereotype-relevant dimensions in natural language text, based on the SADCAT (Stereotype-Associated Dictionary of Content and Affect with Traits) framework.
What it does
Given a word or phrase, SADBERT predicts:
| Output column | Description |
|---|---|
category |
Stereotype-content dimension (e.g. Warmth, Competence) |
probability |
Confidence of the category classifier |
valence |
Direction within the category: 1 = positive, 0 = neutral, −1 = negative |
valence probability |
Confidence of the valence prediction |
interpretation |
Human-readable label (e.g. "Warm", "Incompetent", "Moral") |
Categories detected
Major (with valence): Warmth · Competence · Sociability · Morality · Ability · Assertiveness · Status · Beliefs · health · deviance · beauty · Politics · Religion
Minor (category only, no valence): emotions · Geography · Appearance · occupation · socialgroups · inhabitant · country · relative · insults · stem · humanities · art · Lacksknowledge · fortune · clothing · bodpart · bodprop · skin · bodcov · beliefsother · Other_large · Other
Installation
pip install sadbert
Note: On first use, SADBERT automatically downloads ~2 GB of model weights from the HuggingFace Hub. These are cached locally in
~/.cache/huggingface/and do not need to be re-downloaded on subsequent runs.
GPU / Apple Silicon
SADBERT auto-detects CUDA and Apple MPS. To use a specific device, instantiate SADBERT directly:
from sadbert import SADBERT
model = SADBERT(device="cuda") # or "mps", "cpu"
Quick Start
import sadbert
# Single word — returns a DataFrame
df = sadbert.get_stereotype_content("honest")
print(df)
# Multiple words — stacked into one DataFrame (default)
df = sadbert.get_stereotype_content(["honest", "lazy", "senator"])
print(df)
# Multiple words — one DataFrame per word
results = sadbert.get_stereotype_content(["honest", "lazy"], stacked=False)
print(results["honest"])
print(results["lazy"])
Example output
>>> sadbert.get_stereotype_content("honest")
category probability valence valence probability interpretation
0 Warmth 0.912 1.0 0.876 Warm
1 Morality 0.843 1.0 0.791 Moral
API reference
sadbert.get_stereotype_content(text, stacked=True)
Module-level convenience function. Uses a shared, lazily-initialised SADBERT instance.
| Parameter | Type | Description |
|---|---|---|
text |
str or list[str] |
Word(s) or phrase(s) to classify |
stacked |
bool |
True (default): return one combined DataFrame with a "text" column. False: return a dict[str, DataFrame]. For single string input with stacked=False, returns the DataFrame directly. |
sadbert.SADBERT(device=None, batch_size=32, load_models=True)
Instantiate your own SADBERT object for full control.
from sadbert import SADBERT
model = SADBERT(
device="cuda", # "cuda" | "mps" | "cpu" | None (auto-detect)
batch_size=64, # increase for faster throughput on GPU
load_models=True, # set False to defer model loading to first call
)
results = model.get_stereotype_content(["nurse", "engineer", "senator"])
Model architecture
SADBERT uses a three-stage ensemble:
Input text
│
▼
┌─────────────────────────────────────────────────────┐
│ Stage 1 · Master model (SADBERT_master_model) │
│ Multi-label DistilBERT, 35 output classes │
│ Softmax probabilities compared against per-class │
│ Youden-J thresholds → candidate categories │
└─────────────────────────────────────────────────────┘
│ candidate categories
▼
┌─────────────────────────────────────────────────────┐
│ Stage 2 · Classifier heads (SADBERT_{cat}_classifier) │
│ One binary DistilBERT per category │
│ Veto gate — keeps only categories confirmed by │
│ both master model and dedicated head │
└─────────────────────────────────────────────────────┘
│ confirmed categories + probabilities
▼
┌─────────────────────────────────────────────────────┐
│ Stage 3 · Sentiment models (SADBERT_{cat}_sentiment) │
│ One 3-class DistilBERT per major category │
│ Predicts negative / neutral / positive valence │
└─────────────────────────────────────────────────────┘
│
▼
Results DataFrame
All models are hosted on HuggingFace at huggingface.co/XanderD24.
Citation
If you use SADBERT in research, please cite the underlying SADCAT framework:
@misc{sadbert2025,
author = {Deanhardt, Xander},
title = {{SADBERT}: Stereotype-content Analysis with {DistilBERT}},
year = {2025},
url = {https://github.com/XanderD24/sadbert},
}
Citation of Original Work
All data used to fine-tune these models was taken from the SADCAT dictionary, published by Gandalf Nicolas, Xuecunzi Bai, and Susan T Fiske, and hosted on Github by Gandalf Nicolas. It was first published in this journal:
Nicolas, Gandalf, et al. “Comprehensive Stereotype Content Dictionaries Using a Semi‐Automated Method.” European Journal of Social Psychology, vol. 51, no. 1, Feb. 2021, pp. 178–196, https://doi.org/10.1002/ejsp.2724.
Github Link = {https://github.com/gandalfnicolas/SADCAT/tree/master}
OSF Repository = {https://osf.io/yx45f/}
License
MIT License — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sadbert-0.1.1.1.tar.gz.
File metadata
- Download URL: sadbert-0.1.1.1.tar.gz
- Upload date:
- Size: 20.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5ebf30963ecaa97a67449c06d89e7a066a3ead7076b9622e350274ed9a8fbb8
|
|
| MD5 |
f3d24492719c939c5ddf7f37f88b28a1
|
|
| BLAKE2b-256 |
ebd91f74b5ebc6e5a6041795c0179a2a49b925f042b8165fce94e0d24ecc37e4
|
File details
Details for the file sadbert-0.1.1.1-py3-none-any.whl.
File metadata
- Download URL: sadbert-0.1.1.1-py3-none-any.whl
- Upload date:
- Size: 16.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c20f88396940384186a464b16e2b042162f15bb89bcd4169371237241bee37df
|
|
| MD5 |
a9455248930d6efa7679e71fefdf6056
|
|
| BLAKE2b-256 |
d1dee963f6b9488cf39d648d439caf116ade94a3ddab868fc04857971580779b
|