File size: 2,809 Bytes
f2fd225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# app.py
from fastapi import FastAPI
from pydantic import BaseModel
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
import torch

app = FastAPI(title="Forex Sentiment API", version="1.0")

# ===============================
# Load Models
# ===============================
finbert_name = "ProsusAI/finbert"
longformer_name = "Miruzen/LongFormer_Skripsi"

device = 0 if torch.cuda.is_available() else -1

print("📥 Loading FinBERT model...")
finbert = pipeline("text-classification",
                    model=finbert_name,
                    tokenizer=finbert_name,
                    return_all_scores=True,
                    device=device)

print("📥 Loading LongFormer model...")
longformer = pipeline("text-classification",
                        model=longformer_name,
                        tokenizer=longformer_name,
                        return_all_scores=True,
                        device=device)

# ===============================
# Input Schema
# ===============================
class InputData(BaseModel):
    title: str | None = None
    content: str | None = None


# ===============================
# Helper Functions
# ===============================
def extract_scores(predictions):
    """Convert HF model output into {positive, neutral, negative} dict."""
    scores = {"positive": 0.0, "neutral": 0.0, "negative": 0.0}
    for item in predictions[0]:
        label = item["label"].lower()
        if "pos" in label:
            scores["positive"] = item["score"]
        elif "neg" in label:
            scores["negative"] = item["score"]
        elif "neu" in label:
            scores["neutral"] = item["score"]
    dominant = max(scores, key=scores.get)
    return {"label": dominant, "scores": scores}


# ===============================
# Main Endpoint
# ===============================
@app.post("/analyze")
def analyze(data: InputData):
    result = {}

    if data.title:
        finbert_out = finbert(data.title)
        result["title"] = extract_scores(finbert_out)

    if data.content:
        longformer_out = longformer(data.content)
        result["content"] = extract_scores(longformer_out)

    # Gabungkan menjadi mood_score sederhana
    mood_score = (
        result.get("title", {}).get("scores", {}).get("positive", 0)
        + result.get("content", {}).get("scores", {}).get("positive", 0)
        - result.get("title", {}).get("scores", {}).get("negative", 0)
        - result.get("content", {}).get("scores", {}).get("negative", 0)
    )

    return {
        "mood_score": mood_score,
        "details": result,
        "status": "ok"
    }


@app.get("/")
def root():
    return {"message": "Forex Sentiment API active!"}