Text Classification
Transformers
Joblib
Safetensors
bert
sentiment-analysis
finance
macroeconomics
climate
esg
policy
ensemble
dictionary
finbert
Eval Results (legacy)
text-embeddings-inference
Instructions to use peyterho/macro-sentiment-finbert with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use peyterho/macro-sentiment-finbert with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="peyterho/macro-sentiment-finbert")# Load model directly from transformers import AutoTokenizer, AutoModelForSequenceClassification tokenizer = AutoTokenizer.from_pretrained("peyterho/macro-sentiment-finbert") model = AutoModelForSequenceClassification.from_pretrained("peyterho/macro-sentiment-finbert", device_map="auto") - Notebooks
- Google Colab
- Kaggle
v0.3.0: Add OOD eval, custom fine-tuning, multilingual sections to README
Browse files
README.md
CHANGED
|
@@ -10,6 +10,7 @@ tags:
|
|
| 10 |
- climate
|
| 11 |
- esg
|
| 12 |
- macroeconomics
|
|
|
|
| 13 |
datasets:
|
| 14 |
- nickmuchi/financial-classification
|
| 15 |
- zeroshot/twitter-financial-news-sentiment
|
|
@@ -21,6 +22,13 @@ metrics:
|
|
| 21 |
- f1
|
| 22 |
language:
|
| 23 |
- en
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
pipeline_tag: text-classification
|
| 25 |
model-index:
|
| 26 |
- name: macro-sentiment-finbert
|
|
@@ -41,181 +49,164 @@ model-index:
|
|
| 41 |
- name: F1 Macro (FinBERT)
|
| 42 |
type: f1
|
| 43 |
value: 0.881
|
| 44 |
-
- name: Accuracy (ClimateBERT)
|
| 45 |
-
type: accuracy
|
| 46 |
-
value: 0.889
|
| 47 |
-
- name: F1 Macro (ClimateBERT)
|
| 48 |
-
type: f1
|
| 49 |
-
value: 0.872
|
| 50 |
---
|
| 51 |
|
| 52 |
# π¦ Macroeconomic Sentiment Analysis
|
| 53 |
|
| 54 |
-
**What it does:** Takes any financial or economic text and tells you whether the sentiment is positive, negative, or neutral β plus whether the tone is hawkish/dovish, whether it signals a crisis, and how much it relates to climate/ESG.
|
| 55 |
|
| 56 |
-
**Who it's for:** Anyone analyzing news articles, central bank statements, earnings reports, financial tweets, or climate/ESG disclosures.
|
| 57 |
|
| 58 |
---
|
| 59 |
|
| 60 |
## The Simple Way (3 lines of Python)
|
| 61 |
|
| 62 |
-
If you just want to classify financial text as positive/negative/neutral, use the fine-tuned models directly. No cloning, no extra packages β just `pip install transformers torch` and go:
|
| 63 |
-
|
| 64 |
```python
|
| 65 |
from transformers import pipeline
|
| 66 |
|
| 67 |
-
|
| 68 |
-
classifier = pipeline("text-classification", model="peyterho/finbert-macro-sentiment") # 110M, fast
|
| 69 |
-
# classifier = pipeline("text-classification", model="peyterho/financial-roberta-large-macro-sentiment") # 355M, most accurate
|
| 70 |
-
# classifier = pipeline("text-classification", model="peyterho/climatebert-macro-sentiment") # 82M, climate-focused
|
| 71 |
|
| 72 |
-
# Classify any financial text
|
| 73 |
classifier("Tesla shares surged 15% after beating earnings expectations.")
|
| 74 |
# β [{'label': 'positive', 'score': 0.998}]
|
| 75 |
|
| 76 |
classifier("Markets crashed amid recession fears and massive layoffs.")
|
| 77 |
# β [{'label': 'negative', 'score': 0.997}]
|
| 78 |
-
|
| 79 |
-
classifier("The company reported quarterly revenue in line with expectations.")
|
| 80 |
-
# β [{'label': 'neutral', 'score': 0.95}]
|
| 81 |
```
|
| 82 |
|
| 83 |
-
That's it. Each model outputs one of three labels: **positive**, **negative**, or **neutral**, with a confidence score.
|
| 84 |
-
|
| 85 |
### Which model should I pick?
|
| 86 |
|
| 87 |
| Model | Size | Speed | Accuracy | Best for |
|
| 88 |
|-------|------|-------|----------|----------|
|
| 89 |
| [`peyterho/finbert-macro-sentiment`](https://huggingface.co/peyterho/finbert-macro-sentiment) | 110M | Fast | 89.7% | General financial text β good default choice |
|
| 90 |
-
| [`peyterho/financial-roberta-large-macro-sentiment`](https://huggingface.co/peyterho/financial-roberta-large-macro-sentiment) | 355M | Slower | **91.3%** | When accuracy matters most
|
| 91 |
-
| [`peyterho/climatebert-macro-sentiment`](https://huggingface.co/peyterho/climatebert-macro-sentiment) | 82M | Fastest | 88.9% | Climate
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
-
|
|
|
|
|
|
|
| 94 |
|
| 95 |
```python
|
| 96 |
-
|
| 97 |
-
"Fed raised rates by 75bps citing persistent inflation.",
|
| 98 |
-
"Renewable energy investments hit record highs.",
|
| 99 |
-
"Lehman Brothers filed for bankruptcy.",
|
| 100 |
-
]
|
| 101 |
-
results = classifier(texts)
|
| 102 |
-
for text, result in zip(texts, results):
|
| 103 |
-
print(f"{result['label']:>8} ({result['score']:.2f}) {text}")
|
| 104 |
-
# β neutral (0.91) Fed raised rates by 75bps citing persistent inflation.
|
| 105 |
-
# positive (0.57) Renewable energy investments hit record highs.
|
| 106 |
-
# negative (0.99) Lehman Brothers filed for bankruptcy.
|
| 107 |
-
```
|
| 108 |
|
| 109 |
-
|
| 110 |
|
| 111 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
-
|
|
|
|
|
|
|
| 114 |
|
| 115 |
-
#
|
|
|
|
|
|
|
|
|
|
| 116 |
|
|
|
|
| 117 |
```bash
|
| 118 |
-
pip install
|
|
|
|
| 119 |
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
cd macro-sentiment-finbert
|
| 124 |
```
|
| 125 |
|
| 126 |
-
|
| 127 |
|
| 128 |
-
|
| 129 |
-
from macro_sentiment import MacroSentimentPipeline
|
| 130 |
|
| 131 |
-
|
| 132 |
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
```
|
| 137 |
|
| 138 |
-
|
| 139 |
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
result.climate_exposure # 0.0 (no climate topic) to 1.0 (climate-heavy)
|
| 146 |
-
result.detected_domain # "policy", "climate", "financial_news", or "social"
|
| 147 |
-
result.confidence # 0.0 to 1.0 β how confident the model is
|
| 148 |
-
```
|
| 149 |
|
| 150 |
-
|
| 151 |
|
| 152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
-
|
| 155 |
-
2. **Scores it** with four financial dictionaries (Loughran-McDonald, Henry, climate exposure, macro policy)
|
| 156 |
-
3. **Combines** both signals with crisis-adaptive weighting β when crisis terms are detected, dictionary signals get more weight (AI models can struggle with novel crisis patterns)
|
| 157 |
|
| 158 |
-
##
|
| 159 |
|
| 160 |
-
|
| 161 |
|
| 162 |
-
```
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
print(result.policy_stance) # -0.5 β dovish
|
| 167 |
```
|
| 168 |
|
| 169 |
-
|
|
|
|
| 170 |
|
| 171 |
-
|
| 172 |
|
| 173 |
-
|
|
|
|
|
|
|
| 174 |
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
|
| 182 |
---
|
| 183 |
|
| 184 |
-
##
|
| 185 |
|
| 186 |
-
|
| 187 |
-
from macro_sentiment import TransformerEnsemble
|
| 188 |
|
| 189 |
-
|
| 190 |
-
|
|
|
|
|
|
|
|
|
|
| 191 |
|
| 192 |
-
#
|
| 193 |
-
ensemble = TransformerEnsemble(
|
| 194 |
-
finbert_model="peyterho/finbert-macro-sentiment",
|
| 195 |
-
roberta_model="peyterho/financial-roberta-large-macro-sentiment",
|
| 196 |
-
climatebert_model="peyterho/climatebert-macro-sentiment",
|
| 197 |
-
)
|
| 198 |
-
|
| 199 |
-
# Route automatically to the best head for the input
|
| 200 |
-
result = ensemble.score_routed("ECB signals patience on rate cuts.")
|
| 201 |
-
print(result["head_used"]) # "policy"
|
| 202 |
-
print(result["sentiment_score"]) # [-1, +1]
|
| 203 |
-
|
| 204 |
-
# Or score with all three heads at once
|
| 205 |
-
result = ensemble.score_all("Markets tumbled on trade war fears.")
|
| 206 |
-
print(result["ensemble_mean"])
|
| 207 |
-
```
|
| 208 |
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
|
|
|
|
|
|
| 212 |
|
| 213 |
-
|
| 214 |
-
finbert_model=ORIGINAL_FINBERT,
|
| 215 |
-
roberta_model=ORIGINAL_ROBERTA,
|
| 216 |
-
climatebert_model=ORIGINAL_CLIMATEBERT,
|
| 217 |
-
)
|
| 218 |
-
```
|
| 219 |
|
| 220 |
---
|
| 221 |
|
|
@@ -223,51 +214,39 @@ ensemble = TransformerEnsemble(
|
|
| 223 |
|
| 224 |
| Field | Range | What it means |
|
| 225 |
|-------|-------|---------------|
|
| 226 |
-
| `macro_sentiment` | -1 to +1 | Overall sentiment
|
| 227 |
-
| `policy_stance` | -1 to +1 | Dovish
|
| 228 |
-
| `financial_sentiment` | -1 to +1 | Raw
|
| 229 |
-
| `climate_sentiment` | -1 to +1 | Climate risk β 0 β
|
| 230 |
-
| `crisis_signal` | 0 to 1 |
|
| 231 |
-
| `uncertainty` | 0 to 1 |
|
| 232 |
-
| `confidence` | 0 to 1 |
|
| 233 |
-
| `climate_exposure` | 0 to 1 |
|
| 234 |
-
| `detected_domain` | text |
|
| 235 |
-
| `head_used` | text | Which
|
| 236 |
-
| `lm_polarity` | -1 to +1 | Loughran-McDonald dictionary score |
|
| 237 |
-
| `henry_polarity` | -1 to +1 | Henry (2008) earnings tone score |
|
| 238 |
-
|
| 239 |
-
---
|
| 240 |
-
|
| 241 |
-
## Training Data
|
| 242 |
-
|
| 243 |
-
~20,000 training samples from 5 public datasets:
|
| 244 |
-
|
| 245 |
-
| Dataset | Samples | What it covers |
|
| 246 |
-
|---------|---------|---------------|
|
| 247 |
-
| [Financial PhraseBank](https://huggingface.co/datasets/nickmuchi/financial-classification) | 5,057 | News headlines about companies |
|
| 248 |
-
| [Twitter Financial News](https://huggingface.co/datasets/zeroshot/twitter-financial-news-sentiment) | 11,931 | Financial tweets with $cashtags |
|
| 249 |
-
| [Auditor Sentiment](https://huggingface.co/datasets/FinanceInc/auditor_sentiment) | 4,846 | Audit and accounting reports |
|
| 250 |
-
| [FiQA](https://huggingface.co/datasets/pauri32/fiqa-2018) | 1,213 | Financial questions and opinions |
|
| 251 |
-
| [Climate Sentiment](https://huggingface.co/datasets/climatebert/climate_sentiment) | 1,320 | Climate and ESG disclosures |
|
| 252 |
|
| 253 |
## File Structure
|
| 254 |
|
| 255 |
```
|
| 256 |
macro_sentiment/
|
| 257 |
-
βββ __init__.py # Package entry point
|
| 258 |
βββ dictionaries.py # Four financial dictionaries
|
| 259 |
-
βββ transformers_ensemble.py #
|
| 260 |
βββ pipeline.py # Full pipeline combining everything
|
|
|
|
| 261 |
βββ data_prep.py # Dataset loading
|
| 262 |
βββ train_meta.py # Meta-classifier training
|
|
|
|
|
|
|
| 263 |
```
|
| 264 |
|
| 265 |
## References
|
| 266 |
|
| 267 |
-
- Araci (2019). [FinBERT](https://arxiv.org/abs/1908.10063)
|
| 268 |
-
- Loughran & McDonald (2011).
|
| 269 |
-
- Henry (2008).
|
| 270 |
-
- Sautner et al. (2023).
|
|
|
|
| 271 |
|
| 272 |
## License
|
| 273 |
Apache 2.0
|
|
|
|
| 10 |
- climate
|
| 11 |
- esg
|
| 12 |
- macroeconomics
|
| 13 |
+
- multilingual
|
| 14 |
datasets:
|
| 15 |
- nickmuchi/financial-classification
|
| 16 |
- zeroshot/twitter-financial-news-sentiment
|
|
|
|
| 22 |
- f1
|
| 23 |
language:
|
| 24 |
- en
|
| 25 |
+
- ar
|
| 26 |
+
- de
|
| 27 |
+
- es
|
| 28 |
+
- fr
|
| 29 |
+
- hi
|
| 30 |
+
- it
|
| 31 |
+
- pt
|
| 32 |
pipeline_tag: text-classification
|
| 33 |
model-index:
|
| 34 |
- name: macro-sentiment-finbert
|
|
|
|
| 49 |
- name: F1 Macro (FinBERT)
|
| 50 |
type: f1
|
| 51 |
value: 0.881
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
---
|
| 53 |
|
| 54 |
# π¦ Macroeconomic Sentiment Analysis
|
| 55 |
|
| 56 |
+
**What it does:** Takes any financial or economic text and tells you whether the sentiment is positive, negative, or neutral β plus whether the tone is hawkish/dovish, whether it signals a crisis, and how much it relates to climate/ESG. Now supports **multilingual text** (v0.3.0).
|
| 57 |
|
| 58 |
+
**Who it's for:** Anyone analyzing news articles, central bank statements, earnings reports, financial tweets, or climate/ESG disclosures β in English or other languages.
|
| 59 |
|
| 60 |
---
|
| 61 |
|
| 62 |
## The Simple Way (3 lines of Python)
|
| 63 |
|
|
|
|
|
|
|
| 64 |
```python
|
| 65 |
from transformers import pipeline
|
| 66 |
|
| 67 |
+
classifier = pipeline("text-classification", model="peyterho/finbert-macro-sentiment")
|
|
|
|
|
|
|
|
|
|
| 68 |
|
|
|
|
| 69 |
classifier("Tesla shares surged 15% after beating earnings expectations.")
|
| 70 |
# β [{'label': 'positive', 'score': 0.998}]
|
| 71 |
|
| 72 |
classifier("Markets crashed amid recession fears and massive layoffs.")
|
| 73 |
# β [{'label': 'negative', 'score': 0.997}]
|
|
|
|
|
|
|
|
|
|
| 74 |
```
|
| 75 |
|
|
|
|
|
|
|
| 76 |
### Which model should I pick?
|
| 77 |
|
| 78 |
| Model | Size | Speed | Accuracy | Best for |
|
| 79 |
|-------|------|-------|----------|----------|
|
| 80 |
| [`peyterho/finbert-macro-sentiment`](https://huggingface.co/peyterho/finbert-macro-sentiment) | 110M | Fast | 89.7% | General financial text β good default choice |
|
| 81 |
+
| [`peyterho/financial-roberta-large-macro-sentiment`](https://huggingface.co/peyterho/financial-roberta-large-macro-sentiment) | 355M | Slower | **91.3%** | When accuracy matters most |
|
| 82 |
+
| [`peyterho/climatebert-macro-sentiment`](https://huggingface.co/peyterho/climatebert-macro-sentiment) | 82M | Fastest | 88.9% | Climate/ESG text |
|
| 83 |
+
|
| 84 |
+
---
|
| 85 |
+
|
| 86 |
+
## Multilingual Support (v0.3.0)
|
| 87 |
|
| 88 |
+
The pipeline now auto-detects non-English text and routes it to an XLM-RoBERTa multilingual sentiment model.
|
| 89 |
+
|
| 90 |
+
**Supported languages:** English, Arabic, French, German, Hindi, Italian, Portuguese, Spanish β plus reasonable performance on many others.
|
| 91 |
|
| 92 |
```python
|
| 93 |
+
from macro_sentiment import TransformerEnsemble
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
|
| 95 |
+
ensemble = TransformerEnsemble(device="cpu")
|
| 96 |
|
| 97 |
+
# German β auto-routed to multilingual head
|
| 98 |
+
result = ensemble.score_routed("EZB signalisiert Geduld bei Zinssenkungen.")
|
| 99 |
+
print(result["head_used"]) # "multilingual"
|
| 100 |
+
print(result["detected_language"]) # "de"
|
| 101 |
+
print(result["sentiment_score"]) # [-1, +1]
|
| 102 |
|
| 103 |
+
# French
|
| 104 |
+
result = ensemble.score_routed("La BCE maintient ses taux directeurs inchangΓ©s.")
|
| 105 |
+
print(result["head_used"]) # "multilingual"
|
| 106 |
|
| 107 |
+
# English β still routed to domain-specific heads as before
|
| 108 |
+
result = ensemble.score_routed("Fed raised rates by 75bps.")
|
| 109 |
+
print(result["head_used"]) # "policy" (RoBERTa-Large)
|
| 110 |
+
```
|
| 111 |
|
| 112 |
+
For better language detection accuracy, install `langdetect`:
|
| 113 |
```bash
|
| 114 |
+
pip install langdetect
|
| 115 |
+
```
|
| 116 |
|
| 117 |
+
To disable multilingual routing (v0.2.0 behavior):
|
| 118 |
+
```python
|
| 119 |
+
ensemble = TransformerEnsemble(multilingual_model=None)
|
|
|
|
| 120 |
```
|
| 121 |
|
| 122 |
+
---
|
| 123 |
|
| 124 |
+
## Fine-Tune on Your Own Data
|
|
|
|
| 125 |
|
| 126 |
+
Got your own labelled financial text? Fine-tune any head in one command:
|
| 127 |
|
| 128 |
+
```bash
|
| 129 |
+
python -m macro_sentiment.finetune \
|
| 130 |
+
--data my_labels.csv \
|
| 131 |
+
--text-column headline \
|
| 132 |
+
--label-column sentiment \
|
| 133 |
+
--base-model peyterho/finbert-macro-sentiment \
|
| 134 |
+
--output my-org/my-custom-model \
|
| 135 |
+
--push-to-hub
|
| 136 |
```
|
| 137 |
|
| 138 |
+
**Your CSV/TSV/JSON/JSONL just needs two columns:**
|
| 139 |
|
| 140 |
+
| headline | sentiment |
|
| 141 |
+
|----------|-----------|
|
| 142 |
+
| Company profits soared to record highs | positive |
|
| 143 |
+
| Stock prices crashed amid panic selling | negative |
|
| 144 |
+
| Revenue remained flat quarter over quarter | neutral |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
+
Labels accept: `positive`/`negative`/`neutral` (or `bullish`/`bearish`, `pos`/`neg`, `risk`/`opportunity`, or integers `0`/`1`/`2`).
|
| 147 |
|
| 148 |
+
**Options:**
|
| 149 |
+
```
|
| 150 |
+
--base-model Which model to start from (default: peyterho/finbert-macro-sentiment)
|
| 151 |
+
--epochs Training epochs (default: 4)
|
| 152 |
+
--lr Learning rate (default: 2e-5)
|
| 153 |
+
--batch-size Batch size (default: 32)
|
| 154 |
+
--max-length Max token length (default: 128)
|
| 155 |
+
--push-to-hub Push result to Hugging Face Hub
|
| 156 |
+
--output Local dir or Hub model ID
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
The script auto-detects label remapping from the model's config, applies class weighting for imbalanced data, and selects the best checkpoint by macro F1.
|
| 160 |
|
| 161 |
+
---
|
|
|
|
|
|
|
| 162 |
|
| 163 |
+
## The Full Pipeline
|
| 164 |
|
| 165 |
+
For hawkish/dovish stance, crisis detection, climate exposure, and uncertainty scoring:
|
| 166 |
|
| 167 |
+
```bash
|
| 168 |
+
pip install transformers torch pysentiment2 scikit-learn numpy datasets huggingface_hub
|
| 169 |
+
python -c "from huggingface_hub import snapshot_download; snapshot_download('peyterho/macro-sentiment-finbert', local_dir='macro-sentiment-finbert')"
|
| 170 |
+
cd macro-sentiment-finbert
|
|
|
|
| 171 |
```
|
| 172 |
|
| 173 |
+
```python
|
| 174 |
+
from macro_sentiment import MacroSentimentPipeline
|
| 175 |
|
| 176 |
+
pipe = MacroSentimentPipeline(device="cpu")
|
| 177 |
|
| 178 |
+
result = pipe("The Federal Reserve raised rates by 75bps citing persistent inflation.")
|
| 179 |
+
print(result.summary())
|
| 180 |
+
# β Sentiment: ... | Policy: Very Hawkish (+0.999) | Crisis: Normal | Domain: policy
|
| 181 |
|
| 182 |
+
result.macro_sentiment # -1.0 to +1.0
|
| 183 |
+
result.policy_stance # -1.0 (dovish) to +1.0 (hawkish)
|
| 184 |
+
result.crisis_signal # 0.0 (calm) to 1.0 (crisis)
|
| 185 |
+
result.uncertainty # 0.0 (certain) to 1.0 (uncertain)
|
| 186 |
+
result.climate_exposure # 0.0 to 1.0
|
| 187 |
+
```
|
| 188 |
|
| 189 |
---
|
| 190 |
|
| 191 |
+
## Accuracy
|
| 192 |
|
| 193 |
+
### In-domain (4,333 test samples from training datasets)
|
|
|
|
| 194 |
|
| 195 |
+
| Model | Accuracy | F1 Macro |
|
| 196 |
+
|-------|----------|----------|
|
| 197 |
+
| RoBERTa-Large (fine-tuned) | **91.3%** | **0.902** |
|
| 198 |
+
| FinBERT (fine-tuned) | 89.7% | 0.881 |
|
| 199 |
+
| ClimateBERT (fine-tuned) | 88.9% | 0.872 |
|
| 200 |
|
| 201 |
+
### Out-of-domain (datasets NOT in training)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
|
| 203 |
+
| Model | Stock News (30K) | JB PhraseBank (785) |
|
| 204 |
+
|-------|------------------|---------------------|
|
| 205 |
+
| RoBERTa-Large | **72.1% acc / 0.727 F1** | **94.1% acc / 0.936 F1** |
|
| 206 |
+
| FinBERT | 67.8% / 0.677 | 92.4% / 0.913 |
|
| 207 |
+
| ClimateBERT | 64.7% / 0.644 | 92.5% / 0.921 |
|
| 208 |
|
| 209 |
+
The Stock News OOD dataset ([ic-fspml/stock_news_sentiment](https://huggingface.co/datasets/ic-fspml/stock_news_sentiment)) uses 5-class labels mapped to 3-class, with different annotation conventions β the 20pp accuracy drop is expected and honest. The JB PhraseBank OOD dataset ([Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75](https://huggingface.co/datasets/Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75)) is a similar domain and holds up well.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
---
|
| 212 |
|
|
|
|
| 214 |
|
| 215 |
| Field | Range | What it means |
|
| 216 |
|-------|-------|---------------|
|
| 217 |
+
| `macro_sentiment` | -1 to +1 | Overall sentiment |
|
| 218 |
+
| `policy_stance` | -1 to +1 | Dovish β 0 β Hawkish |
|
| 219 |
+
| `financial_sentiment` | -1 to +1 | Raw sentiment from active head |
|
| 220 |
+
| `climate_sentiment` | -1 to +1 | Climate risk β 0 β opportunity |
|
| 221 |
+
| `crisis_signal` | 0 to 1 | Crisis intensity |
|
| 222 |
+
| `uncertainty` | 0 to 1 | Uncertainty level |
|
| 223 |
+
| `confidence` | 0 to 1 | Model confidence |
|
| 224 |
+
| `climate_exposure` | 0 to 1 | Climate topic density |
|
| 225 |
+
| `detected_domain` | text | policy / climate / financial_news / social |
|
| 226 |
+
| `head_used` | text | Which model was activated |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
|
| 228 |
## File Structure
|
| 229 |
|
| 230 |
```
|
| 231 |
macro_sentiment/
|
| 232 |
+
βββ __init__.py # Package entry point (v0.3.0)
|
| 233 |
βββ dictionaries.py # Four financial dictionaries
|
| 234 |
+
βββ transformers_ensemble.py # Four AI heads + language-aware router
|
| 235 |
βββ pipeline.py # Full pipeline combining everything
|
| 236 |
+
βββ finetune.py # Custom fine-tuning CLI
|
| 237 |
βββ data_prep.py # Dataset loading
|
| 238 |
βββ train_meta.py # Meta-classifier training
|
| 239 |
+
eval_results.json # In-domain metrics
|
| 240 |
+
eval_ood_results.json # Out-of-domain metrics
|
| 241 |
```
|
| 242 |
|
| 243 |
## References
|
| 244 |
|
| 245 |
+
- Araci (2019). [FinBERT](https://arxiv.org/abs/1908.10063)
|
| 246 |
+
- Loughran & McDonald (2011). *Journal of Finance*
|
| 247 |
+
- Henry (2008). *Journal of Business Communication*
|
| 248 |
+
- Sautner et al. (2023). *Review of Financial Studies*
|
| 249 |
+
- Barbieri et al. (2022). [XLM-T: Multilingual Language Models for Twitter](https://arxiv.org/abs/2104.12250)
|
| 250 |
|
| 251 |
## License
|
| 252 |
Apache 2.0
|