Kartik13's picture
added app.py
9efa351 verified
raw
history blame
7.03 kB
import streamlit as st
import requests
import re
import torch
from transformers import BertTokenizer, BertForSequenceClassification
# Load tokenizer and model
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model_path = '/Users/kartikrathi/Documents/News_sentiment_analysis/model'
model = BertForSequenceClassification.from_pretrained(model_path)
# Function to analyze sentiment
def analyze_sentiment(text):
# Tokenize inputs
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True, max_length=512)
# Perform inference
with torch.no_grad():
outputs = model(**inputs)
# Get predicted logits
logits = outputs.logits
# Determine predicted sentiment
predicted_class_id = torch.argmax(logits, dim=1).item()
sentiment = {0: "positive", 1: "negative", 2: "neutral"}
return sentiment[predicted_class_id]
# Function to fetch news using an API
def fetch_stock_news(symbol):
api_token = '6679177763bcd9.48465511' # Replace with your actual API token
url = f'https://eodhd.com/api/news?s={symbol}&offset=0&limit=2&api_token={api_token}&fmt=json'
try:
response = requests.get(url)
response.raise_for_status() # Raise exception for bad status codes
data = response.json()
news_list = []
for article in data:
title = article.get('title', 'Title not available')
content = article.get('content', 'Content not available')
url = article.get('url', 'URL not available')
date = article.get('date', 'Date not available')
# Remove unwanted sections from content
cleaned_content = remove_sections(content)
news_list.append({'title': title, 'content': cleaned_content, 'url': url, 'date': date})
return news_list
except requests.exceptions.RequestException as e:
print(f"Error fetching news for {symbol}: {e}")
return None
# Function to remove unwanted sections
def remove_sections(content):
# Patterns to remove
patterns = [
r'About\s+.*?[\n\r]+', # 'About {stock}' section
r'Safe\s+Harbor.*', # 'Safe Harbor' section
r'Story\s+continues.*', # 'Story continues'
r'Visit\s+www\.infosys\.com.*', # 'Visit www.infosys.com...'
r'Logo', # 'Logo'
]
for pattern in patterns:
content = re.sub(pattern, '', content, flags=re.IGNORECASE)
return content.strip()
# Streamlit app with multi-page support
def main():
st.sidebar.title('Navigation')
page = st.sidebar.radio("Go to", ('Home', 'Portfolio & News'))
if page == 'Home':
st.title("Financial News Sentiment Analysis")
st.markdown("""
This app performs sentiment analysis on financial news using FinBERT model.
""")
# Input text box for user input
user_input = st.text_area("Enter your financial news text here:", height=200)
# Perform sentiment analysis when user clicks the button
if st.button("Analyze"):
if user_input:
sentiment = analyze_sentiment(user_input)
if sentiment == "positive":
st.markdown(f"<p style='color:green;font-size:40px;font-weight:bold'>{sentiment}</p>", unsafe_allow_html=True)
elif sentiment == "negative":
st.markdown(f"<p style='color:red;font-size:40px;font-weight:bold'>{sentiment}</p>", unsafe_allow_html=True)
elif sentiment == "neutral":
st.markdown(f"<p style='color:blue;font-size:40px;font-weight:bold'>{sentiment}</p>", unsafe_allow_html=True)
else:
st.warning("Please enter some text.")
elif page == 'Portfolio & News':
st.title('Portfolio & News')
# Sidebar to manage portfolio and fetch news
st.sidebar.subheader('Manage Portfolio & Fetch News')
st.sidebar.info("Enter your portfolio/company names here to fetch news.")
# Input fields for portfolio management and news fetching
portfolio = st.sidebar.text_area("Enter your portfolio/company names (one per line):", height=200)
if st.sidebar.button("Save"):
# Add ".NSE" suffix to each company name
shares = portfolio.split("\n")
shares = [share.strip() + ".NSE" for share in shares if share.strip()]
st.sidebar.markdown("**Shares**")
st.sidebar.markdown("\n".join(shares))
# Button to fetch news and perform sentiment analysis
if st.sidebar.button("Fetch News & Analyze Sentiment"):
if portfolio:
companies = portfolio.split("\n")
companies = [company.strip() + ".NSE" for company in companies if company.strip()]
for company in companies:
st.subheader(f"Latest News for {company}:")
news = fetch_stock_news(company)
if news:
for article in news:
title = article['title']
content = article['content']
url = article['url']
date = article['date']
st.markdown(f"**Title:** [{title}]({url}) <span style='color:green;font-size:12px;'>({date})</span>", unsafe_allow_html=True)
# Display a truncated version of the content
truncated_content = content[:200] + "..."
st.markdown(f"**Content:** {truncated_content}")
# Expander for full content
with st.expander("Expand more"):
st.markdown(f"{content}")
st.markdown("---")
# Analyze sentiment of news content (assuming content is available)
if content:
sentiment = analyze_sentiment(content)
if sentiment == "positive":
sentiment_color = "green"
elif sentiment == "negative":
sentiment_color = "red"
elif sentiment == "neutral":
sentiment_color = "blue"
st.markdown(f"**Sentiment:** <span style='color:{sentiment_color};font-weight:bold'>{sentiment}</span>", unsafe_allow_html=True)
st.markdown("---")
else:
st.warning(f"No news articles found for {company}.")
else:
st.warning("Please enter portfolio/company names to fetch news.")
if __name__ == '__main__':
main()