Downloads · 30 days
63
15% of all-time downloads
SinclairSchneider/english_politic_RoBERTa-large
english_politic_RoBERTa-large is a text classification model from SinclairSchneider. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as mit.
This classifier predicts whether an English text is political (politic) or not (other). It is FacebookAI/roberta-large fine-tuned on SinclairSchneider/trainsetpoliticaltextyesnoenglish, a set of about 45k news and blo…
Downloads · 30 days
63
15% of all-time downloads
All-time downloads
411
Public
Parameters
355M
1.4 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors1.4 GB · 100%
From the Hugging Face model README
This classifier predicts whether an English text is political (politic) or not (other). It is FacebookAI/roberta-large fine-tuned on SinclairSchneider/trainset_political_text_yes_no_english, a set of about 45k news and blog articles from TIME, Military Times and Security Affairs. Each article is labeled by the section or outlet it was published in.
The training script is in this repository: train.py.
The model reaches 97.9% accuracy / 0.979 weighted F1 on a held-out split of its own training data. On an outside dataset (BBC News) it ranks texts well (ROC-AUC 0.97), but the default 0.5 threshold produces many false positives, especially for sport and business news. For out-of-domain text, use a stricter threshold such as 0.9–0.98. See Evaluation.
The German counterpart is SinclairSchneider/german_politic_DeBERTa-v2-base.
Related paper: Ideology Prediction of German Political Texts (Schneider, Steuber, Schneider & Dreo Rodosek, ICWSM 2026). This model was developed in the same research project. The paper uses the German counterpart as a pre-filter that removes non-political texts before political ideology is predicted.
[!IMPORTANT] Before using the model, note:
- Pass
truncation=True. Inputs longer than 512 tokens otherwise crash the pipeline (RuntimeError: index 514 is out of bounds…, or a CUDA device-side assert on GPU).- Replace non-breaking spaces (
\xa0) with regular spaces. In the training data they appeared only in one non-political source, so the model learned them as a cue forother. Three of them inserted into a political article flip 25% of political BBC articles toother.- Don't rely on the 0.5 threshold outside the news domain the model was trained on. On BBC News it labels 79% of sport and 65% of business articles as
politic.- Short texts get low-confidence scores. Headlines and single sentences often score between 0.5 and 0.75, e.g. "Trump and Putin agree on limited ceasefire" →
politic0.65.
from transformers import pipeline
political_classifier = pipeline("text-classification", model="SinclairSchneider/english_politic_RoBERTa-large")
political_classifier("The Senate passed the bill by a vote of 52 to 48, sending the immigration reform package to the president's desk.")
# [{'label': 'politic', 'score': 0.9991005659103394}]
political_classifier("The new smartphone features a larger battery, a faster processor and an improved camera system.")
# [{'label': 'other', 'score': 0.9969991445541382}]
political_classifier("Trump and Putin agree on limited ceasefire")
# [{'label': 'politic', 'score': 0.6543024778366089}]
political_classifier("Franck Ribéry and Arjen Robben celebrate their comeback at FC Bayern at the \"Beckenbauer Cup\". They look as good as in their best days and awaken a great longing at the record champions.")
# [{'label': 'other', 'score': 0.7409901022911072}]
The last two examples are the English translations of the examples in the German model's card. The outputs shown were produced with transformers 5.15 / torch 2.13. Scores may differ in the last decimal places with other versions or hardware.
import re
from transformers import pipeline
political_classifier = pipeline("text-classification", model="SinclairSchneider/english_politic_RoBERTa-large")
def normalize(text):
# Non-breaking spaces and typographic quotes push the model towards "other" (see "Shortcut probes")
text = (text.replace("\xa0", " ")
.replace("“", '"').replace("”", '"')
.replace("‘", "'").replace("’", "'"))
return re.sub(r"\s+", " ", text).strip()
texts = [
"Lawmakers are debating a bill to raise the minimum wage.",
"This recipe needs two cups of flour and a pinch of salt.",
" ".join(["The parliament debated the new budget proposal for several hours."] * 120), # > 512 tokens
]
results = political_classifier([normalize(t) for t in texts], truncation=True, top_k=None, batch_size=32)
p_politic = [{d["label"]: d["score"] for d in r}["politic"] for r in results]
print([round(p, 4) for p in p_politic])
# [0.9129, 0.01, 0.9984]
THRESHOLD = 0.95 # stricter than 0.5; see "Choosing a threshold"
print([p >= THRESHOLD for p in p_politic])
# [False, False, True]
With top_k=None, the pipeline returns the scores of both labels. Note that the minimum-wage sentence is a political text that falls below the strict threshold: single sentences rarely reach 0.95. Choose the threshold according to the length of your inputs and how you weigh false positives against false negatives.
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
repo = "SinclairSchneider/english_politic_RoBERTa-large"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForSequenceClassification.from_pretrained(repo).eval()
texts = ["The prime minister announced a snap election for next month.",
"The band announced a world tour starting in March."]
enc = tokenizer(texts, truncation=True, max_length=512, padding=True, return_tensors="pt")
with torch.no_grad():
probs = model(**enc).logits.softmax(dim=-1)
for text, p in zip(texts, probs):
print(model.config.id2label[int(p.argmax())], round(float(p[1]), 4), text)
# politic 0.991 The prime minister announced a snap election for next month.
# other 0.0013 The band announced a world tour starting in March.
| Developed by | Sinclair Schneider, Research Institute CODE, Bundeswehr University Munich (NLP Research Group UniBW) |
| Model type | RobertaForSequenceClassification: transformer encoder with a sequence-classification head |
| Base model | FacebookAI/roberta-large |
| Parameters | 355.4 M |
| Language | English |
| Task | Binary topic classification: political vs. other |
| Labels | 0 → other, 1 → politic |
| Max input length | 512 tokens (longer inputs must be truncated) |
| Training data | SinclairSchneider/trainset_political_text_yes_no_english |
| Trained | June 2024 |
| License | MIT |
| Related models | SinclairSchneider/german_politic_DeBERTa-v2-base (German) |
| Related paper | Ideology Prediction of German Political Texts (ICWSM 2026) |
The model was trained on SinclairSchneider/trainset_political_text_yes_no_english. Labels come from the section or outlet; no article was labeled by hand.
| Label | Source | Articles |
|---|---|---|
politic (1) | TIME Politics | 8,166 |
politic (1) | TIME World | 7,103 |
politic (1) | Military Times (all) | 6,558 |
other (0) | TIME Entertainment | 7,577 |
other (0) | TIME Health | 3,800 |
other (0) | TIME Tech | 3,336 |
other (0) | TIME Business | 1,175 |
other (0) | Security Affairs (IT-security blog, all) | 7,755 |
The articles date mostly from the 2010s and come mostly from US outlets. The other class contains no sport, travel, food, science or religion content. This explains the sport false positives in the out-of-domain evaluation. The dataset card describes the composition, statistics and known artifacts in detail.
As implemented in train.py:
content) was used. The title was not used.Paganini Security, Security Affair, Pierluigi, Paganini, opting Newsletter, Newsletter, breaking news, email opting, directly inbox, email and inbox were deleted from every text.(label, text) pairs (184 rows). That left 45,108 texts (23,340 other / 21,768 politic).Dataset.train_test_split(0.2), giving 36,086 train / 9,022 eval texts. No seed was set for the shuffle or the split, so the exact split can't be reproduced.DataCollatorWithPadding).The keyword filter removes words but not the remaining sentence fragments or character-level formatting. Some source artifacts therefore stayed in the training text, and the model picked them up (see Shortcut probes).
| Hyperparameter | Value |
|---|---|
| Base checkpoint | FacebookAI/roberta-large |
| Optimizer | AdamW (adamw_torch), β₁ = 0.9, β₂ = 0.999, ε = 1e-8 |
| Learning rate | 2e-5, linear decay to 0, no warm-up |
| Weight decay | 0.01 |
| Max gradient norm | 1.0 |
| Epochs | 4 (2,256 steps, 564 per epoch) |
| Batch size | 16 per GPU × 4 GPUs = 64, no gradient accumulation |
| Max sequence length | 512 |
| Dropout | 0.1 (hidden and attention) |
| Precision | bf16: weights loaded in bfloat16 and trained with bf16=True |
| Evaluation / checkpointing | every epoch |
| Model selection | load_best_model_at_end=True on eval loss → epoch 3 (step 1,692) was published |
Seed (Trainer) | 42 |
| Loss | cross-entropy (single-label classification) |
The published model.safetensors stores the epoch-3 weights as float32 (1.42 GB). The values are identical to the bf16 checkpoint, just upcast.
| Training runtime | 1,331.6 s (≈ 22 min) for 4 epochs |
| Training throughput | 108.4 samples/s, 1.69 steps/s |
| Evaluation throughput | ≈ 445 samples/s (9,022 texts in ≈ 20 s) |
| Total training FLOPs | 1.35 × 10¹⁷ |
| Mean training loss | 0.0717 |
| Checkpoint size | 1.42 GB (float32 safetensors) |
Scores on 9,022 held-out texts, from the same sources and the same period as the training data. Precision, recall and F1 are weighted over both classes.
| Epoch | Eval loss | Accuracy | F1 | Precision | Recall |
|---|---|---|---|---|---|
| 1 | 0.0660 | 0.9768 | 0.9768 | 0.9769 | 0.9768 |
| 2 | 0.0700 | 0.9769 | 0.9770 | 0.9771 | 0.9769 |
| 3 (published) | 0.0659 | 0.9789 | 0.9789 | 0.9789 | 0.9789 |
| 4 | 0.0665 | 0.9793 | 0.9793 | 0.9793 | 0.9793 |
The split is random, so source-specific artifacts appear in both train and eval data. Read these numbers as an upper bound for news articles similar to the training data.
Setup. The original, cased BBC News dataset (Greene & Cunningham, 2006) contains 2,225 BBC articles from 2004–2005 in five sections. After removing exact duplicates, 2,127 remain: politics 403, business 503, entertainment 369, sport 505, tech 347.
Target: politics → politic, all other sections → other. This test differs from the training data in outlet (BBC), country (UK), period (2004–2005) and topic mix: sport never appeared in training. The model input was title + "\n\n" + body, truncated to 512 tokens. Four input variants were evaluated: the full article, the first sentence of the body only, the headline only, and the full article in lowercase.
| Input | Accuracy | Precision (politic) | Recall (politic) | F1 (politic) | Macro F1 | ROC-AUC |
|---|---|---|---|---|---|---|
| Full article | 0.628 | 0.337 | 0.998 | 0.504 | 0.603 | 0.971 |
| First sentence only | 0.694 | 0.380 | 0.980 | 0.548 | 0.658 | 0.949 |
| Headline only | 0.552 | 0.291 | 0.955 | 0.447 | 0.535 | 0.899 |
| Full article, lowercased | 0.654 | 0.353 | 0.998 | 0.522 | 0.625 | 0.979 |
Confusion matrix, full article at 0.5: TN 933 · FP 791 · FN 1 · TP 402.
politic| Input / threshold | politics | business | sport | tech | entertainment |
|---|---|---|---|---|---|
| Full article @ 0.5 | 99.8% | 64.8% | 78.6% | 12.4% | 6.8% |
| Full article @ 0.9 | 98.8% | 35.4% | 10.9% | 4.9% | 2.7% |
| Full article @ 0.95 | 96.8% | 29.2% | 3.2% | 3.7% | 1.9% |
| First sentence @ 0.5 | 98.0% | 50.1% | 71.1% | 6.3% | 3.0% |
| Headline @ 0.5 | 95.5% | 70.6% | 94.7% | 16.1% | 12.7% |
Full articles, BBC News:
| Threshold | Accuracy | Precision | Recall | F1 (politic) | Macro F1 |
|---|---|---|---|---|---|
| 0.50 | 0.628 | 0.337 | 0.998 | 0.504 | 0.603 |
| 0.80 | 0.793 | 0.478 | 0.993 | 0.645 | 0.750 |
| 0.90 | 0.875 | 0.605 | 0.988 | 0.750 | 0.834 |
| 0.95 | 0.908 | 0.681 | 0.968 | 0.799 | 0.870 |
| 0.98 | 0.924 | 0.744 | 0.911 | 0.819 | 0.886 |
| 0.99 | 0.923 | 0.786 | 0.819 | 0.802 | 0.877 |
These thresholds were picked on the same data they are scored on, so the numbers are optimistic. Validate a threshold on a sample of your own data.
other class in training had no sport, and sports reporting shares vocabulary with world news: nations, teams, coaches, "campaign", "defeat". Sport articles get a median politic score of 0.71. Most of them are only moderately confident, though, so a 0.9–0.95 threshold removes almost all of them. Examples: "Campbell to be Lions consultant" 0.995, "Bomb threat at Bernabeu stadium" 0.983, "Iranian misses Israel match" 0.981, "Spain coach faces racism inquiry" 0.968.These 16 hand-written sentences were not drawn from any dataset. The table shows P(politic):
| Sentence | Gold | P(politic) |
|---|---|---|
| The Senate voted to confirm the new Supreme Court justice. | politic | 0.993 |
| The prime minister announced a snap election for next month. | politic | 0.991 |
| Lawmakers are debating a bill to raise the minimum wage. | politic | 0.913 |
| The president vetoed the defense spending bill. | politic | 0.988 |
| NATO foreign ministers met in Brussels to discuss sanctions against Russia. | politic | 0.997 |
| The opposition party accused the government of corruption. | politic | 0.995 |
| Voters in Ohio head to the polls on Tuesday for the primary. | politic | 0.989 |
| The UN Security Council condemned the missile test. | politic | 0.998 |
| I like to go to the gym | other | 0.446 |
| This recipe needs two cups of flour and a pinch of salt. | other | 0.010 |
| The striker scored twice as the home team won 3-1. | other | 0.727 ✗ |
| The new phone has a bigger screen and a better camera. | other | 0.002 |
| The band announced a world tour starting in March. | other | 0.001 |
| Scientists discovered a new species of frog in the rainforest. | other | 0.305 |
| Drinking enough water is important for your health. | other | 0.011 |
| Our hotel had a beautiful view of the beach. | other | 0.568 ✗ |
At 0.5, 14 of 16 are correct. Both errors are topics that were missing from the training data (sport, travel), and the scores for everyday sentences sit close to 0.5.
To test whether the model learned source formatting instead of topic, typical training-source artifacts were inserted into BBC articles and the predictions compared.
Military Times newsletter text → pushes towards politic. The newsletter fragment left in the Military Times training texts after keyword filtering ("Fear no longer. Be the first to hear about , as it happens. … Sign up for the Early Bird Brief,") was inserted after the first paragraph of the 1,724 non-political BBC articles. A neutral newsletter sentence of similar length served as a control:
Predicted politic (all non-political) | entertainment | tech | business | sport | |
|---|---|---|---|---|---|
| Original | 45.9% | 6.8% | 12.4% | 64.8% | 78.6% |
| + neutral control text | 50.8% | 7.9% | 14.1% | 71.0% | 87.3% |
| + Military Times fragment | 72.7% | 37.1% | 42.4% | 92.6% | 99.6% |
Security Affairs formatting → pushes towards other. These were applied to the bodies of the 403 political BBC articles:
| Modification | Predicted politic |
|---|---|
| None (body only) | 99.5% |
Paragraphs joined with ", " | 99.5% |
Typographic quotes (“ ” ’) | 99.5% |
Tag remnant (s – politics, government) appended | 99.8% |
3 non-breaking spaces (\xa0) after sentence ends | 74.4% |
| Typographic quotes + 3 non-breaking spaces | 62.3% |
| All of the above combined | 26.3% |
The non-breaking space is the strongest single cue. In the training data it occurred only in Security Affairs (other). Web-scraped text often contains non-breaking spaces, so normalize whitespace before classifying (see the normalize() function above).
other, so the model scores them unpredictably, often as politic.truncation=True, and normalize whitespace and quotes before inference.DataParallel, on-premise university GPU server (no cloud provider).These figures cover only the published run. Development runs (one earlier complete run of ≈ 17 min and several short debugging runs) are not included.
RobertaClassificationHead): dropout → dense 1,024→1,024 + tanh → dropout → linear 1,024→2 applied to the <s> token.problem_type: single_label_classification).Related paper from the same project:
@article{schneider2026ideology,
title = {Ideology Prediction of German Political Texts},
author = {Schneider, Sinclair and Steuber, Florian and Schneider, Jo{\~a}o A. G. and Dreo Rodosek, Gabi},
journal = {Proceedings of the International AAAI Conference on Web and Social Media},
volume = {20},
number = {1},
pages = {2006--2021},
year = {2026},
doi = {10.1609/icwsm.v20i1.42735},
url = {https://doi.org/10.1609/icwsm.v20i1.42735}
}
This model:
@misc{schneider_english_politic_roberta_large,
author = {Schneider, Sinclair},
title = {english\_politic\_RoBERTa-large: a RoBERTa-large classifier for detecting political text in English},
year = {2024},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/SinclairSchneider/english_politic_RoBERTa-large}}
}
Base model:
@article{liu2019roberta,
title = {RoBERTa: A Robustly Optimized BERT Pretraining Approach},
author = {Liu, Yinhan and Ott, Myle and Goyal, Naman and Du, Jingfei and Joshi, Mandar and Chen, Danqi and Levy, Omer and Lewis, Mike and Zettlemoyer, Luke and Stoyanov, Veselin},
journal = {arXiv preprint arXiv:1907.11692},
year = {2019}
}
Out-of-domain evaluation data:
@inproceedings{greene2006bbc,
title = {Practical Solutions to the Problem of Diagonal Dominance in Kernel Document Clustering},
author = {Greene, Derek and Cunningham, P{\'a}draig},
booktitle = {Proceedings of the 23rd International Conference on Machine Learning (ICML)},
pages = {377--384},
year = {2006}
}
Sinclair Schneider, NLP Research Group UniBW. Questions and issues are welcome in the Community tab.