A fine-tuned ModernBERT-base cross-encoder for binary classification of news article pairs. Given two articles (by headline, or headline + content), the model predicts whether they refer to the same real-world event.
This model is used in Stage 2 of a news article grouping research pipeline.
Model Description
The model classifies whether a pair of news articles refers to the same underlying real-world event — not just general semantic similarity, but whether both articles report on the same specific occurrence, potentially from different sources or perspectives.
Input structure:
(Article A, Article B) → [1 = Same Event | 0 = Different Event]
The model is built on top of answerdotai/ModernBERT-base, fine-tuned using task-specific layer unfreezing and a focal loss function to handle class imbalance.
How to Use
Installation
pip install transformers torch
Predict with the Model
python
1import torch
2import torch.nn.functional as F
3from transformers import AutoTokenizer, AutoModelForSequenceClassification
45MODEL_NAME ="Juanillaberia/articles-pairs-event-detection"67tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)8model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME)9model.eval()1011defpredict_same_event(headline_a:str, headline_b:str)->dict:12"""
13 Predicts whether two article headlines refer to the same real-world event.
1415 Args:
16 headline_a: Headline of the first article.
17 headline_b: Headline of the second article.
1819 Returns:
20 Dictionary with predicted label and probabilities.
21 """22 inputs = tokenizer(23 text=headline_a,24 text_pair=headline_b,25 return_tensors="pt",26 truncation=True,27 max_length=12828)2930with torch.no_grad():31 outputs = model(**inputs)32 logits = outputs.logits
33 probs = F.softmax(logits, dim=-1)3435 predicted_class = torch.argmax(probs, dim=-1).item()36 labels ={0:"Different Event",1:"Same Event"}3738return{39"label": labels[predicted_class],40"score": probs[0][predicted_class].item(),41"probabilities":{42"Different Event": probs[0][0].item(),43"Same Event": probs[0][1].item()44}45}4647# Example usage48headline_a ="Government announces new climate policy targeting carbon emissions"49headline_b ="New climate bill signed into law by administration"5051result = predict_same_event(headline_a, headline_b)52print(result)53# {'label': 'Same Event', 'score': 0.87, 'probabilities': {'Different Event': 0.13, 'Same Event': 0.87}}
Optional: Apply Temporal Adjustment
If you have access to the publication dates of both articles, you can apply a post-hoc temporal adjustment to improve precision:
python
1from datetime import datetime
23defpredict_with_date_adjustment(4 headline_a:str,5 headline_b:str,6 date_a:str,7 date_b:str,8 lambda_:float=0.20,9 threshold:float=0.4510)->dict:11"""
12 Predicts same-event with temporal adjustment based on publication date difference.
1314 Args:
15 headline_a: Headline of the first article.
16 headline_b: Headline of the second article.
17 date_a: Publication date of article A (format: 'YYYY-MM-DD').
18 date_b: Publication date of article B (format: 'YYYY-MM-DD').
19 lambda_: Decay factor for temporal adjustment (default: 0.20).
20 threshold: Classification threshold after adjustment (default: 0.45).
21 """22 inputs = tokenizer(23 text=headline_a,24 text_pair=headline_b,25 return_tensors="pt",26 truncation=True,27 max_length=12828)2930with torch.no_grad():31 outputs = model(**inputs)32 logits = outputs.logits
33 prob_same_event = F.softmax(logits, dim=-1)[0][1]3435 diff_days =abs((36 datetime.strptime(date_a,"%Y-%m-%d")- datetime.strptime(date_b,"%Y-%m-%d")37).days)3839 adjusted_prob = prob_same_event * torch.exp(torch.tensor(-lambda_ * diff_days))40 predicted =int(adjusted_prob.item()>= threshold)41 labels ={0:"Different Event",1:"Same Event"}4243return{44"label": labels[predicted],45"adjusted_score": adjusted_prob.item(),46"raw_score": prob_same_event.item(),47"diff_days": diff_days
48}4950# Example usage51result = predict_with_date_adjustment(52 headline_a="Government announces new climate policy",53 headline_b="New climate bill signed into law",54 date_a="2024-03-01",55 date_b="2024-03-02"56)57print(result)
Task head: Standard Hugging Face sequence classification head
Fine-tuning strategy: Embeddings and lower transformer layers are frozen; only the top 3 layers (19–21) and the classification head are trained
Loss function: Focal loss with class weights [0.18, 0.82] to address class imbalance
Max sequence length: 128 tokens (headlines only)
Parameter Summary
Parameter Type
Count
Total
149,606,402
Trainable
15,638,018
Frozen
133,968,384
Hyperparameters (selected via Optuna HPO)
Hyperparameter
Value
Epochs
2
Train Batch Size
32
Gradient Accumulation
2
Learning Rate
3.538e-05
Weight Decay
0.002508
Warmup Ratio
0.1014
HPO was run on a NVIDIA L4 GPU (22.5 GB VRAM, 53 GB system RAM) using 10 Optuna trials with TPE sampler and Median Pruner.
Evaluation Results
Experiment 1: Headlines-Only (~20k samples) — Best Configuration
After threshold tuning (threshold = 0.55):
Metric
Value
Eval Loss
0.0261
Precision
0.8927
Recall
0.8789
F1-Score
0.8838
Accuracy
0.91
Per-class breakdown:
Class
Precision
Recall
F1
Support
Different Event
0.94
0.95
0.94
1656
Same Event
0.74
0.72
0.73
350
Weighted Avg
0.91
0.91
0.91
2006
Experiment 5: Post-Hoc Date Adjustment (λ=0.20, threshold=0.45)
Incorporating the publication date difference as a post-hoc feature further improves performance:
Class
Precision
Recall
F1
Support
Different Event
0.95
0.95
0.95
1656
Same Event
0.75
0.76
0.76
350
Accuracy
0.92
2006
Weighted Avg
0.92
0.92
0.92
2006
The date adjustment results in ~3% F1 improvement while simultaneously reducing both false positives and false negatives.
Experiment Summary
Experiment
F1-Score
Notes
Headlines-Only (~20k)
0.91
Best standalone model
Headlines + Content (~8k)
0.83
Content adds noise, not signal
Content-Only (~8k)
0.41
Confirms headlines are key
Headlines-Only reduced (~8k)
~0.87
Dataset size has minor effect
Headlines + Date Adjustment
0.92
Best overall — recommended configuration
Dataset
The model was trained on a custom dataset of article pairs collected from approximately 40 news outlets, with binary labels indicating whether each pair refers to the same real-world event.
Headlines-only dataset: ~20,056 pairs
Headlines + Content dataset: ~8,284 pairs
@inproceedings {Laban2021NewsHG,
title={News Headline Grouping as a Challenging NLU Task},
author={Laban, Philippe and Bandarkar, Lucas and Hearst, Marti A},
booktitle={NAACL 2021},
publisher = {Association for Computational Linguistics},
year={2021}
}
Intended Use & Limitations
Intended for:
News deduplication and clustering pipelines
Event-centric article grouping
Research on media coverage analysis
Limitations:
Trained primarily on English-language news headlines
Performance may degrade on non-English or domain-specific content
Full article content was found to reduce performance in experiments — headlines only is recommended
The model may struggle with events that are semantically very similar but distinct (e.g., recurring political debates)