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
File size: 8,671 Bytes
4068b1c 522f497 4068b1c 522f497 4068b1c f385a4c 33afa05 522f497 33afa05 522f497 eee5a39 f385a4c eee5a39 f385a4c 33afa05 f385a4c 33afa05 522f497 f385a4c 33afa05 f385a4c 522f497 f385a4c 522f497 f385a4c 522f497 eee5a39 522f497 f385a4c 522f497 f385a4c 522f497 f385a4c 522f497 eee5a39 522f497 eee5a39 522f497 33afa05 522f497 eee5a39 33afa05 522f497 eee5a39 522f497 33afa05 522f497 33afa05 522f497 33afa05 522f497 eee5a39 522f497 eee5a39 522f497 eee5a39 522f497 eee5a39 522f497 eee5a39 522f497 f385a4c 522f497 eee5a39 522f497 f385a4c eee5a39 522f497 eee5a39 522f497 eee5a39 522f497 f385a4c 522f497 f385a4c 33afa05 522f497 eee5a39 522f497 eee5a39 522f497 eee5a39 522f497 33afa05 522f497 33afa05 522f497 33afa05 f385a4c 33afa05 f385a4c 33afa05 f385a4c 522f497 33afa05 522f497 f385a4c 522f497 f385a4c 522f497 f385a4c 522f497 33afa05 f385a4c 33afa05 522f497 33afa05 | 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | ---
library_name: transformers
license: apache-2.0
tags:
- text-classification
- sentiment-analysis
- finance
- finbert
- roberta
- climate
- esg
- macroeconomics
- multilingual
datasets:
- nickmuchi/financial-classification
- zeroshot/twitter-financial-news-sentiment
- FinanceInc/auditor_sentiment
- pauri32/fiqa-2018
- climatebert/climate_sentiment
metrics:
- accuracy
- f1
language:
- en
- ar
- de
- es
- fr
- hi
- it
- pt
pipeline_tag: text-classification
model-index:
- name: macro-sentiment-finbert
results:
- task:
type: text-classification
name: Financial Sentiment Analysis
metrics:
- name: Accuracy (RoBERTa-Large)
type: accuracy
value: 0.913
- name: F1 Macro (RoBERTa-Large)
type: f1
value: 0.902
- name: Accuracy (FinBERT)
type: accuracy
value: 0.897
- name: F1 Macro (FinBERT)
type: f1
value: 0.881
---
# π¦ Macroeconomic Sentiment Analysis
**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).
**Who it's for:** Anyone analyzing news articles, central bank statements, earnings reports, financial tweets, or climate/ESG disclosures β in English or other languages.
---
## The Simple Way (3 lines of Python)
```python
from transformers import pipeline
classifier = pipeline("text-classification", model="peyterho/finbert-macro-sentiment")
classifier("Tesla shares surged 15% after beating earnings expectations.")
# β [{'label': 'positive', 'score': 0.998}]
classifier("Markets crashed amid recession fears and massive layoffs.")
# β [{'label': 'negative', 'score': 0.997}]
```
### Which model should I pick?
| Model | Size | Speed | Accuracy | Best for |
|-------|------|-------|----------|----------|
| [`peyterho/finbert-macro-sentiment`](https://huggingface.co/peyterho/finbert-macro-sentiment) | 110M | Fast | 89.7% | General financial text β good default choice |
| [`peyterho/financial-roberta-large-macro-sentiment`](https://huggingface.co/peyterho/financial-roberta-large-macro-sentiment) | 355M | Slower | **91.3%** | When accuracy matters most |
| [`peyterho/climatebert-macro-sentiment`](https://huggingface.co/peyterho/climatebert-macro-sentiment) | 82M | Fastest | 88.9% | Climate/ESG text |
---
## Multilingual Support (v0.3.0)
The pipeline now auto-detects non-English text and routes it to an XLM-RoBERTa multilingual sentiment model.
**Supported languages:** English, Arabic, French, German, Hindi, Italian, Portuguese, Spanish β plus reasonable performance on many others.
```python
from macro_sentiment import TransformerEnsemble
ensemble = TransformerEnsemble(device="cpu")
# German β auto-routed to multilingual head
result = ensemble.score_routed("EZB signalisiert Geduld bei Zinssenkungen.")
print(result["head_used"]) # "multilingual"
print(result["detected_language"]) # "de"
print(result["sentiment_score"]) # [-1, +1]
# French
result = ensemble.score_routed("La BCE maintient ses taux directeurs inchangΓ©s.")
print(result["head_used"]) # "multilingual"
# English β still routed to domain-specific heads as before
result = ensemble.score_routed("Fed raised rates by 75bps.")
print(result["head_used"]) # "policy" (RoBERTa-Large)
```
For better language detection accuracy, install `langdetect`:
```bash
pip install langdetect
```
To disable multilingual routing (v0.2.0 behavior):
```python
ensemble = TransformerEnsemble(multilingual_model=None)
```
---
## Fine-Tune on Your Own Data
Got your own labelled financial text? Fine-tune any head in one command:
```bash
python -m macro_sentiment.finetune \
--data my_labels.csv \
--text-column headline \
--label-column sentiment \
--base-model peyterho/finbert-macro-sentiment \
--output my-org/my-custom-model \
--push-to-hub
```
**Your CSV/TSV/JSON/JSONL just needs two columns:**
| headline | sentiment |
|----------|-----------|
| Company profits soared to record highs | positive |
| Stock prices crashed amid panic selling | negative |
| Revenue remained flat quarter over quarter | neutral |
Labels accept: `positive`/`negative`/`neutral` (or `bullish`/`bearish`, `pos`/`neg`, `risk`/`opportunity`, or integers `0`/`1`/`2`).
**Options:**
```
--base-model Which model to start from (default: peyterho/finbert-macro-sentiment)
--epochs Training epochs (default: 4)
--lr Learning rate (default: 2e-5)
--batch-size Batch size (default: 32)
--max-length Max token length (default: 128)
--push-to-hub Push result to Hugging Face Hub
--output Local dir or Hub model ID
```
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.
---
## The Full Pipeline
For hawkish/dovish stance, crisis detection, climate exposure, and uncertainty scoring:
```bash
pip install transformers torch pysentiment2 scikit-learn numpy datasets huggingface_hub
python -c "from huggingface_hub import snapshot_download; snapshot_download('peyterho/macro-sentiment-finbert', local_dir='macro-sentiment-finbert')"
cd macro-sentiment-finbert
```
```python
from macro_sentiment import MacroSentimentPipeline
pipe = MacroSentimentPipeline(device="cpu")
result = pipe("The Federal Reserve raised rates by 75bps citing persistent inflation.")
print(result.summary())
# β Sentiment: ... | Policy: Very Hawkish (+0.999) | Crisis: Normal | Domain: policy
result.macro_sentiment # -1.0 to +1.0
result.policy_stance # -1.0 (dovish) to +1.0 (hawkish)
result.crisis_signal # 0.0 (calm) to 1.0 (crisis)
result.uncertainty # 0.0 (certain) to 1.0 (uncertain)
result.climate_exposure # 0.0 to 1.0
```
---
## Accuracy
### In-domain (4,333 test samples from training datasets)
| Model | Accuracy | F1 Macro |
|-------|----------|----------|
| RoBERTa-Large (fine-tuned) | **91.3%** | **0.902** |
| FinBERT (fine-tuned) | 89.7% | 0.881 |
| ClimateBERT (fine-tuned) | 88.9% | 0.872 |
### Out-of-domain (datasets NOT in training)
| Model | Stock News (30K) | JB PhraseBank (785) |
|-------|------------------|---------------------|
| RoBERTa-Large | **72.1% acc / 0.727 F1** | **94.1% acc / 0.936 F1** |
| FinBERT | 67.8% / 0.677 | 92.4% / 0.913 |
| ClimateBERT | 64.7% / 0.644 | 92.5% / 0.921 |
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.
---
## All Output Fields
| Field | Range | What it means |
|-------|-------|---------------|
| `macro_sentiment` | -1 to +1 | Overall sentiment |
| `policy_stance` | -1 to +1 | Dovish β 0 β Hawkish |
| `financial_sentiment` | -1 to +1 | Raw sentiment from active head |
| `climate_sentiment` | -1 to +1 | Climate risk β 0 β opportunity |
| `crisis_signal` | 0 to 1 | Crisis intensity |
| `uncertainty` | 0 to 1 | Uncertainty level |
| `confidence` | 0 to 1 | Model confidence |
| `climate_exposure` | 0 to 1 | Climate topic density |
| `detected_domain` | text | policy / climate / financial_news / social |
| `head_used` | text | Which model was activated |
## File Structure
```
macro_sentiment/
βββ __init__.py # Package entry point (v0.3.0)
βββ dictionaries.py # Four financial dictionaries
βββ transformers_ensemble.py # Four AI heads + language-aware router
βββ pipeline.py # Full pipeline combining everything
βββ finetune.py # Custom fine-tuning CLI
βββ data_prep.py # Dataset loading
βββ train_meta.py # Meta-classifier training
eval_results.json # In-domain metrics
eval_ood_results.json # Out-of-domain metrics
```
## References
- Araci (2019). [FinBERT](https://arxiv.org/abs/1908.10063)
- Loughran & McDonald (2011). *Journal of Finance*
- Henry (2008). *Journal of Business Communication*
- Sautner et al. (2023). *Review of Financial Studies*
- Barbieri et al. (2022). [XLM-T: Multilingual Language Models for Twitter](https://arxiv.org/abs/2104.12250)
## License
Apache 2.0
|