Political Discourse Dataset Stance on X Posts
Authors/Creators
Description
Candidate-Affiliation Dataset, Code, and Supplementary Information
Overview
This record accompanies the paper Political Stance Detection on X During the 2024 U.S. Election: A Comparative Study of Classical, Neural, and Transformer Models. It extends the USE24-XD dataset (10.5281/zenodo.22803534) and contains:
- Dataset: X (Twitter) posts labeled with political candidate affiliation (
Trump,Biden_Kamala,Neutral), plus engineered features. The features cover sentiment, hate and misinformation signals, temporal context, engagement, location, and LDA topic tokens. - Human evaluation set: 300 posts labeled by two annotators.
- Code: notebooks for the stance-detection experiments (classical, neural and transformer models) and the run-to-run variance analysis.
- Supplementary Information (SI): the paper's SI as a PDF, covering model configurations and cross-validation robustness.
Intended uses:
- Political discourse analysis
- Temporal dynamics of narratives
- Stance detection, topic modeling and other NLP tasks
Citation
If you use this dataset or build on it in your research, please cite:
TBD
Please also cite the source dataset, USE24-XD (10.5281/zenodo.22803534).
Post text and access
This record does not contain raw post text, usernames or author IDs. Each post is identified only by its X post id. The only text-derived content is lda_tokens: lemmatized, stop-word-filtered tokens with no word order.
To get the original post text:
- Full text and metrics: request access through the USE24-XD record, 10.5281/zenodo.22803534.
- Dehydrated IDs (public): 10.5281/zenodo.22777827. Rehydrate them through the X API.
Join on id in both cases. Read id as a string, because it exceeds 64-bit float precision.
Contents
| File | Description |
|---|---|
README.md |
This file |
supplementary_information.pdf |
Supplementary Information (SI) of the paper |
annotation_dataset.csv |
X (Twitter) posts with labels and engineered features |
human_evaluation.csv |
300 posts double-annotated by humans |
stance_detection_experiment.ipynb |
Preprocessing, labeling, feature engineering, all models |
mlp_variance_analysis.ipynb |
Seed / 5-fold / bootstrap variance of SBERT + MLP |
Data schema: annotation_dataset.csv
Each row is one post. Posts span 2024-10-17 to 2025-07-16.
| Column | Type | Description |
|---|---|---|
id |
string | X post ID (joins to USE24-XD) |
candidate_affiliation |
string | Candidate affiliation label: Trump, Biden_Kamala or Neutral |
user_state |
string | U.S. state code inferred from the user-provided location, or Non_US |
sentiment_score |
float | VADER compound sentiment score in [-1, 1] |
sentiment_label |
string | positive, negative or neutral |
hate_count |
int | Number of hate-related keywords detected |
hate_flag |
0/1 | 1 if hate_count > 0 |
misinfo_count |
int | Number of misinformation-related patterns detected (e.g. "rigged election", "voter fraud") |
misinfo_flag |
0/1 | 1 if misinfo_count > 0 |
tweet_date |
date | Creation date (UTC), YYYY-MM-DD. Empty for 2 posts whose timestamps could not be parsed. |
tweet_hour |
int | Hour of creation (UTC), 0–23 |
tweet_dayofweek |
int | Day of week, 0 = Monday … 6 = Sunday |
engagement_raw |
int | Total engagement: likes + retweets + replies + quotes + bookmarks |
engagement_rate |
float | engagement_raw / (impressions + 1) |
engagement_rate_log |
float | log1p(engagement_rate) |
sensitive_flag |
0/1 | X's possibly_sensitive flag |
lda_tokens |
list[str] | Preprocessed tokens used for topic modeling (Python list literal) |
Label distribution
| Label | Posts | Share |
|---|---|---|
| Neutral | 27,340 | 48.3% |
| Trump | 22,811 | 40.3% |
| Biden_Kamala | 6,443 | 11.4% |
Notes
-
Labeling.
candidate_affiliationcomes from a keyword-and-stance heuristic. Candidate-skewed vocabulary was refined with log-odds ratios and then combined with stance cues. See the "Candidate fan heuristic" section ofstance_detection_experiment.ipynb, where this column is namedcandidate_fan. -
Temporal period.
temporal_periodis used as a feature in the experiments. It is not stored in the file; derive it fromtweet_dateas below. Posts dated 2024-10-17, before the first boundary, have no period.temporal_periodDates (UTC) election_period2024-10-18 – 2024-11-04 election_day2024-11-05 post_election2024-11-06 – 2025-07-16 -
Content warning.
lda_tokenscontains offensive language, because it reflects the original posts.
Sample rows
| id | candidate_affiliation | user_state | sentiment_score | sentiment_label | hate_count | hate_flag | misinfo_count | misinfo_flag | tweet_date | tweet_hour | tweet_dayofweek | engagement_raw | engagement_rate | engagement_rate_log | sensitive_flag | lda_tokens |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1882403261095043491 | Trump | Non_US | -0.8658 | negative | 3 | 1 | 0 | 0 | 2025-01-23 | 12 | 3 | 0 | 0 | 0 | 0 | ['moron', 'get', 'ass', 'kick', 'election', ...] |
| 1932964629195731097 | Trump | CA | -0.9482 | negative | 3 | 1 | 1 | 1 | 2025-06-12 | 0 | 3 | 2 | 0.06896551724 | 0.0666913745 | 0 | ['evidence', 'emerge', 'prove', 'wrongdoing', ...] |
| 1886480963905183809 | Trump | Non_US | -0.9779 | negative | 3 | 1 | 0 | 0 | 2025-02-03 | 18 | 0 | 0 | 0 | 0 | 1 | ['mean', 'trump', 'deport', 'well', ...] |
Loading
Human evaluation: human_evaluation.csv
300 posts were sampled from the dataset. Two annotators labeled each post independently, and disagreements were resolved into a final label. Post text is not included; join on id with USE24-XD to view it.
| Column | Description |
|---|---|
id |
X post ID (joins to annotation_dataset.csv) |
annotator_1 |
Label from annotator 1 |
annotator_2 |
Label from annotator 2 |
final_label |
Adjudicated label |
- Inter-annotator agreement: 87.3% raw, Cohen's κ = 0.81
- Agreement between the heuristic
candidate_affiliationandfinal_label: 89.7% (269 / 300)
Code
stance_detection_experiment.ipynb
This notebook implements the full pipeline. All models share the same preprocessing and evaluation setup.
1. Data preprocessing
- English filter, text normalization and cleaning
- Removal of URLs, mentions and noise
- Tokenization and lemmatization
- Handling of hashtags and emoji
- Removal of short or empty posts, and de-duplication
2. Feature engineering
- Text: TF-IDF (unigrams + bigrams) and SBERT sentence embeddings (
all-mpnet-base-v2) - Sentiment: score in [-1, 1] and label
- Hate and misinformation signals: keyword-based counts and binary flags
- Temporal: hour of day, day of week, event-based temporal period
- Engagement: raw count, normalized rate, log-transformed rate
- Metadata: state-level user location, platform sensitivity flag
- Topic modeling: LDA tokens
3. Models
- Classical:
- Logistic regression (TF-IDF)
- Linear SVM
- Histogram gradient boosting (HGB with SVD)
- Neural: SBERT (
all-mpnet-base-v2) embeddings + MLP classifier - Transformer: BERTweet (
vinai/bertweet-base), fine-tuned
4. Training setup
- Stratified split: 64% train, 16% validation, 20% test
- Training classes balanced by upsampling
- Early stopping on validation macro-F1
- Hyperparameter tuning for all models
5. Evaluation
- Macro-F1 (primary metric)
- Accuracy
- Confusion matrices for error analysis
mlp_variance_analysis.ipynb
This notebook measures the run-to-run variability of the SBERT + MLP model. It retrains the model under three protocols:
- 10 random seeds on the fixed 64/16/20 split
- Stratified 5-fold cross-validation
- 2,000-sample bootstrap 95% CIs on the test set
Each feature configuration is compared with the text-only baseline using paired tests with Holm correction. When run, the notebook writes per-run metrics, summary tables and a macro-F1 figure.
MLP settings:
- Hidden layers [256, 128], dropout 0.5
- AdamW (lr 5e-4, weight decay 1e-3)
- Label smoothing 0.1, batch size 128
- Up to 40 epochs, early-stopping patience 7
Feature configurations:
| Config | SBERT embedding plus |
|---|---|
emb_only |
— (text only) |
A |
sentiment score/label, hate, misinformation and sensitive flags |
A+B |
A + log engagement rate |
A+B+C |
A+B + user state, is_US, has_US_state |
A+B+C+D |
A+B+C + hour, day of week, temporal period |
Supplementary Information: supplementary_information.pdf
The paper's Supplementary Information (6 pages):
- Appendix A — Model configurations. Original baseline vs. final settings for each model family:
- Table A1: logistic regression and linear SVM
- Table A2: MLP variants
- Table A3: BERTweet
- Appendix B — Cross-validation robustness. The feature analyses from the main text, repeated with stratified 5-fold cross-validation (64/16/20 within each fold) and the Nadeau–Bengio corrected resampled t-test with Holm correction:
- Table B4: incremental feature blocks (P, A–D)
- Table B5: single-feature ablation
How to run
The notebooks start from a full table that includes post text (cleaned_election_tweets.csv). To rebuild it, join this dataset with the USE24-XD post text on id (see Post text and access). Notebook outputs that displayed post text were cleared before release.
Ethics and intended use
- For research on political discourse, stance detection and NLP methods only.
- Do not use it to identify, profile or target individual users.
- Location is coarse: it is inferred at the state level from free-text profiles and is often unreliable.
- Hate and misinformation flags come from simple keyword lists. They are not validated classifiers.
- Anyone using rehydrated content must follow the X Developer Agreement and Policy.
Files
annotation_dataset.csv
Files
(17.5 MB)
| Name | Size | |
|---|---|---|
|
md5:da6832f0afddbd4035917cdc5e77c1da
|
14.5 MB | Preview Download |
|
md5:23bfd1bf3b6ed21a807bb0e4a6855b4a
|
14.3 kB | Preview Download |
|
md5:104887e08b2d562027df4c26b9f8a9c6
|
380.7 kB | Preview Download |
|
md5:4df1d07942647eb982c0b880eb59fd51
|
2.4 MB | Preview Download |
|
md5:8058e9c87e03b4a0bc38d588e2397022
|
230.7 kB | Preview Download |
Additional details
Software
- Programming language
- Python