Instructions to use SinclairSchneider/german_politic_direction_DeBERTa-large with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use SinclairSchneider/german_politic_direction_DeBERTa-large with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="SinclairSchneider/german_politic_direction_DeBERTa-large")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("SinclairSchneider/german_politic_direction_DeBERTa-large") model = AutoModelForSequenceClassification.from_pretrained("SinclairSchneider/german_politic_direction_DeBERTa-large", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- german_politic_direction_DeBERTa-large
- Quick start
- Model details
- Uses
- Training data
- Training procedure
- From party scores to an ideology score
- Evaluation
- Comparison with the other models of the collection
- 1. In-distribution: the random 20% split used during training
- 2. Bundestag speeches after the training cut-off
- 3. Wahl-O-Mat theses after the training cut-off
- 4. Newspapers (the paper's out-of-domain benchmark)
- 5. Tweets by members of the Bundestag
- 6. Party order on 2025/26 speeches
- Bias, risks, and limitations
- Environmental impact
- Technical specifications
- Citation
- Model card authors and contact
german_politic_direction_DeBERTa-large
This model estimates where a German political text stands on the left–right spectrum. It returns two things:
- Six party scores: for each of Die Linke, Bündnis 90/Die Grünen, SPD, FDP, CDU/CSU and AfD, the probability that members of that party would applaud or agree with the text.
- One ideology score from −1 (left, like Die Linke) through 0 (liberal centre, like the FDP) to +1 (right, like the AfD), computed from the six scores with the small formula shown below.
It is ikim-uk-essen/geberta-xlarge (GeBERTa-xlarge, a German DeBERTa-v2 model) fine-tuned on SinclairSchneider/trainset_political_party_big: Bundestag speeches labelled with which parliamentary groups applauded, Wahl-O-Mat answers of the parties, party manifestos, and LLM paraphrases of all of them (636,717 texts, 1998 – September 2024).
Paper: Ideology Prediction of German Political Texts (Schneider, Steuber, Schneider & Dreo Rodosek, ICWSM 2026). Code: github.com/SinclairSchneider/german_ideology_prediction. This model is one of five classifiers in the collection; see the comparison to choose between them.
Summary of results:
- In-distribution (random 20% split used during training): micro-F1 0.772, precision 0.805, recall 0.742. These numbers are optimistic, because paraphrases of the same speech can end up on both sides of the split.
- On Bundestag speeches given after the training data ends (Mar 2025 – Nov 2026), it ranks which groups applaud with a macro ROC-AUC of 0.807 (training-period speeches: 0.880). That is rank 3 of the 5 models in this collection.
- On the 2025/26 Wahl-O-Mat theses it separates the parties' "agree" answers with a macro ROC-AUC of 0.857. For 85.3% of the theses, the party with the highest score really agreed (base rate 53.4%).
- Newspaper benchmark (33 outlets): mean absolute error 0.175 on a −1…1 scale with the calibrated angles (paper: 0.182). The angles were fitted on these same outlets; with leave-one-outlet-out fitting the error is 0.187, with the uncalibrated default angles 0.192. Rank 3 of 5.
- Tweets by members of the Bundestag: the top-scoring party is the author's party for 42.2% of political tweets (chance 16.7%), rising to 72.6% for tweets with ≥ 50 words.
- Party order: averaged over 2025/26 speeches, the scores of the speakers' groups come out as Linke −0.72, Grüne −0.39, SPD −0.41, CDU/CSU +0.03, AfD +0.81.
Before using the model, note:
- The six scores measure approval, not authorship. Each one is an independent sigmoid probability that members of that party would applaud or agree with the text. They don't sum to 1, and several parties can score high at once. To ask "which party wrote this?", look at the highest score, but expect errors between parties with similar positions.
- The left–right score is relative to six German parties. −1 means "like Die Linke", +1 "like the AfD", 0 "like the FDP". Positions further out can't be distinguished from these end points, and parties outside the six (e.g. BSW, Freie Wähler) aren't modelled.
- Use it for aggregates, not verdicts on single texts. Short texts are noisy (see the tweet results). The paper's validation averages over hundreds of articles per newspaper. Don't use the score to judge individuals.
- Filter out non-political text first. The model was trained only on political text and gives arbitrary scores to anything else. The paper keeps only texts with P(politic) ≥ 0.8 from
german_politic_DeBERTa-v2-base.- Despite the repository name, this is a DeBERTa-v2 xlarge model (GeBERTa-xlarge, 887 M parameters, hidden size 1,536). The paper calls it "DeBERTa-large" and lists 435 M parameters; the uploaded checkpoint is the xlarge one.
- Only the first 512 tokens are read. 57% of the Bundestag speeches and 50% of the political news articles used in the evaluation below are longer, so the model judges them by their beginning. Pass
truncation=True.
Quick start
import numpy as np
import torch
from transformers import pipeline
classifier = pipeline(
"text-classification",
model="SinclairSchneider/german_politic_direction_DeBERTa-large",
dtype=torch.bfloat16,
top_k=None, # return the scores of all six parties
)
# Party positions on the left-right half-circle, calibrated for this model
# (see "From party scores to an ideology score" below).
PARTIES = ["DIE LINKE", "BÜNDNIS 90/DIE GRÜNEN", "SPD", "FDP", "CDU/CSU", "AfD"] # left -> right
ANGLES = np.array([-1.0, -0.9744292185507617, -0.740913657001974, 0.25, 0.6714926780690442, 1.0])
VECTORS = np.stack([np.sin(ANGLES * np.pi / 2), np.cos(ANGLES * np.pi / 2)], axis=1)
def party_scores(text):
"""Independent probabilities (sigmoid) that each party would applaud / agree with the text."""
return {d["label"]: d["score"] for d in classifier([text], truncation=True, max_length=512)[0]}
def ideology(text):
"""-1 = left (Die Linke) ... 0 = liberal centre (FDP) ... +1 = right (AfD)."""
p = party_scores(text)
x, y = np.array([p[party] for party in PARTIES]) @ VECTORS
return float(np.arctan2(x, y) / (np.pi / 2))
text = "Wir brauchen eine Vermögensteuer, um den Sozialstaat nachhaltig zu finanzieren."
print({party: round(score, 3) for party, score in party_scores(text).items()})
print(round(ideology(text), 3))
# {'DIE LINKE': 0.927, 'SPD': 0.63, 'BÜNDNIS 90/DIE GRÜNEN': 0.541, 'FDP': 0.064, 'CDU/CSU': 0.056, 'AfD': 0.018}
# -0.885
The same ideology() function on a few hand-written statements:
-0.885 Wir brauchen eine Vermögensteuer, um den Sozialstaat nachhaltig zu finanzieren.
-0.960 Mietendeckel und mehr gemeinnütziger Wohnungsbau sollen Wohnen bezahlbar machen.
-0.900 Die Energiewende muss mit massiven öffentlichen Investitionen beschleunigt werden.
+0.288 Die soziale Marktwirtschaft braucht moderne Regeln und weniger Bürokratie.
-0.540 Gezielte Entlastungen für kleine und mittlere Einkommen stärken die Mitte.
+0.146 Bildungsoffensive: Basiskompetenzen sichern, Weiterbildung im Beruf fördern.
+0.991 Deutsche Leitkultur und Sprache stärker in öffentlichen Einrichtungen betonen.
+0.752 Grenzschutz an EU-Außengrenzen verstärken, Sekundärmigration begrenzen.
+0.975 Identitätspolitik an Schulen und Behörden zurückfahren, Fokus auf Leistungsprinzip.
These outputs were produced on a GPU in bfloat16 with transformers 5.15 / torch 2.13; other hardware or versions can differ in the second or third decimal place.
Scoring many texts
import numpy as np
import torch
from transformers import pipeline
classifier = pipeline("text-classification", model="SinclairSchneider/german_politic_direction_DeBERTa-large",
dtype=torch.bfloat16, top_k=None)
PARTIES = ["DIE LINKE", "BÜNDNIS 90/DIE GRÜNEN", "SPD", "FDP", "CDU/CSU", "AfD"]
ANGLES = np.array([-1.0, -0.9744292185507617, -0.740913657001974, 0.25, 0.6714926780690442, 1.0])
VECTORS = np.stack([np.sin(ANGLES * np.pi / 2), np.cos(ANGLES * np.pi / 2)], axis=1)
texts = [...] # e.g. all political articles of one outlet or one week of posts
results = classifier(texts, truncation=True, max_length=512, batch_size=16)
P = np.array([[{d["label"]: d["score"] for d in r}[p] for p in PARTIES] for r in results]) # (n_texts, 6)
xy = P @ VECTORS
scores = np.arctan2(xy[:, 0], xy[:, 1]) / (np.pi / 2) # one score per text
print(scores.mean()) # the paper compares averages like this one with outlet-level ratings
Without the pipeline
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
repo = "SinclairSchneider/german_politic_direction_DeBERTa-large"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForSequenceClassification.from_pretrained(repo, dtype=torch.bfloat16).eval()
texts = ["Die Schuldenbremse muss reformiert werden, damit wir in Schulen und Schienen investieren können."]
enc = tokenizer(texts, truncation=True, max_length=512, padding=True, return_tensors="pt")
with torch.no_grad():
probs = torch.sigmoid(model(**enc).logits.float()) # sigmoid, not softmax: the labels are independent
for i, label in model.config.id2label.items():
print(f"{label:>22} {probs[0, i]:.3f}")
Model details
| Developed by | Sinclair Schneider, Florian Steuber, João A. G. Schneider, Gabi Dreo Rodosek — Research Institute CODE, Bundeswehr University Munich |
| Model type | DebertaV2ForSequenceClassification, multi-label (6 independent sigmoid outputs) |
| Base model | ikim-uk-essen/geberta-xlarge |
| Parameters | 887 M |
| Language | German |
| Labels | 0 AfD · 1 BÜNDNIS 90/DIE GRÜNEN · 2 CDU/CSU · 3 DIE LINKE · 4 FDP · 5 SPD |
| Max input length | 512 tokens |
| Training data | SinclairSchneider/trainset_political_party_big (DOI 10.57967/hf/4924) |
| Data cut-off | Bundestag speeches up to 27 Sep 2024, Wahl-O-Mat up to 22 Sep 2024, manifestos up to the 2021 federal election |
| Trained | November 2024 |
| License | CC-BY-4.0 |
| Paper | Ideology Prediction of German Political Texts (ICWSM 2026) |
Uses
Direct use
- Measuring the average political leaning of a collection of German texts, such as the political articles of a newspaper, the posts of a forum or a time window of social media posts, after filtering for political content. This is how the paper validates the method.
- Tracking shifts in such averages over time.
- Retrieving texts from one part of the spectrum, for example all texts close to the CDU/CSU but not to the AfD, using the six party scores or a band of the ideology score.
Downstream use
- As a starting point for fine-tuning on newer data. The paper recommends retraining when the political landscape shifts, e.g. to add BSW or to cover the 21st Bundestag.
Out-of-scope use
- Judging, profiling or ranking individual people by their political views, or any automated decision about individuals.
- Blocking or filtering content based on its political direction without human review.
- Fact-checking or measuring quality. The score says which parties would applaud a text, not whether it is true, extreme or legitimate.
- Non-German text, or politics outside Germany.
Training data
| Label | Source | How the label was derived |
|---|---|---|
| Party X = 1 | Bundestag plenary protocols | X applauded during the speech (from comments like "(Beifall bei der SPD)" in the official protocols). Heckling (−1) and silence (0) both become 0 for training. |
| Party X = 1 | Wahl-O-Mat (qual-o-mat-data) | X answered "agree" to the thesis; "neutral" and "disagree" become 0. |
| Party X = 1 | Manifesto Project | X is the author of the manifesto section. |
Every augmented text (summary, paraphrase, synthetic tweet) inherits the labels of its original. Only texts with at least one positive party are included. On average, 2.2 of the 6 parties are positive per text; the positive rate ranges from 24.8% (AfD) to 47.8% (SPD).
| Source | Type in the dataset | Rows | Median words |
|---|---|---|---|
| Bundestag speeches (WP 19–20, 24 Oct 2017 – 27 Sep 2024) and Wahl-O-Mat theses (56 elections, 2002 – Sep 2024) | original |
33,997 | 610 |
| Party manifestos (Manifesto Project, federal elections 1998–2021), one row per section | original (with year/party) |
4,428 | 157 |
| LLM summaries in four registers (child, teenager, adult, eloquent) of speeches and manifesto sections | summary_* |
145,457 | 62–83 |
| LLM paraphrases of the Wahl-O-Mat theses in the same four registers (≈10 per thesis and register) | sentences_* |
69,818 | 38–43 |
| LLM-generated tweets about speeches / theses | synthetic_tweets |
338,765 | 27 |
| LLM-generated tweets about manifesto sections | synthetic_tweet |
44,252 | 26 |
| Total | 636,717 | 31 |
The summaries of speeches were generated with Llama-3.1-70B-Instruct (GPTQ-INT4); the Wahl-O-Mat paraphrases, synthetic tweets and manifesto summaries with Llama-3.1-405B-Instruct. The dataset card describes collection and known limitations in detail.
Training procedure
Preprocessing
The senti_* columns were binarized (1 if the value is +1, otherwise 0) and the text column was used without further cleaning. Maximum length: 512 tokens (all examples padded to 512). The data was split randomly 80/20 with train_test_split(test_size=0.2) and no seed, giving 509,374 training and 127,343 evaluation texts. That split can't be reproduced exactly, and paraphrases of the same original can end up on both sides.
Training hyperparameters
| Hyperparameter | Value |
|---|---|
| Objective | binary cross-entropy over 6 labels (problem_type="multi_label_classification") |
| Optimizer | AdamW (adamw_torch, Trainer default) |
| Learning rate | 5e-5 (Trainer default), linear decay, no warm-up |
| Weight decay | 0.01 |
| Epochs | 8 were run (7,952 steps, 994 per epoch); the published weights are from epoch 4 |
| Batch size | 8 per GPU × 16 gradient-accumulation steps × 4 GPUs = 512 |
| Precision | float32 |
| Evaluation / checkpointing | every epoch, metric = eval micro-F1 at threshold 0.5 |
| Published checkpoint | The published weights are checkpoint-3979, the end of epoch 4 of an 8-epoch run, which is also where the eval loss was lowest (0.367). The run is identified from the checkpoint path stored in config.json (05_train_new_model/politic_Deberta-xlarge_multilabel_bundestag_and_wahlomat/checkpoint-3979) and the 994 steps per epoch logged for the 4-GPU workstation run |
| Training script | 05_train_new_model/deberta_multilabel_full_speech.py |
Training curve
From the Weights & Biases log of the training run, on the random 20% evaluation split:
| Epoch | Step | Eval loss | Micro-F1 | Precision | Recall | ROC-AUC ⁽ᵃ⁾ | Exact match |
|---|---|---|---|---|---|---|---|
| 1 | 994 | 0.4205 | 0.7164 | 0.7456 | 0.6895 | 0.7749 | 0.3606 |
| 2 | 1,989 | 0.3920 | 0.7413 | 0.7762 | 0.7095 | 0.7940 | 0.4121 |
| 3 | 2,984 | 0.3695 | 0.7599 | 0.7995 | 0.7241 | 0.8081 | 0.4486 |
| 4 (published) | 3,979 | 0.3668 | 0.7722 | 0.8051 | 0.7418 | 0.8176 | 0.4706 |
| 5 | 4,974 | 0.3679 | 0.7827 | 0.8083 | 0.7586 | 0.8259 | 0.4867 |
| 6 | 5,969 | 0.3753 | 0.7919 | 0.8137 | 0.7712 | 0.8332 | 0.5007 |
| 7 | 6,964 | 0.3991 | 0.7958 | 0.8128 | 0.7794 | 0.8364 | 0.5114 |
| 8 | 7,952 | 0.4195 | 0.7977 | 0.8117 | 0.7841 | 0.8380 | 0.5133 |
⁽ᵃ⁾ Computed by the training script from thresholded 0/1 predictions, so it is a balanced accuracy rather than a ranking AUC.
Speeds, sizes, times
| Training hardware | 4 × NVIDIA RTX 6000 Ada Generation (48 GB) |
| Training time | 62.6 h wall-clock for the whole run (8 epochs; the published epoch-4 checkpoint was reached after about half of it) |
| Inference throughput | 70 texts/s on one RTX 6000 Ada (bfloat16, length-sorted batches, 18,860 texts of mean 680–850 tokens), peak memory 5.3 GB |
| Checkpoint | float32 safetensors |
From party scores to an ideology score
Each party gets a direction on a half-circle: Die Linke points left, the FDP up, the AfD right, and the others in between. The six scores weight these unit vectors, the vectors are added up, and the angle of the sum, divided by 90°, is the ideology score:
where $a_p \in [-1, 1]$ is the party's angle in units of 90° (the ANGLES in the code):
| Linke | Grüne | SPD | FDP | CDU/CSU | AfD | |
|---|---|---|---|---|---|---|
| Default angle (Wahl-O-Mat distances) | -1.000 | -0.724 | -0.598 | +0.000 | +0.421 | +1.000 |
| Calibrated angle (this model, used in the code) | -1.000 | -0.974 | -0.741 | +0.250 | +0.671 | +1.000 |
| … in degrees | -90.0° | -87.7° | -66.7° | +22.5° | +60.4° | +90.0° |
The default angles come from Wahl-O-Mat answers. Die Linke (−90°), the FDP (0°) and the AfD (+90°) are fixed. The Grüne and SPD are placed between Linke and FDP, and the CDU/CSU between FDP and AfD, in proportion to how often their answers differ (identical answer = 0, one side neutral = 0.5, opposite = 1). For example, Grüne and Linke differ on 20.8% of jointly answered theses, Grüne and FDP on 54.7%, so the Grüne sit at −90° · 0.547 / (0.208 + 0.547) ≈ −65.2°.
The paper then fine-tunes the four inner angles for each model (±0.25 at most, Linke and AfD fixed) so that newspaper averages match the Medienkompass.org ratings. These calibrated angles are used in the code above. Several of them sit on the ±0.25 bound (Grüne at the left bound, FDP and CDU/CSU at the right bound), so the bound, not the data, determines them. Because they were fitted on the same 33 outlets that are used to evaluate them, the in-sample error (0.175) is optimistic. Re-fitting on 32 outlets and testing on the 33rd gives 0.187, compared with 0.192 for the default angles.
Evaluation
Comparison with the other models of the collection
| Model | Params | Max input | In-distribution micro-F1 ¹ | Bundestag 2025–26 macro-AUC ² | Wahl-O-Mat 2025–26 macro-AUC ³ | Newspapers MAE, leave-one-out ⁴ | Tweets accuracy ⁵ | Throughput ⁶ |
|---|---|---|---|---|---|---|---|---|
| gemma-2-9b_v0.1 | 9.24 B | 2,048 | 0.820 | 0.797 | 0.850 | 0.177 | 0.390 | 7/s |
| gemma-2-2b | 2.61 B | 8,192 | 0.753 | 0.845 | 0.862 | 0.169 | 0.400 | 22/s |
| DeBERTa-large (GeBERTa-xlarge) (this model) | 887 M | 512 | 0.772 | 0.807 | 0.857 | 0.187 | 0.422 | 70/s |
| EuroBERT-610m | 610 M | 8,192 | 0.787 | 0.800 | 0.828 | 0.196 | 0.336 | 64/s |
| EuroBERT-210m | 212 M | 8,192 | 0.729 | 0.833 | 0.801 | 0.215 | 0.310 | 201/s |
¹ Eval micro-F1 of the published checkpoint on the random 20% split used during training (from the training logs; see the caveats in Evaluation). ² Bundestag speeches from the 21st legislative period (25 Mar 2025 – 5 Nov 2026), all after the training cut-off; target = "party applauded during the speech"; mean ROC-AUC over the five parliamentary groups. ³ The 266 theses of the 7 Wahl-O-Mat editions published after the training cut-off (federal election 2025 and six state elections 2025/26); target = "party agrees"; mean ROC-AUC over the six parties. ⁴ Mean absolute error between the average ideology score of a newspaper's political articles and its Medienkompass.org rating (33 outlets, scale −1…1), with the party angles re-fitted on 32 outlets and tested on the held-out one. All five models scored the same 9,535 articles (up to 300 per outlet). ⁵ 60,000 political tweets by members of the Bundestag (10,000 per party); share where the highest-scoring party is the author's party (chance = 0.167). ⁶ Texts per second on one RTX 6000 Ada in bfloat16 for the 18,860 test texts of ² and ³ (mean 680–850 tokens), length-sorted batches.
1. In-distribution: the random 20% split used during training
The training curve above shows micro-F1 0.772 for the published checkpoint. The paper reports 0.84 for this model. The paper value comes from a different, earlier training run: a 4-epoch run on a smaller version of the training data (about 240,000 texts, 375 steps per epoch, 12 h 03 min — the training time listed in the paper). The published checkpoint was trained on the full 636,717-text dataset and reaches 0.772 on its own evaluation split.
Caveats: the split is random, so the summaries, paraphrases and tweets derived from one speech are spread across train and test. The model has effectively seen close paraphrases of most test texts. The test texts also come from the same period and sources as the training texts. The next sections use data the model can't have seen.
2. Bundestag speeches after the training cut-off
Setup. All plenary protocols of the 20th legislative period from 9 Oct 2024 and of the 21st period up to 5 Nov 2026 were downloaded from the Bundestag's open-data service. For every speech (≥ 200 characters), the speaker's paragraphs were extracted, and a party counts as positive if a comment within the speech records its applause ("Beifall bei der AfD", "Beifall bei Abgeordneten der SPD", …). This reproduces the training labels only approximately: on 858 training-period speeches, the extracted applause agrees with the training labels for 84–96% of speech–party pairs, depending on the party. To separate the effect of time from that of the label definition, the first row applies the same procedure to 1,446 speeches from sessions that were part of the training data. The FDP has no seats in the 21st Bundestag and is left out there.
| Test set | Speeches | Linke | Grüne | SPD | FDP | CDU/CSU | AfD | Macro-AUC | Micro-F1 @0.5 | Precision | Recall |
|---|---|---|---|---|---|---|---|---|---|---|---|
| WP 20, 2023–Sep 2024 — seen in training (reference) | 1,446 | 0.857 | 0.872 | 0.910 | 0.877 | 0.875 | 0.892 | 0.880 | 0.787 | 0.817 | 0.758 |
| WP 20, Oct 2024 – Mar 2025 (after cut-off) | 3,028 | 0.825 | 0.756 | 0.832 | 0.736 | 0.799 | 0.867 | 0.803 | 0.644 | 0.603 | 0.691 |
| WP 21, Mar 2025 – Nov 2026 (after cut-off) | 14,111 | 0.840 | 0.742 | 0.813 | – | 0.730 | 0.910 | 0.807 | 0.652 | 0.677 | 0.630 |
| WP 21, only speeches with ≥ 1 applause ⁺ | 12,053 | 0.850 | 0.753 | 0.848 | – | 0.793 | 0.916 | 0.832 | 0.696 | 0.777 | 0.630 |
⁺ The training data contained only speeches with at least one applauding party.
ROC-AUC measures how well the scores rank speeches that a party applauded above those it didn't (0.5 = random, 1 = perfect). Micro-F1/precision/recall use the 0.5 threshold.
3. Wahl-O-Mat theses after the training cut-off
Setup. The 266 theses of the seven Wahl-O-Mat editions published after the training data ends: federal election 2025, Hamburg 2025, Baden-Württemberg, Rhineland-Palatinate, Saxony-Anhalt, Berlin and Mecklenburg-Western Pomerania 2026. All six parties answered all 266 theses. Target: the party answered "agree".
| Linke | Grüne | SPD | FDP | CDU/CSU | AfD | Macro | |
|---|---|---|---|---|---|---|---|
| ROC-AUC (agree vs. neutral/disagree) | 0.937 | 0.898 | 0.791 | 0.835 | 0.849 | 0.833 | 0.857 |
| ROC-AUC (agree vs. disagree, neutral removed) | 0.950 | 0.912 | 0.817 | 0.873 | 0.873 | 0.849 | 0.879 |
For 85.3% of the theses, the party with the highest score agreed with the thesis (all parties together agreed with 53.4% of thesis–party pairs). Micro-F1 at 0.5: 0.807.
4. Newspapers (the paper's out-of-domain benchmark)
Setup (as in the paper). For 33 German news outlets, the political articles (P(politic) ≥ 0.8 by german_politic_DeBERTa-v2-base) are scored and averaged per outlet. The averages are compared with the outlets' ratings on Medienkompass.org (1 = extreme left … 7 = extreme right, mapped linearly to −1…1). The error is the mean absolute difference over the 33 outlets.
| MAE, default angles | MAE, calibrated angles (fitted on all 33 outlets) | MAE, leave-one-outlet-out | Pearson r (outlet means vs. ratings) | |
|---|---|---|---|---|
| Paper (Table 3) | 0.197 | 0.182 | – | – |
| Stored per-article scores, sample of ≈ 24,000 rows per outlet | 0.199 | 0.185 | 0.194 | 0.806 |
| Re-scored, same 9,535 articles for all five models | 0.192 | 0.175 | 0.187 | 0.817 |
The second row uses the per-article scores stored in the NLP-UniBW/*_classified datasets for a sample of 24 row groups per outlet; it matches the paper within ±0.004. The third row re-scores up to 300 political articles per outlet with the published weights, identically for all five models of the collection. A fresh run of the published weights reproduces the stored scores at r ≥ 0.999 for every party.
Per-outlet results (re-scored articles)
| Outlet | Medienkompass (1–7) | Target (−1…1) | Model, default angles | Model, calibrated angles |
|---|---|---|---|---|
| linksunten | 2.0 | -0.67 | -0.43 | -0.47 |
| jungle world | 2.3 | -0.57 | -0.01 | +0.00 |
| junge welt | 2.4 | -0.53 | -0.28 | -0.28 |
| neues deutschland | 2.6 | -0.47 | -0.32 | -0.35 |
| der freitag | 2.7 | -0.43 | -0.14 | -0.15 |
| taz | 2.8 | -0.40 | -0.22 | -0.23 |
| vice | 2.8 | -0.40 | -0.08 | -0.04 |
| nachdenkseiten | 3.1 | -0.30 | -0.01 | -0.00 |
| frankfurter rundschau | 3.4 | -0.20 | -0.08 | +0.01 |
| spiegel | 3.5 | -0.17 | +0.05 | +0.11 |
| sueddeutsche | 3.5 | -0.17 | -0.13 | -0.09 |
| wdr | 3.5 | -0.17 | -0.11 | -0.06 |
| zeit | 3.6 | -0.13 | -0.19 | -0.18 |
| tagesspiegel | 3.6 | -0.13 | -0.09 | -0.03 |
| tagesschau | 3.7 | -0.10 | -0.16 | -0.13 |
| ndr | 3.7 | -0.10 | -0.16 | -0.15 |
| deutschlandfunk | 3.8 | -0.07 | -0.09 | -0.06 |
| stern | 3.8 | -0.07 | -0.07 | -0.01 |
| mdr | 4.1 | +0.03 | -0.12 | -0.10 |
| ntv | 4.3 | +0.10 | -0.08 | -0.03 |
| br | 4.4 | +0.13 | -0.06 | +0.02 |
| rtl | 4.5 | +0.17 | -0.11 | -0.05 |
| frankfurter allgemeine | 4.5 | +0.17 | +0.02 | +0.08 |
| welt | 4.8 | +0.27 | +0.03 | +0.08 |
| focus | 4.9 | +0.30 | +0.01 | +0.13 |
| cicero | 4.9 | +0.30 | +0.11 | +0.15 |
| russia today | 5.1 | +0.37 | +0.26 | +0.30 |
| mm news | 5.1 | +0.37 | -0.04 | +0.02 |
| bild | 5.2 | +0.40 | -0.03 | +0.05 |
| achgut | 5.2 | +0.40 | +0.05 | +0.10 |
| tichyseinblick | 5.5 | +0.50 | +0.52 | +0.57 |
| junge freiheit | 5.8 | +0.60 | +0.34 | +0.41 |
| compact | 6.0 | +0.67 | +0.53 | +0.57 |
5. Tweets by members of the Bundestag
Setup. As in the paper, but sampled anew: from tweets_from_members_of_the_german_bundestag, original tweets (no retweets, URLs removed, ≥ 3 words) with P(politic) ≥ 0.8, 10,000 random tweets per party (2011 – Jan 2026). A prediction counts as correct if the highest of the six scores belongs to the author's party. The paper reports only the three best in-domain models on its own sample of 535,200 tweets.
| Minimum words | all | ≥ 20 | ≥ 30 | ≥ 50 | ≥ 75 | ≥ 100 |
|---|---|---|---|---|---|---|
| Tweets | 60,000 | 32,245 | 20,634 | 1,151 | 693 | 449 |
| Accuracy (top party = author's party) | 0.422 | 0.471 | 0.490 | 0.726 | 0.799 | 0.817 |
Macro-F1 over the six parties: 0.412. Per party, the share of tweets correctly attributed is: Linke 0.38, Grüne 0.23, SPD 0.58, FDP 0.30, CDU/CSU 0.33, AfD 0.71. The median tweet has 21 words; only 1.9% have 50 words or more.
6. Party order on 2025/26 speeches
Mean ideology score of all speeches of the 21st Bundestag by the speaker's parliamentary group:
| Speaker's group | Linke | Grüne | SPD | CDU/CSU | AfD |
|---|---|---|---|---|---|
| Speeches | 1,560 | 2,038 | 2,118 | 3,272 | 2,918 |
| Mean score, calibrated angles (as in the code) | -0.72 | -0.39 | -0.41 | +0.03 | +0.81 |
| Mean score, default angles | -0.66 | -0.36 | -0.36 | -0.07 | +0.75 |
Bias, risks, and limitations
- Applause is a proxy. Parliamentary groups applaud their own speakers and their coalition partners, and react to tone as well as content. The model partly learns "who is speaking" and "who governs with whom" in 2017–2024, not only positions. After the 2025 election the government and opposition changed, and the out-of-time results above show the resulting drop, especially for the Grüne and the CDU/CSU.
- Fixed set of six parties and a one-dimensional scale. The scale ends at Die Linke and the AfD. Die Linke and the AfD agree on some issues (e.g. arms deliveries) for opposite reasons, and a single dimension can't represent that. BSW and other parties are missing.
- LLM-generated training text. Most training texts are summaries, paraphrases and tweets written by Llama 3.1. They may carry the LLM's own wording and biases, and they make the in-distribution scores optimistic.
- Low scores everywhere make the ideology score meaningless. The score is the direction of the summed party vectors. If the model thinks no party would applaud (all six scores low), that direction is set by small, noisy values. Check the largest party score, or the length of the summed vector, before trusting the score of a single text.
- Short and quoted texts. Accuracy on short tweets is low, and the model can't tell whether a quoted position is endorsed or criticised.
- Novel or abstract statements. The model knows what German parties said in parliament and in manifestos. Ideas outside that agenda get unreliable scores; the paper's example is Proudhon's "Property is theft", which its Gemma-2-9B model scores at +0.78 (right-wing).
- Calibration on the evaluation outlets. The calibrated angles were fitted on the newspaper benchmark; use the leave-one-out numbers as the realistic estimate.
- Time. Political language and coalitions change. The paper recommends retraining at regular intervals.
Recommendations
- Filter for political content first, then average over many texts.
- Report the six party scores alongside the ideology score; they carry more information than one number.
- Validate on a labelled sample of your own domain, especially for texts written after 2024.
- Don't use the outputs to make decisions about individuals.
Environmental impact
- Hardware: 4 × NVIDIA RTX 6000 Ada Generation (48 GB).
- Training time: 62.6 h for the logged run.
- Energy: at most ≈ 75 kWh for the GPUs, assuming 4 GPUs at their full 300 W TDP for the whole run.
- Carbon emitted: ≈ 30 kg CO₂eq, assuming 0.4 kg CO₂eq/kWh (Lacoste et al., 2019). Earlier experimental runs aren't included.
Technical specifications
- Architecture: DeBERTa-v2 with 24 layers, hidden size 1,536, 24 heads, feed-forward 6,144, disentangled relative-position attention (c2p + p2c, 256 position buckets), SentencePiece vocabulary 128,101 (cased).
- Classification head:
ContextPooler(dense 1,536 → 1,536 + GELU on[CLS]) → dropout → linear 1,536 → 6. - Objective: binary cross-entropy with logits over 6 labels; inference applies a sigmoid per label.
Citation
If you use this model, please cite the paper:
@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}
}
Training data:
@misc{schneider_trainset_political_party_big,
author = {Schneider, Sinclair},
title = {German Political Party \& Stance Corpus (1998--2024)},
year = {2025},
publisher = {Hugging Face},
doi = {10.57967/hf/4924},
howpublished = {\url{https://huggingface.co/datasets/SinclairSchneider/trainset_political_party_big}}
}
Base model:
@inproceedings{dada2023geberta,
title = {On the Impact of Cross-Domain Data on {German} Language Models},
author = {Dada, Amin and Chen, Aokun and Peng, Cheng and Smith, Kaleb and Idrissi-Yaghir, Ahmad and Seibold, Constantin and Li, Jianning and Heiliger, Lars and Friedrich, Christoph and Truhn, Daniel and Egger, Jan and Bian, Jiang and Kleesiek, Jens and Wu, Yonghui},
booktitle = {Findings of the Association for Computational Linguistics: EMNLP 2023},
pages = {13801--13813},
year = {2023}
}
Model card authors and contact
Sinclair Schneider, Research Institute CODE, Bundeswehr University Munich. Questions and issues are welcome in the Community tab.
- Downloads last month
- 56
Model tree for SinclairSchneider/german_politic_direction_DeBERTa-large
Base model
ikim-uk-essen/geberta-xlargeDataset used to train SinclairSchneider/german_politic_direction_DeBERTa-large
Collection including SinclairSchneider/german_politic_direction_DeBERTa-large
Paper for SinclairSchneider/german_politic_direction_DeBERTa-large
Evaluation results
- Micro-F1 (threshold 0.5) on trainset_political_party_big (random 20% held-out split used during training)self-reported0.772
- Micro precision on trainset_political_party_big (random 20% held-out split used during training)self-reported0.805
- Micro recall on trainset_political_party_big (random 20% held-out split used during training)self-reported0.742
- Macro ROC-AUC (5 parliamentary groups) on Bundestag plenary protocols, 25 Mar 2025 - 5 Nov 2026 (applause parsed from the official XML)self-reported0.807
- Micro-F1 (threshold 0.5) on Bundestag plenary protocols, 25 Mar 2025 - 5 Nov 2026 (applause parsed from the official XML)self-reported0.652
- Macro ROC-AUC (6 parties) on Wahl-O-Mat, federal election 2025 + 6 state elections 2025/26 (266 theses)self-reported0.857
- MAE, leave-one-outlet-out calibrated angles (9,535 re-scored articles) on 33 German news outlets vs. Medienkompass.org ratingsself-reported0.187
- MAE, default angles on 33 German news outlets vs. Medienkompass.org ratingsself-reported0.192