IndoRoBERTa Financial Sentiment v2
Fine-tuned Indonesian financial sentiment classifier built on top of ihsan31415/indo-roBERTa-financial-sentiment, which itself derives from w11wo/indonesian-roberta-base-sentiment-classifier.
Model Details
Label Mapping
⚠️ Non-standard label order — inherited from the base model.
Training Data
This model was fine-tuned on a combination of three datasets, augmented with synthetic data:
Data Augmentation
Three augmentation methods were used to balance class distribution:
- Gemini Synthetic Generation (
gemini-2.5-flash) — Generated structured financial news sentences targeting underrepresented classes
- GPT-2 Prompt Completion (
indonesian-nlp/gpt2-medium-indonesian) — Diverse paraphrasing from financial prompt templates
- RoBERTa Masked Augmentation — Strategic token masking with protected financial keywords (tickers, directional terms)
Final Dataset Distribution
Training Configuration
TrainingArguments(
per_device_train_batch_size=64,
gradient_accumulation_steps=4, # Effective batch size: 256
num_train_epochs=15, # With early stopping (patience=3)
learning_rate=1e-5, # Lower LR for continued fine-tuning
weight_decay=0.01,
warmup_ratio=0.1,
lr_scheduler_type="cosine",
metric_for_best_model="f1",
fp16=True,
)
Training Progress
Evaluation Results
Per-Class Performance
Confusion Matrix
Usage
Pipeline API
from transformers import pipeline
classifier = pipeline(
"sentiment-analysis",
model="will702/indo-roBERTa-financial-sentiment-v2"
)
result = classifier("IHSG ditutup menguat 1.5% didorong aksi beli investor asing")
# {'label': 'LABEL_0', 'score': 0.98} → Positive
Manual Inference
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
model = AutoModelForSequenceClassification.from_pretrained(
"will702/indo-roBERTa-financial-sentiment-v2"
)
tokenizer = AutoTokenizer.from_pretrained(
"will702/indo-roBERTa-financial-sentiment-v2"
)
text = "Rupiah melemah tajam terhadap dolar AS akibat sentimen global"
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
outputs = model(**inputs)
label_map = {0: "Positive", 1: "Neutral", 2: "Negative"}
predicted = torch.argmax(outputs.logits, dim=1).item()
print(f"Sentiment: {label_map[predicted]}")
Improvements Over Base Model
Limitations
- Primarily trained on formal financial news — may underperform on very informal social media text or slang
- Label mapping is non-standard (0=Positive) — ensure downstream systems account for this
- Augmented data includes synthetic samples which may not perfectly reflect real-world distribution
Citation
@misc{indo_roberta_fin_v2_2026,
title = {IndoRoBERTa Financial Sentiment v2},
author = {Gregorius Willson},
howpublished = {\url{https://huggingface.co/will702/indo-roBERTa-financial-sentiment-v2}},
year = {2026},
note = {Fine-tuned from ihsan31415/indo-roBERTa-financial-sentiment with multi-source data and augmentation},
}
Acknowledgments