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
| library_name: transformers | |
| base_model: ProsusAI/finbert | |
| tags: | |
| - sentiment-analysis | |
| - finance | |
| - macroeconomics | |
| - climate | |
| - esg | |
| - policy | |
| - ensemble | |
| - dictionary | |
| - finbert | |
| - text-classification | |
| language: | |
| - en | |
| - ar | |
| - fr | |
| - de | |
| - hi | |
| - it | |
| - pt | |
| - es | |
| license: apache-2.0 | |
| datasets: | |
| - nickmuchi/financial-classification | |
| - zeroshot/twitter-financial-news-sentiment | |
| - FinanceInc/auditor_sentiment | |
| - pauri32/fiqa-2018 | |
| - climatebert/climate_sentiment | |
| metrics: | |
| - accuracy | |
| - f1 | |
| pipeline_tag: text-classification | |
| model-index: | |
| - name: macro-sentiment-finbert | |
| results: | |
| - task: | |
| type: text-classification | |
| name: Sentiment Analysis | |
| dataset: | |
| name: Combined Financial Sentiment (5 datasets) | |
| type: custom | |
| metrics: | |
| - type: accuracy | |
| value: 0.8973 | |
| name: Accuracy | |
| - type: f1 | |
| value: 0.8813 | |
| name: F1 (macro) | |
| - type: f1 | |
| value: 0.8984 | |
| name: F1 (weighted) | |
| - task: | |
| type: text-classification | |
| name: Sentiment Analysis (OOD) | |
| dataset: | |
| name: Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75 | |
| type: Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75 | |
| metrics: | |
| - type: accuracy | |
| value: 0.9236 | |
| name: Accuracy | |
| - type: f1 | |
| value: 0.9134 | |
| name: F1 (macro) | |
| - task: | |
| type: text-classification | |
| name: Sentiment Analysis (OOD) | |
| dataset: | |
| name: ic-fspml/stock_news_sentiment | |
| type: ic-fspml/stock_news_sentiment | |
| metrics: | |
| - type: accuracy | |
| value: 0.6781 | |
| name: Accuracy | |
| - type: f1 | |
| value: 0.6765 | |
| name: F1 (macro) | |
| # Macro Sentiment FinBERT | |
| **A multi-signal macroeconomic sentiment pipeline** that combines fine-tuned transformer ensembles with financial dictionaries and topic routing to produce structured sentiment analysis for financial news, central bank communications, climate/ESG reports, and social media. | |
| This repo hosts the **FinBERT head** (109M params, fine-tuned from [ProsusAI/finbert](https://huggingface.co/ProsusAI/finbert)) β the default routing target and backbone of the full pipeline. The complete system includes three additional transformer heads, four dictionary scorers, and a keyword-based topic router. | |
| ## Key Features | |
| - π¦ **Macro-aware** β outputs financial sentiment, monetary policy stance (dovish β hawkish), crisis signals, and uncertainty | |
| - π± **Climate/ESG scoring** β dedicated ClimateBERT head + Sautner-style exposure dictionary for climate risk vs. opportunity | |
| - π **Topic routing** β automatically selects the best transformer head based on text content (policy β RoBERTa-Large, climate β ClimateBERT, financial news β FinBERT) | |
| - π **Multilingual** β non-English text auto-routes to XLM-RoBERTa (8+ languages: EN, AR, FR, DE, HI, IT, PT, ES) | |
| - π **Dictionary layer** β Loughran-McDonald, Henry earnings tone, climate exposure, and macro policy dictionaries provide interpretable feature signals alongside neural predictions | |
| ## Architecture | |
| ``` | |
| ββββββββββββββββββββββββββββββββββββ | |
| β Input Text β | |
| ββββββββββββββββ¬ββββββββββββββββββββ | |
| β | |
| ββββββββββββββββββββββΌβββββββββββββββββββββ | |
| βΌ βΌ βΌ | |
| βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββ | |
| β Topic Router β β Dictionary β β Language β | |
| β (keywords) β β Scorers (Γ4) β β Detection β | |
| ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ βββββββββ¬ββββββββ | |
| β β β | |
| ββββββββββΌβββββββββββββββββββββΌβββββββββββββββββββββΌβββββββββ | |
| β Head Selection β | |
| β policy β RoBERTa-Large β climate β ClimateBERT β | |
| β financial β FinBERT β β non-English β XLM-RoBERTa β | |
| ββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ¬βββββββββ | |
| β β | |
| ββββββββββΌβββββββββ ββββββββββΌβββββββββ | |
| β Transformer β β Dictionary β | |
| β Score [-1,+1] β β Composite β | |
| ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ | |
| β β | |
| ββββββββββββββββ¬ββββββββββββββββββββββββββ | |
| βΌ | |
| ββββββββββββββββββββββββββββββββ | |
| β Weighted Fusion β | |
| β (crisis-adaptive weights) β | |
| ββββββββββββββββ¬ββββββββββββββββ | |
| βΌ | |
| ββββββββββββββββββββββββββββββββ | |
| β MacroSentimentResult β | |
| β β’ macro_sentiment [-1,+1] β | |
| β β’ policy_stance [-1,+1] β | |
| β β’ crisis_signal [0,1] β | |
| β β’ climate_sentiment [-1,+1] β | |
| β β’ confidence [0,1] β | |
| β β’ detected_domain β | |
| ββββββββββββββββββββββββββββββββ | |
| ``` | |
| The fusion weights are **crisis-adaptive**: when the crisis dictionary fires strongly, more weight shifts to the dictionary composite (up to 75% dict / 25% transformer), since crisis language often carries clearer signal through keywords than neural softmax probabilities. | |
| ## Ensemble Components | |
| | Head | Model | Params | Base | Role | | |
| |---|---|---|---|---| | |
| | **FinBERT** β | [peyterho/finbert-macro-sentiment](https://huggingface.co/peyterho/finbert-macro-sentiment) | 109M | [ProsusAI/finbert](https://huggingface.co/ProsusAI/finbert) | Default β financial news, tweets | | |
| | **RoBERTa-Large** | [peyterho/financial-roberta-large-macro-sentiment](https://huggingface.co/peyterho/financial-roberta-large-macro-sentiment) | 355M | [soleimanian/financial-roberta-large-sentiment](https://huggingface.co/soleimanian/financial-roberta-large-sentiment) | Policy/macro text | | |
| | **ClimateBERT** | [peyterho/climatebert-macro-sentiment](https://huggingface.co/peyterho/climatebert-macro-sentiment) | 82M | [climatebert/distilroberta-base-climate-sentiment](https://huggingface.co/climatebert/distilroberta-base-climate-sentiment) | Climate/ESG text | | |
| | **XLM-RoBERTa** | [cardiffnlp/twitter-xlm-roberta-base-sentiment-multilingual](https://huggingface.co/cardiffnlp/twitter-xlm-roberta-base-sentiment-multilingual) | 278M | β | Non-English text (8+ languages) | | |
| | Dictionary | Based On | Signal | | |
| |---|---|---| | |
| | **Loughran-McDonald** | Loughran & McDonald (2011) | Financial polarity, subjectivity | | |
| | **Henry** | Henry (2008) β earnings tone | Earnings press release tone | | |
| | **Climate Exposure** | Sautner et al. (2023) style | Climate risk vs. opportunity density | | |
| | **Macro Policy** | Custom | Hawkish/dovish stance, crisis intensity, uncertainty | | |
| ## Quick Start | |
| There are two ways to use this model β pick the one that fits your needs: | |
| ### Option A: Standalone FinBERT (classification only) | |
| If you just need positive/negative/neutral labels, use the model directly β no repo cloning required: | |
| ```python | |
| # pip install transformers torch | |
| from transformers import pipeline | |
| classifier = pipeline("text-classification", model="peyterho/macro-sentiment-finbert", top_k=None) | |
| result = classifier("The Federal Reserve signaled a pause in rate hikes amid cooling inflation.") | |
| print(result) | |
| # [[{'label': 'positive', 'score': 0.72}, {'label': 'neutral', 'score': 0.21}, {'label': 'negative', 'score': 0.07}]] | |
| ``` | |
| ### Option B: Full Pipeline (multi-signal analysis) | |
| For the complete system β topic routing, policy stance, crisis signals, climate scoring, and dictionaries β you need to clone this repo since the pipeline code lives inside it: | |
| ```bash | |
| git clone https://huggingface.co/peyterho/macro-sentiment-finbert | |
| cd macro-sentiment-finbert | |
| pip install -r requirements.txt | |
| ``` | |
| ```python | |
| from macro_sentiment import MacroSentimentPipeline | |
| pipe = MacroSentimentPipeline(device="cpu") | |
| # Financial news β auto-routes to FinBERT | |
| result = pipe("Markets rallied on strong earnings, with the S&P 500 hitting record highs.") | |
| print(result.summary()) | |
| # Sentiment: Positive (+0.612) | Policy: Neutral (+0.000) | Crisis: Normal (0.000) | Domain: financial_news | |
| # Central bank communication β auto-routes to RoBERTa-Large | |
| result = pipe("The ECB raised rates by 25 basis points, citing persistent inflation pressures.") | |
| print(result.summary()) | |
| # Sentiment: Negative (-0.348) | Policy: Hawkish (+0.714) | Crisis: Normal (0.000) | Domain: policy | |
| # Climate/ESG text β auto-routes to ClimateBERT | |
| result = pipe("The company committed to net-zero emissions by 2040 through renewable energy investments.") | |
| print(result.summary()) | |
| # Sentiment: Positive (+0.445) | Policy: Neutral (+0.000) | Crisis: Normal (0.000) | Domain: climate | Climate: Opportunity (exp=0.60) | |
| # Non-English text β auto-routes to XLM-RoBERTa | |
| result = pipe("Die EZB signalisiert Geduld bei kΓΌnftigen Zinssenkungen.") | |
| print(result.summary()) | |
| ``` | |
| ## Use in Google Colab / Kaggle | |
| Copy-paste these cells into a notebook. Both work on Colab (free tier) and Kaggle. | |
| ### Cell 1 β Standalone FinBERT only | |
| ```python | |
| !pip install -q transformers torch | |
| from transformers import pipeline | |
| classifier = pipeline("text-classification", model="peyterho/macro-sentiment-finbert", top_k=None) | |
| # Try it | |
| texts = [ | |
| "Tesla shares surged 15% after crushing earnings expectations.", | |
| "The Federal Reserve raised rates by 75bps citing persistent inflation.", | |
| "Markets crashed amid recession fears and massive layoffs.", | |
| "The company reported quarterly results in line with analyst estimates.", | |
| ] | |
| for text in texts: | |
| result = classifier(text)[0] | |
| top = max(result, key=lambda x: x["score"]) | |
| print(f'{top["label"]:>8s} ({top["score"]:.2f}) {text}') | |
| ``` | |
| ### Cell 1 β Full Pipeline (with policy stance, crisis signals, climate scoring) | |
| ```python | |
| # Install dependencies and clone the repo | |
| !pip install -q transformers torch pysentiment2 scikit-learn numpy pandas datasets accelerate huggingface_hub | |
| !git clone https://huggingface.co/peyterho/macro-sentiment-finbert /content/macro-sentiment-finbert | |
| import sys | |
| sys.path.insert(0, "/content/macro-sentiment-finbert") | |
| ``` | |
| ### Cell 2 β Score any text | |
| ```python | |
| from macro_sentiment import MacroSentimentPipeline | |
| pipe = MacroSentimentPipeline(device="cpu") | |
| texts = [ | |
| "Markets rallied on strong earnings, with the S&P 500 hitting record highs.", | |
| "The ECB raised rates by 25 basis points, citing persistent inflation pressures.", | |
| "The company committed to net-zero emissions by 2040 through renewable energy investments.", | |
| "Credit markets froze as contagion fears spread across European banks.", | |
| "Die EZB signalisiert Geduld bei kΓΌnftigen Zinssenkungen.", | |
| ] | |
| for text in texts: | |
| result = pipe(text) | |
| print(result.summary()) | |
| print(f" β {text}\n") | |
| ``` | |
| ### Cell 3 β Explore the full structured output | |
| ```python | |
| result = pipe("Fed signals two more rate cuts before year-end, a dovish surprise that lifted equities.") | |
| print(f"Macro sentiment: {result.macro_sentiment:+.3f}") | |
| print(f"Financial sentiment:{result.financial_sentiment:+.3f}") | |
| print(f"Policy stance: {result.policy_stance:+.3f} (negative=dovish, positive=hawkish)") | |
| print(f"Crisis signal: {result.crisis_signal:.3f}") | |
| print(f"Climate sentiment: {result.climate_sentiment:+.3f}") | |
| print(f"Uncertainty: {result.uncertainty:.3f}") | |
| print(f"Confidence: {result.confidence:.3f}") | |
| print(f"Domain: {result.detected_domain}") | |
| print(f"Head used: {result.head_used}") | |
| print(f"LM polarity: {result.lm_polarity:+.3f}") | |
| print(f"Henry polarity: {result.henry_polarity:+.3f}") | |
| print(f"Climate exposure: {result.climate_exposure:.3f}") | |
| ``` | |
| ### Cell 4 β Batch scoring with pandas | |
| ```python | |
| import pandas as pd | |
| headlines = [ | |
| "Strong jobs report pushes markets to record highs", | |
| "Tech earnings mixed as AI spending soars", | |
| "Fed signals patience on rate cuts, markets dip", | |
| "Retail sales disappoint, recession fears resurface", | |
| "Green bond issuance hit $500B as investors pivot to sustainable fixed income", | |
| "Bank of Japan holds rates steady in surprise decision", | |
| ] | |
| results = pipe.score_batch(headlines, mode="routed") | |
| df = pd.DataFrame([{ | |
| "text": t, | |
| "sentiment": r.macro_sentiment, | |
| "policy": r.policy_stance, | |
| "crisis": r.crisis_signal, | |
| "climate": r.climate_sentiment, | |
| "domain": r.detected_domain, | |
| "head": r.head_used, | |
| } for t, r in zip(headlines, results)]) | |
| print(df.to_string(index=False)) | |
| ``` | |
| ### Cell 5 β Dictionary-only mode (no GPU needed, instant) | |
| ```python | |
| # No transformer models loaded β uses only the four dictionaries | |
| result = pipe.score("The central bank cut rates amid fears of a deepening recession.", mode="dict_only") | |
| print(result.summary()) | |
| print(f"LM polarity: {result.lm_polarity:+.3f}") | |
| print(f"Henry polarity: {result.henry_polarity:+.3f}") | |
| print(f"Policy stance: {result.policy_stance:+.3f}") | |
| print(f"Crisis signal: {result.crisis_signal:.3f}") | |
| ``` | |
| > **π‘ Notes:** | |
| > - The full pipeline lazy-loads transformer models on first use. First call takes 30β60 seconds to download (~800MB across 4 models). Subsequent calls are fast. | |
| > - `mode="routed"` (default) loads only 1 model per call. `mode="all"` loads all 4 models (~2GB RAM). | |
| > - For Colab free tier, `mode="routed"` works fine. For `mode="all"`, use a GPU runtime to avoid OOM. | |
| > - On Kaggle, enable "Internet" in notebook settings (Settings β Internet β On) so models can download. | |
| ## Structured Output | |
| Every call returns a `MacroSentimentResult` with these fields: | |
| | Field | Range | Description | | |
| |---|---|---| | |
| | `macro_sentiment` | [-1, +1] | Overall macroeconomic sentiment (weighted fusion of transformer + dictionary) | | |
| | `financial_sentiment` | [-1, +1] | Financial-domain sentiment from the selected transformer head | | |
| | `policy_stance` | [-1, +1] | Monetary policy orientation: -1 = very dovish, +1 = very hawkish | | |
| | `climate_sentiment` | [-1, +1] | Climate outlook: -1 = risk, +1 = opportunity | | |
| | `crisis_signal` | [0, 1] | Crisis language intensity (recession, contagion, bank failure, etc.) | | |
| | `uncertainty` | [0, 1] | Uncertainty/volatility language density | | |
| | `confidence` | [0, 1] | Pipeline confidence (based on head agreement, topic match, uncertainty) | | |
| | `detected_domain` | str | Routed domain: `financial_news`, `policy`, `climate`, `social`, `ensemble` | | |
| | `head_used` | str | Which transformer head was selected | | |
| | `lm_polarity` | [-1, +1] | Loughran-McDonald polarity score | | |
| | `henry_polarity` | [-1, +1] | Henry earnings tone score | | |
| | `climate_exposure` | [0, 1] | Climate keyword density (Sautner-style) | | |
| ## Scoring Modes | |
| ```python | |
| # "routed" (default) β topic router selects best head | |
| result = pipe.score("text", mode="routed") | |
| # "all" β runs ALL heads and averages composite scores | |
| result = pipe.score("text", mode="all") | |
| # "dict_only" β dictionary signals only, no transformer inference | |
| result = pipe.score("text", mode="dict_only") | |
| ``` | |
| ## Training Data | |
| All three transformer heads were fine-tuned on the same combined dataset of **5 public financial/climate sentiment corpora**: | |
| | Dataset | Domain | Samples | Label Mapping | | |
| |---|---|---|---| | |
| | [nickmuchi/financial-classification](https://huggingface.co/datasets/nickmuchi/financial-classification) | Financial PhraseBank | ~4,800 train / ~1,200 test | negative / neutral / positive | | |
| | [zeroshot/twitter-financial-news-sentiment](https://huggingface.co/datasets/zeroshot/twitter-financial-news-sentiment) | Financial tweets | ~9,900 train / ~2,500 val | bearish β neg, bullish β pos, neutral | | |
| | [FinanceInc/auditor_sentiment](https://huggingface.co/datasets/FinanceInc/auditor_sentiment) | Auditor reports | ~3,600 train / ~900 test | negative / neutral / positive | | |
| | [pauri32/fiqa-2018](https://huggingface.co/datasets/pauri32/fiqa-2018) | Financial QA + microblog | ~938 train+val / ~235 test | Continuous score thresholded at Β±0.15 | | |
| | [climatebert/climate_sentiment](https://huggingface.co/datasets/climatebert/climate_sentiment) | Climate reports | ~1,000 train / ~500 test | risk β neg, neutral, opportunity β pos | | |
| All datasets were unified to a consistent 3-class schema: `0=negative`, `1=neutral`, `2=positive`. | |
| ## Training Details | |
| ### FinBERT Head (this model) | |
| | Hyperparameter | Value | | |
| |---|---| | |
| | Base model | [ProsusAI/finbert](https://huggingface.co/ProsusAI/finbert) | | |
| | Learning rate | 2e-5 | | |
| | Batch size | 16 Γ 4 gradient accumulation = 64 effective | | |
| | Epochs | 2 | | |
| | Scheduler | Cosine with 31 warmup steps | | |
| | Optimizer | AdamW (fused) | | |
| | Max length | 512 | | |
| | Seed | 42 | | |
| ### Training Curve | |
| | Epoch | Train Loss | Val Loss | Accuracy | F1 (macro) | F1 (weighted) | | |
| |:---:|:---:|:---:|:---:|:---:|:---:| | |
| | 1 | 1.6807 | 0.3761 | 0.8246 | 0.8058 | 0.8300 | | |
| | 2 | 1.1679 | 0.3450 | 0.8486 | 0.8325 | 0.8515 | | |
| > Note: The higher training loss reflects the FinBERT label ordering (positive=0, negative=1, neutral=2) which differs from the unified schema β a label remapping is applied at training time. | |
| ## Evaluation Results | |
| ### In-Domain (Combined Test Set β 4,333 samples) | |
| | Model | Accuracy | F1 (macro) | F1 (weighted) | | |
| |---|:---:|:---:|:---:| | |
| | **RoBERTa-Large (355M)** | **0.9130** | **0.9023** | **0.9137** | | |
| | FinBERT (109M) β | 0.8973 | 0.8813 | 0.8984 | | |
| | ClimateBERT (82M) | 0.8885 | 0.8716 | 0.8898 | | |
| | Dict-only baseline (GBT) | 0.6693 | 0.5781 | 0.6500 | | |
| | Dict-only baseline (rules) | 0.5684 | 0.5277 | 0.5784 | | |
| ### Out-of-Domain: Financial News Phrasebank (785 samples) | |
| Evaluated on [Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75](https://huggingface.co/datasets/Jean-Baptiste/financial_news_sentiment_mixte_with_phrasebank_75) β **not in the training mix**. | |
| | Model | Accuracy | F1 (macro) | | |
| |---|:---:|:---:| | |
| | **RoBERTa-Large** | **0.9414** | **0.9357** | | |
| | ClimateBERT | 0.9248 | 0.9213 | | |
| | FinBERT β | 0.9236 | 0.9134 | | |
| ### Out-of-Domain: Stock News Headlines (30,150 samples) | |
| Evaluated on [ic-fspml/stock_news_sentiment](https://huggingface.co/datasets/ic-fspml/stock_news_sentiment) β 5-class mapped to 3-class. **Not in the training mix**. | |
| | Model | Accuracy | F1 (macro) | | |
| |---|:---:|:---:| | |
| | **RoBERTa-Large** | **0.7211** | **0.7265** | | |
| | FinBERT β | 0.6781 | 0.6765 | | |
| | ClimateBERT | 0.6472 | 0.6441 | | |
| Performance drops on stock news headlines are expected β these are short, noisy texts with 5β3 class mapping, representing a significant domain shift from the training data. | |
| ## Custom Fine-Tuning | |
| You can fine-tune any head on your own labelled data using the included `finetune.py` script: | |
| ```bash | |
| pip install -r requirements.txt | |
| python -m macro_sentiment.finetune \ | |
| --data my_labels.csv \ | |
| --text-column headline \ | |
| --label-column sentiment \ | |
| --base-model peyterho/macro-sentiment-finbert \ | |
| --output my-org/my-custom-model \ | |
| --push-to-hub \ | |
| --epochs 4 \ | |
| --lr 2e-5 \ | |
| --batch-size 32 | |
| ``` | |
| Accepts CSV, TSV, JSON, or JSONL. Labels can be strings (`"positive"`, `"negative"`, `"neutral"`, `"bullish"`, `"bearish"`, `"risk"`, `"opportunity"`) or integers (0/1/2). Automatic class-weighted loss handles imbalanced datasets. | |
| ## Limitations | |
| - **English-centric** β the fine-tuned heads (FinBERT, RoBERTa, ClimateBERT) are English-only. Non-English text falls back to the pre-trained XLM-RoBERTa multilingual model, which was not fine-tuned on the macro sentiment training mix. | |
| - **Domain-specific** β trained on financial news, earnings reports, climate disclosures, and financial tweets. Performance on general-purpose sentiment tasks (movie reviews, product reviews) will be lower. | |
| - **Dictionary lag** β the Loughran-McDonald and Henry dictionaries use static word lists that may not capture emerging financial terminology or evolving language patterns. | |
| - **No temporal awareness** β the model treats each text independently and does not incorporate time-series context or market state. | |
| - **Topic router is keyword-based** β the routing heuristic may misclassify ambiguous texts. Use `mode="all"` for important decisions to get ensemble averaging across all heads. | |
| - **Label noise** β the FiQA dataset uses continuous sentiment scores thresholded at Β±0.15 to create discrete labels, introducing boundary noise for scores near the thresholds. | |
| ## Citation | |
| If you use this model or pipeline, please cite the base models: | |
| ```bibtex | |
| @article{araci2019finbert, | |
| title={FinBERT: Financial Sentiment Analysis with Pre-Trained Language Models}, | |
| author={Araci, Dogu}, | |
| journal={arXiv preprint arXiv:1908.10063}, | |
| year={2019} | |
| } | |
| @article{loughran2011liability, | |
| title={When is a liability not a liability? Textual analysis, dictionaries, and 10-Ks}, | |
| author={Loughran, Tim and McDonald, Bill}, | |
| journal={The Journal of Finance}, | |
| volume={66}, | |
| number={1}, | |
| pages={35--65}, | |
| year={2011} | |
| } | |
| @article{henry2008earnings, | |
| title={Are investors influenced by how earnings press releases are written?}, | |
| author={Henry, Elaine}, | |
| journal={Journal of Business Communication}, | |
| volume={45}, | |
| number={4}, | |
| pages={363--407}, | |
| year={2008} | |
| } | |
| ``` | |
| ## Repository Contents | |
| ``` | |
| βββ model.safetensors # FinBERT fine-tuned weights (109M params) | |
| βββ config.json # Model config (3-class: positive/negative/neutral) | |
| βββ tokenizer.json # BERT tokenizer | |
| βββ eval_results.json # In-domain benchmarks for all heads | |
| βββ eval_ood_results.json # Out-of-domain benchmarks | |
| βββ artifacts/ | |
| β βββ meta_classifier.joblib # GradientBoosting meta-classifier on dictionary features | |
| β βββ smart_router.joblib # Topic routing model | |
| βββ macro_sentiment/ | |
| β βββ __init__.py # Public API exports | |
| β βββ pipeline.py # MacroSentimentPipeline β main entry point | |
| β βββ transformers_ensemble.py # Multi-head transformer ensemble + topic router | |
| β βββ dictionaries.py # LM, Henry, Climate, Macro dictionary scorers | |
| β βββ data_prep.py # Dataset loading and combination (5 datasets) | |
| β βββ finetune.py # Custom fine-tuning script | |
| β βββ train_meta.py # Meta-classifier training script | |
| βββ requirements.txt | |
| ``` | |
| ## Framework Versions | |
| - Transformers 5.6.2 | |
| - PyTorch 2.11.0+cu130 | |
| - Datasets 4.8.4 | |
| - Tokenizers 0.22.2 | |