File size: 2,936 Bytes
a143bbf
 
8ad6cb1
 
a143bbf
 
 
8ad6cb1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3e0d335
8ad6cb1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a143bbf
 
 
 
 
 
 
8ad6cb1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460a4e3
db083db
 
 
8ad6cb1
 
 
ae1f735
397baf7
8ad6cb1
 
 
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
from time import strftime

import feedparser
import streamlit as st

from transformers import AutoTokenizer, pipeline, \
    AutoModelForSequenceClassification


@st.cache(allow_output_mutation=True, show_spinner=False)
def load_model():
    return AutoModelForSequenceClassification.from_pretrained("warwickai/fin-perceiver") 


@st.cache(show_spinner=False)
def load_news(feed):
    return feedparser.parse(feed).get('entries')


def filter_with_sentiment(articles, sentiments):
    return filter(
        lambda article: article[1].get('label') in sentiments,
        articles
    )


tokenizer = AutoTokenizer.from_pretrained("warwickai/fin-perceiver")

with st.spinner('πŸ“ˆ Loading model...'):
    model = load_model()
    pipe = pipeline('text-classification', model=model, tokenizer=tokenizer)


def classify_articles(articles, target_pipeline):
    headlines = [article.title for article in articles]
    sentiment = target_pipeline(headlines)

    return list(zip(articles, sentiment))


rss_feeds = {
    'yahoo': 'https://finance.yahoo.com/news/rssindex'
}

sentiment_distribution = {
    'positive': 0,
    'negative': 0,
    'neutral': 0
}

st.title('FINPerceiver')

target_source = st.sidebar.selectbox(
     'Select a financial news source',
     rss_feeds.keys())

target_sentiments = st.sidebar.multiselect(
     label='Select the target sentiments',
     options=sentiment_distribution.keys(),
     default=sentiment_distribution.keys())

with st.spinner('πŸ“° Loading articles...'):
    target_articles = sorted(
        load_news(
            rss_feeds.get(target_source)
        ),
        key=lambda article: article.published_parsed,
        reverse=True
    )

with st.spinner('βš™οΈ Analysing articles...'):
    classified_articles = classify_articles(target_articles, pipe)

    total_articles = 0

    for article, sentiment in classified_articles:
        total_articles += 1
        sentiment_distribution[sentiment.get('label')] += 1
    
    for sentiment in sentiment_distribution.keys():
        sentiment_distribution[sentiment] /= total_articles * 0.01

    st.sidebar.subheader('Summary')
    st.sidebar.metric("Positive", f"πŸ‘ {sentiment_distribution.get('positive'):.2f}%")
    st.sidebar.metric("Neutral", f"😐 {sentiment_distribution.get('neutral'):.2f}%")
    st.sidebar.metric("Negative", f"πŸ‘Ž {sentiment_distribution.get('negative'):.2f}%")

for article, sentiment in filter_with_sentiment(classified_articles, target_sentiments):
    if 'media_content' in article:
        img_url = article.media_content[0].get('url')
        st.image(img_url, width=300)
    
    st.markdown(
        f'''

        #### {article.title}

        Published on {strftime('%H:%M %d/%m/%Y', article.published_parsed)}

        

        **Sentiment:** {sentiment.get('label').capitalize()}

        '''
    )