Fine-tuned IndoBERT for sentiment analysis of Indonesian police-related news articles. Trained on full article text (title + fulltext, untruncated) rather than a short extracted excerpt — full context proved essential for distinguishing sentiment classes in this domain (see optimization report for the ablation that established this).
1from transformers import AutoTokenizer, AutoModelForSequenceClassification
2import torch
3
4model_name = "AzrilFahmiardi/sdd-sentiment-kepolisian"
5tokenizer = AutoTokenizer.from_pretrained(model_name)
6model = AutoModelForSequenceClassification.from_pretrained(model_name)
7
8device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
9model = model.to(device)
1def analyze_sentiment(title: str, fulltext: str) -> dict:
2 text = f"{title} {fulltext}"
3 inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=512).to(device)
4
5 with torch.no_grad():
6 outputs = model(**inputs)
7 logits = outputs.logits
8
9 probabilities = torch.softmax(logits, dim=-1)[0].cpu()
10 predicted_class = logits.argmax(-1).item()
11 predicted_label = model.config.id2label[predicted_class]
12 confidence = probabilities[predicted_class].item()
13
14 return {
15 "sentiment": predicted_label,
16 "confidence": confidence
17 }
18
19# Example
20title = "Polisi Tangkap Pelaku Curanmor di Jakarta Selatan"
21fulltext = "Kepolisian Resor Jakarta Selatan berhasil menangkap seorang pelaku pencurian kendaraan bermotor yang telah beraksi di beberapa lokasi..."
22result = analyze_sentiment(title, fulltext)
23print(f"Sentiment: {result['sentiment']} ({result['confidence']:.2%})")
1{
2 "sentiment": "negatif",
3 "confidence": 0.8734
4}