nickmuchi commited on
Commit
bfb6182
β€’
1 Parent(s): 9ba2327

Create 01_🏠_Home.py

Browse files
Files changed (1) hide show
  1. 01_🏠_Home.py +173 -0
01_🏠_Home.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from variables import *
3
+ from optimum.onnxruntime import ORTModelForSequenceClassification
4
+ from transformers import pipeline, AutoTokenizer
5
+ from optimum.pipelines import pipeline
6
+ import tweepy
7
+ import pandas as pd
8
+ import numpy as np
9
+ import plotly_express as px
10
+ import plotly.graph_objects as go
11
+ from st_aggrid import GridOptionsBuilder, AgGrid, GridUpdateMode, DataReturnMode
12
+
13
+ st.set_page_config(
14
+ page_title="Live FinTwitter Analysis",
15
+ page_icon="πŸ“ˆ",
16
+ layout="wide",
17
+ )
18
+
19
+ st.sidebar.header("Sentiment Analysis Score")
20
+
21
+ @st.experimental_singleton(suppress_st_warning=True)
22
+ def load_models():
23
+ '''load sentimant and topic clssification models'''
24
+ sent_pipe = pipeline(task,model=sent_model_id, tokenizer=sent_model_id)
25
+ topic_pipe = pipeline(task, model=topic_model_id, tokenizer=topic_model_id)
26
+
27
+ return sent_pipe, topic_pipe
28
+
29
+ @st.cache(allow_output_mutation=True, suppress_st_warning=True)
30
+ def process_tweets(df,df_users):
31
+ '''process tweets into a dataframe'''
32
+
33
+ df['author'] = df['author'].astype(np.int64)
34
+
35
+ df_merged = df.merge(df_users, on='author')
36
+
37
+ tweet_list = df_merged['tweet'].tolist()
38
+
39
+ sentiment, topic = pd.DataFrame(sentiment_classifier(tweet_list)), pd.DataFrame(topic_classifier(tweet_list))
40
+
41
+ sentiment.rename(columns={'score':'sentiment_confidence','label':'sentiment'}, inplace=True)
42
+
43
+ topic.rename(columns={'score':'topic_confidence','label':'topic'}, inplace=True)
44
+
45
+ df_group = pd.concat([df_merged,sentiment,topic],axis=1)
46
+
47
+ df_group[['sentiment_confidence','topic_confidence']] = df_group[['sentiment_confidence','topic_confidence']].round(2).mul(100)
48
+
49
+ df_tweets = df_group[['creation_time','username','tweet','sentiment','topic','sentiment_confidence','topic_confidence']]
50
+
51
+ df_tweets = df_tweets.sort_values(by=['creation_time'],ascending=False)
52
+
53
+ return df_tweets
54
+
55
+
56
+
57
+ sentiment_classifier, topic_classifier = load_models()
58
+
59
+ st.title('Live FinTwitter Sentiment & Topic Analysis with Tweepy and Transformers')
60
+
61
+ st.markdown(
62
+ """
63
+ This app uses Tweepy to extract tweets from twitter based on a list of popular accounts that tweet about markets/finance:
64
+ - The stream of tweets is processed via HuggingFace models for finance tweet sentiment and topic analysis:
65
+ - [Topic Classification](https://huggingface.co/nickmuchi/finbert-tone-finetuned-finance-topic-classification)
66
+ - [Sentiment Analysis](https://huggingface.co/nickmuchi/finbert-tone-finetuned-fintwitter-classification)
67
+ - The resulting sentiments and corresponding tweets are displayed, with graphs tracking the live sentiment and topics of financial market tweets in the Visualisation tab.
68
+ """
69
+ )
70
+
71
+ refresh_stream = st.button('Refresh Stream')
72
+
73
+ if "update_but" not in st.session_state:
74
+ st.session_state.update_but = False
75
+
76
+ if refresh_stream or st.session_state.update_but:
77
+ st.session_state.update_but = True
78
+
79
+ client = tweepy.Client(CONFIG['bearer_token'], wait_on_rate_limit=True)
80
+
81
+ users = []
82
+ all_tweets = []
83
+
84
+ for res in tweepy.Paginator(client.get_list_tweets,
85
+ id="1083517925049266176",
86
+ user_fields=['username'],
87
+ tweet_fields=['created_at','text'],
88
+ expansions=['author_id'],
89
+ max_results=100):
90
+
91
+ all_tweets.append(res)
92
+
93
+
94
+ with st.spinner('Generating sentiment and topic classification of tweets...'):
95
+
96
+ tweets = [response.data for response in all_tweets]
97
+ users = [response.includes['users'] for response in all_tweets]
98
+
99
+ flat_users = [x for i in users for x in i]
100
+ flat_tweets = [x for i in tweets for x in i]
101
+
102
+ data = [(tweet.data['author_id'],tweet.data['text'],tweet.data['created_at']) for tweet in flat_tweets]
103
+ df = pd.DataFrame(data,columns=['author','tweet','creation_time'])
104
+
105
+ df['tweet'] = df['tweet'].replace(r'https?://\S+', '', regex=True).replace(r'www\S+', '', regex=True)
106
+
107
+ users = client.get_users(ids=df['author'].unique().tolist())
108
+
109
+ df_users = pd.DataFrame(data=list(set([(user.id,user.username) for user in users.data])),columns=['author','username'])
110
+
111
+ df_tweets = process_tweets(df,df_users)
112
+
113
+ st.session_state['tdf'] = df_tweets
114
+
115
+ with st.container():
116
+
117
+ st.write("Table of Influential FinTweets")
118
+
119
+ gb = GridOptionsBuilder.from_dataframe(df_tweets)
120
+ gb.configure_pagination(paginationPageSize=30,paginationAutoPageSize=False) #Add pagination
121
+ gb.configure_side_bar() #Add a sidebar
122
+ gb.configure_selection('multiple', use_checkbox=True, groupSelectsChildren="Group checkbox select children")
123
+ gb.configure_column('tweet',wrapText=True,autoHeight=True)#Enable multi-row selection
124
+ gridOptions = gb.build()
125
+
126
+ AgGrid(
127
+ df_tweets,
128
+ gridOptions=gridOptions,
129
+ data_return_mode='AS_INPUT',
130
+ update_mode='MODEL_CHANGED',
131
+ fit_columns_on_grid_load=False,
132
+ enable_enterprise_modules=True,
133
+ theme='streamlit', #Add theme color to the table
134
+ height=550,
135
+ width='100%'
136
+ )
137
+
138
+ ## Display sentiment score
139
+ pos_perc = df_tweets[df_tweets['sentiment']=='Bullish'].count()[0]*100/df_tweets.shape[0]
140
+ neg_perc = df_tweets[df_tweets['sentiment']=='Bearish'].count()[0]*100/df_tweets.shape[0]
141
+ neu_perc = df_tweets[df_tweets['sentiment']=='Neutral'].count()[0]*100/df_tweets.shape[0]
142
+
143
+ sentiment_score = neu_perc+pos_perc-neg_perc
144
+
145
+ fig_1 = go.Figure()
146
+
147
+ fig_1.add_trace(go.Indicator(
148
+ mode = "delta",
149
+ value = sentiment_score,
150
+ domain = {'row': 1, 'column': 1}))
151
+
152
+ fig_1.update_layout(
153
+ template = {'data' : {'indicator': [{
154
+ 'title': {'text': "Sentiment Score"},
155
+ 'mode' : "number+delta+gauge",
156
+ 'delta' : {'reference': 50}}]
157
+ }},
158
+ autosize=False,
159
+ width=250,
160
+ height=250,
161
+ margin=dict(
162
+ l=5,
163
+ r=5,
164
+ b=5,
165
+ pad=2
166
+ )
167
+ )
168
+
169
+ with st.sidebar:
170
+
171
+ st.plotly_chart(fig_1)
172
+
173
+ st.markdown("![visitor badge](https://visitor-badge.glitch.me/badge?page_id=nickmuchi-fintweet-sentiment-analysis)")