A production-ready sentiment analysis API for financial text using fine-tuned FinBERT with optimized negative sentiment detection.
- Advanced Model: Fine-tuned FinBERT with optimized thresholds for superior negative detection
- High Performance: Efficient inference with caching and batch processing
- Production Ready: Docker containerization, health checks, and monitoring
- Enhanced API: Confidence scores, batch processing, and detailed responses
- Easy Deployment: One-command deployment with comprehensive testing
- Backward Compatible: Legacy endpoint support for existing integrations
Our fine-tuned FinBERT model achieves 79% accuracy on financial sentiment analysis with balanced performance across sentiment classes.
| Metric | Score |
|---|---|
| Overall Accuracy | 79.0% |
| F1 Score (Macro) | 0.680 |
| F1 Score (Weighted) | 0.768 |
| Clear Examples Accuracy | 75% |
Our fine-tuned FinBERT model achieves excellent performance on financial sentiment analysis, with optimized thresholds for superior negative sentiment detection.
| Metric | Standard Thresholds | Improved Thresholds β |
|---|---|---|
| Overall Accuracy | 79.0% | 76.9% |
| F1 Score (Macro) | 0.680 | 0.742 |
| F1 Score (Weighted) | 0.768 | 0.775 |
| Sentiment | Standard F1 | Improved F1 β | Improvement |
|---|---|---|---|
| Negative | 0.380 | 0.614 | +61% |
| Neutral | 0.850 | 0.822 | Balanced |
| Positive | 0.810 | 0.790 | Stable |
- Negative Detection: 38% β 61.4% F1-score (+23.4 percentage points)
- Perfect Detection: 100% accuracy on clear negative financial statements
- Balanced Performance: No longer overly conservative on negative predictions
- Production Ready: Optimized thresholds based on extensive validation
# Example: "Revenue collapsed due to competitive pressures"
Standard method: neutral β
Improved method: negative β
# Correctly identified!Performance evaluated on 1,169 test samples from Financial PhraseBank dataset
Financial-sentiment/
βββ .devcontainer/
β βββ devcontainer.json # VS Code development container
βββ .env.template # Environment variables template
βββ .gitignore # Git ignore patterns
βββ LICENSE # MIT license
βββ README.md # Project documentation
βββ data/
β βββ data.csv # Financial PhraseBank dataset
β βββ download.py # Dataset download script
βββ deployment.sh # Automated deployment script
βββ docker-compose.yml # Multi-service deployment
βββ dockerfile # Production Docker image
βββ outputs/
β βββ confusion_matrix.png # Model performance visualization
β βββ finbert_fixed_model/ # Fine-tuned FinBERT model
β β βββ config.json # Model configuration
β β βββ model.safetensors # Model weights
β βββ finbert_fixed_tokenizer/ # Model tokenizer
β β βββ special_tokens_map.json
β β βββ tokenizer.json
β β βββ tokenizer_config.json
β β βββ vocab.txt
β βββ model_evaluation.json # Performance metrics
β βββ quick_negative_fix_results.json # Threshold optimization config
βββ requirements.txt # Python dependencies
βββ src/
β βββ __init__.py # Package initialization
β βββ api.py # FastAPI application
β βββ dataset.py # Data loading utilities
β βββ train_model.py # Model training pipeline
βββ test_api.py # API testing suite
- finbert_fixed_model/: Production-ready FinBERT model with optimized performance
- finbert_fixed_tokenizer/: Corresponding tokenizer for text preprocessing
- model_evaluation.json: Comprehensive performance metrics and evaluation results
- quick_negative_fix_results.json: Threshold optimization configuration for improved negative detection
- api.py: FastAPI application with multiple endpoints (standard, improved, comparison)
- dataset.py: Data loading and preprocessing utilities
- train_model.py: Complete training pipeline for model fine-tuning
- deployment.sh: One-command deployment with health checks and testing
- dockerfile: Multi-stage production Docker image
- docker-compose.yml: Full production setup with optional Redis and Nginx
# Clone the repository
git clone <your-repo-url>
cd Financial-sentiment
# Make deployment script executable
chmod +x deployment.sh
# Deploy with one command
./deployment.sh deployThe API will be available at http://localhost:8000 with automatic health checks and testing.
# Start in development mode
./deployment.sh dev
# Or manually:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn src.api:app --host 0.0.0.0 --port 8000 --reload# Full production setup with Redis and Nginx
docker-compose up -d
# Check status
docker-compose psOnce running, visit:
- Interactive Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- Health Check: http://localhost:8000/health
POST /analyze
{
"text": "Company profits increased by 25% this quarter",
"model": "finbert"
}Response:
{
"text": "Company profits increased by 25% this quarter",
"sentiment": "positive",
"confidence": 0.892,
"probabilities": {
"negative": 0.034,
"neutral": 0.074,
"positive": 0.892
},
"model_used": "finbert",
"method": "improved_thresholds",
"processing_time_ms": 45.2,
"timestamp": "2024-01-15T10:30:00Z"
}POST /analyze/compare
{
"text": "Revenue declined due to cost pressures",
"model": "finbert"
}Response:
{
"text": "Revenue declined due to cost pressures",
"standard_method": {
"sentiment": "neutral",
"confidence": 0.45
},
"improved_method": {
"sentiment": "negative",
"confidence": 0.52
},
"methods_agree": false,
"improvement_applied": true,
"recommendation": "improved"
}POST /analyze/improved # Optimized thresholds (recommended)
POST /analyze/standard # Original thresholdsPOST /analyze/batch
{
"texts": [
"Revenue declined this quarter",
"Strong earnings beat expectations",
"Market conditions remain stable"
],
"model": "finbert"
}GET /config/thresholds # View threshold configuration
GET /models # Available models
GET /health # Health status
GET /cache/stats # Cache statisticsPOST /score # Returns simple probability format (backward compatibility)# Run comprehensive test suite
./deployment.sh test
# Or run manually
python test_api.py# Test single prediction
curl -X POST "http://localhost:8000/analyze" \
-H "Content-Type: application/json" \
-d '{"text": "Company stock price soared after earnings", "model": "finbert"}'
# Test batch processing
curl -X POST "http://localhost:8000/analyze/batch" \
-H "Content-Type: application/json" \
-d '{"texts": ["Profits up 20%", "Revenue declined"], "model": "finbert"}'# Train the model with default configuration
python src/train_model.py
# The script will automatically:
# - Load and clean the data from data/data.csv
# - Fine-tune BERT for financial sentiment
# - Save the model to outputs/finbert_fixed_model/
# - Generate performance metrics and reportsThe training script uses optimized defaults but can be customized by editing training_config.json:
{
"data_path": "data/data.csv",
"model_name": "bert-base-uncased",
"output_dir": "outputs/finbert_fixed",
"num_epochs": 2,
"batch_size": 8,
"learning_rate": 2e-5,
"min_accuracy_threshold": 0.75
}The training expects a CSV file with columns:
Sentence: Financial text to analyzeSentiment: Label (negative, neutral, positive)
Sentence,Sentiment
"Company profits increased significantly",positive
"Revenue declined due to market conditions",negative
"Performance remained steady",neutralAfter training, optimize negative detection:
# Run threshold optimization
python quick_negative_fix.py
# This will:
# - Find optimal thresholds for better negative detection
# - Test on validation data
# - Save configuration for API integration# Multi-stage build for optimized image size
FROM python:3.10-slim as production
# ... (see dockerfile for full configuration)Copy .env.template to .env and customize:
# API Configuration
API_PORT=8000
DEFAULT_MODEL=finbert
# Performance
CACHE_SIZE_LIMIT=1000
MAX_BATCH_SIZE=100
# Security
CORS_ALLOW_ORIGINS=["*"]
RATE_LIMIT_ENABLED=false# Basic health check
curl http://localhost:8000/health
# Detailed status
curl http://localhost:8000/cache/stats# View container logs
docker logs finbert-container
# Follow logs in real-time
docker logs -f finbert-container- Request/response times logged
- Cache hit rates tracked
- Model inference metrics
- Error rate monitoring
- Input Validation: Pydantic models with length limits
- Rate Limiting: Configurable request limits
- CORS Configuration: Customizable origins
- Error Handling: Graceful error responses
- Health Monitoring: Automated health checks
AWS ECS/Fargate:
# Build and push to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account>.dkr.ecr.us-east-1.amazonaws.com
docker build -t finbert-sentiment .
docker tag finbert-sentiment:latest <account>.dkr.ecr.us-east-1.amazonaws.com/finbert-sentiment:latest
docker push <account>.dkr.ecr.us-east-1.amazonaws.com/finbert-sentiment:latestGoogle Cloud Run:
# Deploy to Cloud Run
gcloud run deploy finbert-api \
--image gcr.io/PROJECT-ID/finbert-sentiment \
--platform managed \
--region us-central1 \
--memory 4Gi \
--cpu 2- Memory: 4GB+ recommended for optimal performance
- CPU: 2+ cores for concurrent requests
- Storage: Models require ~1GB disk space
- Network: Consider CDN for global deployment
- Model caching reduces cold start time
- Batch processing for multiple texts
- Optimized tokenization pipeline
- Memory-efficient model loading
- In-memory cache for frequent requests
- Redis support for distributed caching
- Configurable TTL and size limits
- Cache statistics and monitoring
# Install development dependencies
pip install -r requirements.txt -r requirements-dev.txt
# Run with auto-reload
uvicorn src.api:app --reload
# Run tests
pytest tests/
# Code formatting
black src/
isort src/- Train your model using
src/train_model.py - Save to
outputs/your_model/ - Update model loading in
src/api.py - Add tests in
test_api.py
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Hugging Face for the transformers library
- FinBERT authors for the pre-trained financial model
- FastAPI team for the excellent web framework
- Financial PhraseBank dataset contributors
- Documentation: Check
/docsendpoint when running - Issues: Open a GitHub issue
- Performance: See monitoring endpoints for diagnostics