devanshsrivastav commited on
Commit
f3007f9
·
0 Parent(s):

streamlit app

Browse files
.github/workflows/check.yml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Check file size
2
+ on: # or directly `on: [push]` to run the action on every push on any branch
3
+ pull_request:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Check large files
14
+ uses: ActionsDesk/[email protected]
15
+ with:
16
+ filesizelimit: 10485760 # this is 10MB so we can sync to HF Spaces
.github/workflows/main.yml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face hub
2
+ on:
3
+ push:
4
+ pull_request:
5
+ branches: [main]
6
+
7
+ # to run this workflow manually from the Actions tab
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ sync-to-hub:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v3
15
+ with:
16
+ fetch-depth: 0
17
+ lfs: true
18
+ - name: Push to hub
19
+ env:
20
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
21
+ HF_username: devanshsrivastav # your huggingface.co username here (check your profile page)
22
+ HF_space_name: GoEmotions # name of the hub space to which you want to push the model
23
+ run: git push https://$HF_username:[email protected]/spaces/$HF_username/$HF_space_name main
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .env
2
+ .DS_Store
3
+ tumai
4
+ venv
.streamlit/config.toml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [theme]
2
+ base="light"
README.md ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ title: GoEmotions Dashboard
4
+ sdk: streamlit
5
+ sdk_version: "1.22.0"
6
+ app_file: app.py
7
+ ---
8
+
9
+ # GoEmotions Dashboard - Analyzing Emotions in Text
10
+
11
+ This is a Python script that uses Streamlit, Plotly, and the Hugging Face Inference API to create a web-based dashboard for analyzing emotions in text. Finally this dashboard is deployed on Hugging Face Spaces using GitHub Actions.
12
+
13
+ ## Pre-requisites:
14
+
15
+ - Python 3.7 or higher
16
+
17
+ ## Project Structure:
18
+ ```dir
19
+ GoEmotions/
20
+ ├── app.py
21
+ ├── requirements.txt
22
+ ├── .env
23
+ ├── README.md
24
+ ├── assets/
25
+ └── .github/workflows
26
+ ```
27
+
28
+ ## Setup
29
+
30
+ `Step 1` - Clone this repository to your local machine using the following command, or open the repository in GitHub Codespaces.
31
+
32
+ ```bash
33
+ git clone https://github.com/devansh-srivastav/GoEmotions.git
34
+ ```
35
+
36
+ `Step 2` - Navigate to the root directory of the project.
37
+
38
+ ```bash
39
+ cd GoEmotions
40
+ ```
41
+
42
+ `Step 3` - Create and activate a new python virtual environment: (This step can be skipped if working on GitHub Codespaces!)
43
+
44
+ ```bash
45
+ python -m venv venv
46
+ ```
47
+
48
+ For Windows
49
+ ```bash
50
+ venv\Scripts\activate
51
+ ```
52
+
53
+ For Linux/MacOS
54
+
55
+ ```bash
56
+ source venv/bin/activate
57
+ ```
58
+
59
+ `Step 4` - Install the required packages using pip: (This step can be skipped if working on GitHub Codespaces as it automatically installs the requirements!)
60
+
61
+ ```bash
62
+ pip install -r requirements.txt
63
+ ```
64
+
65
+ `Step 5`- Create a free account on the [Hugging Face website](https://huggingface.co/) and generate an API key (read).
66
+
67
+ `Step 6`
68
+
69
+ - Create a `.env` file in the root directory of the project and add your
70
+ - Hugging Face API key like this: `HF_API_KEY=<your_api_key_here>`
71
+
72
+ `Step 7` - Run the Streamlit app.
73
+
74
+ ```bash
75
+ streamlit run app.py
76
+ ```
77
+
78
+ or
79
+
80
+ ```bash
81
+ python -m streamlit run app.py
82
+ ```
83
+
84
+ - If you want to run this application on GitHub Codespaces, you will need to add the following flags to the `streamlit run` command:
85
+
86
+ ```bash
87
+ python -m streamlit run app.py --server.enableCORS false --server.enableXsrfProtection false
88
+ ```
89
+
90
+ ## Deployment to Spaces (CI/CD)
91
+
92
+ `Step 1`
93
+ Commit your code and push it to your GitHub repository
94
+
95
+ `Step 2`
96
+ Create a new Space on Hugging Face, add it as an additional remote to git and force push your code on Spaces:
97
+
98
+ ```bash
99
+ git remote add space https://huggingface.co/spaces/HF_USERNAME/SPACE_NAME
100
+ ```
101
+
102
+ ```bash
103
+ git push --force space main
104
+ ```
105
+
106
+ `Step 3`
107
+ In the main.yml, add your Hugging Face username and Space name to the variables 'HF_username' and 'HF_space_name'
108
+
109
+ `Step 4`
110
+ Create a new API key on Hugging Face (write) and add it as a secret to your GitHub Repository naming it as 'HF_TOKEN'.
111
+
112
+ `Step 5`
113
+ Trigger the CI/CD pipeline by a push or a pull request to your main branch.
114
+
115
+ ## Usage:
116
+
117
+ - A web-based dashboard will open in your default browser.
118
+ - Type or paste a text input in the text box provided.
119
+ - The dashboard will visualise the detected emotions in a set of gauges, with each gauge representing the intensity of a specific emotion category. The gauge colors are based on a predefined color map for each emotion category.
120
+ - Moreover, the dashboard will display the results from Hate Speech Analysis and Sexism Detection models.
app.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import plotly.graph_objects as go
2
+ from plotly.subplots import make_subplots
3
+ import streamlit as st
4
+ import requests
5
+ import json
6
+ import os
7
+ from dotenv import load_dotenv
8
+ load_dotenv()
9
+
10
+ # AI model code
11
+ HF_API_KEY = os.getenv("HF_API_KEY")
12
+
13
+ # API_URL_ED = "https://api-inference.huggingface.co/models/j-hartmann/emotion-english-distilroberta-base" #alternate ED model(slow loading on first run)
14
+ API_URL_ED = "https://api-inference.huggingface.co/models/bhadresh-savani/bert-base-go-emotion"
15
+ API_URL_HS = "https://api-inference.huggingface.co/models/IMSyPP/hate_speech_en"
16
+ API_URL_SD = "https://api-inference.huggingface.co/models/NLP-LTU/bertweet-large-sexism-detector"
17
+
18
+ headers = {"Authorization": f"Bearer {HF_API_KEY}"}
19
+
20
+ def query(payload):
21
+ response_ED = requests.request("POST", API_URL_ED, headers=headers, json=payload)
22
+ response_HS = requests.request("POST", API_URL_HS, headers=headers, json=payload)
23
+ response_SD = requests.request("POST", API_URL_SD, headers=headers, json=payload)
24
+ return (json.loads(response_ED.content.decode("utf-8")),json.loads(response_HS.content.decode("utf-8")),json.loads(response_SD.content.decode("utf-8")))
25
+
26
+ st.set_page_config(
27
+ page_title="GoEmotions Dashboard",
28
+ layout="wide"
29
+ )
30
+
31
+ # Set page title
32
+ st.title("GoEmotions Dashboard - Analyzing Emotions in Text")
33
+
34
+ # Define color map for each emotion category
35
+ color_map = {
36
+ 'admiration': ['#1f77b4', '#98df8a', '#2ca02c', '#d62728'],
37
+ 'amusement': ['#ff7f0e', '#98df8a', '#2ca02c', '#d62728'],
38
+ 'anger': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
39
+ 'annoyance': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
40
+ 'approval': ['#1f77b4', '#98df8a', '#2ca02c', '#d62728'],
41
+ 'caring': ['#98df8a', '#2ca02c', '#FF69B4', '#d62728'],
42
+ 'confusion': ['#ffbb78', '#ff7f0e', '#9467bd', '#d62728'],
43
+ 'curiosity': ['#ffbb78', '#ff7f0e', '#9467bd', '#d62728'],
44
+ 'desire': ['#2ca02c', '#ff7f0e', '#98df8a', '#d62728'],
45
+ 'disappointment': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
46
+ 'disapproval': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
47
+ 'disgust': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
48
+ 'embarrassment': ['#ffbb78', '#ff7f0e', '#9467bd', '#d62728'],
49
+ 'excitement': ['#ff7f0e', '#2ca02c', '#98df8a', '#d62728'],
50
+ 'fear': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
51
+ 'gratitude': ['#98df8a', '#2ca02c', '#1f77b4', '#d62728'],
52
+ 'grief': ['#ffbb78', '#d62728', '#bcbd22', '#ff7f0e'],
53
+ 'joy': ['#ff7f0e', '#98df8a', '#2ca02c', '#d62728'],
54
+ 'love': ['#FF69B4', '#98df8a', '#2ca02c', '#d62728'],
55
+ 'nervousness': ['#ffbb78', '#ff7f0e', '#9467bd', '#d62728'],
56
+ 'optimism': ['#98df8a', '#2ca02c', '#1f77b4', '#d62728'],
57
+ 'pride': ['#98df8a', '#ff7f0e', '#1f77b4', '#d62728'],
58
+ 'realization': ['#9467bd', '#ff7f0e', '#ffbb78', '#d62728'],
59
+ 'relief': ['#1f77b4', '#98df8a', '#2ca02c', '#d62728'],
60
+ 'remorse': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
61
+ 'sadness': ['#ffbb78', '#ff7f0e', '#d62728', '#bcbd22'],
62
+ 'surprise': ['#ff7f0e', '#ffbb78', '#9467bd', '#d62728'],
63
+ 'neutral': ['#2ca02c', '#98df8a', '#1f77b4', '#d62728']
64
+ }
65
+
66
+
67
+ # Labels for Hate Speech Classification
68
+ label_hs = {"LABEL_0": "Acceptable", "LABEL_1": "Inappropriate", "LABEL_2": "Offensive", "LABEL_3": "Violent"}
69
+
70
+
71
+ # Define default options
72
+
73
+ default_options = [
74
+ "I'm so excited for my vacation next week!",
75
+ "I'm feeling so stressed about work.",
76
+ "I just received great news from my doctor!",
77
+ "I can't wait to see my best friend tomorrow.",
78
+ "I'm feeling so lonely and sad today."
79
+ "I'm so angry at my neighbor for being so rude.",
80
+ "You are so annoying!",
81
+ "You people from small towns are so dumb.",
82
+ "If you don't agree with me, you are a moron.",
83
+ "I hate you so much!",
84
+ "If you don't listen to me, I'll beat you up!",
85
+ ]
86
+
87
+ with st.sidebar:
88
+
89
+ # Create dropdown with default options
90
+ selected_option = st.selectbox("Select a default option or enter your own text:", default_options)
91
+
92
+ # Display text input with selected option as default value
93
+ text_input = st.text_area("Enter text to analyze emotions:", value = selected_option, height=100)
94
+
95
+ # Add submit button
96
+ submit = st.button("Submit")
97
+
98
+ # If submit button is clicked
99
+ if submit:
100
+
101
+ # Call API and get predicted probabilities for each emotion category and hate speech classification
102
+ payload = {"inputs": text_input, "options": {"wait_for_model": True, "use_cache": True}}
103
+ response_ED, response_HS, response_SD = query(payload)
104
+ predicted_probabilities_ED = response_ED[0]
105
+ predicted_probabilities_HS = response_HS[0]
106
+ predicted_probabilities_SD = response_SD[0]
107
+
108
+ # Creating columns to visualize the results
109
+ ED, _, HS, __, SD = st.columns([4,1,2,1,2])
110
+
111
+ with ED:
112
+ # Get the top 4 emotion categories and their scores
113
+ top_emotions = predicted_probabilities_ED[:4]
114
+ top_scores = [e['score'] for e in top_emotions]
115
+
116
+ # Create the gauge charts for the top 4 emotion categories
117
+ fig = make_subplots(rows=2, cols=2, specs=[[{'type': 'indicator'}, {'type': 'indicator'}],
118
+ [{'type': 'indicator'}, {'type': 'indicator'}]],
119
+ vertical_spacing=0.4)
120
+
121
+ for i, emotion in enumerate(top_emotions):
122
+ # Get the emotion category, color, and normalized score for the current emotion
123
+ category = emotion['label']
124
+ color = color_map[category]
125
+ value = top_scores[i] * 100
126
+
127
+ # Calculate the row and column position for adding the trace to the subplots
128
+ row = i // 2 + 1
129
+ col = i % 2 + 1
130
+
131
+ # Add a gauge chart trace for the current emotion category
132
+ fig.add_trace(go.Indicator(
133
+ domain={'x': [0, 1], 'y': [0, 1]},
134
+ value=value,
135
+ mode="gauge+number",
136
+ title={'text': category.capitalize()},
137
+ gauge={'axis': {'range': [None, 100]},
138
+ 'bar': {'color': color[3]},
139
+ 'bgcolor': 'white',
140
+ 'borderwidth': 2,
141
+ 'bordercolor': color[1],
142
+ 'steps': [{'range': [0, 33], 'color': color[0]},
143
+ {'range': [33, 66], 'color': color[1]},
144
+ {'range': [66, 100], 'color': color[2]}],
145
+ 'threshold': {'line': {'color': "black", 'width': 4},
146
+ 'thickness': 0.5,
147
+ 'value': 50}}), row=row, col=col)
148
+
149
+ # Update the layout of the figure
150
+ fig.update_layout(height=400, margin=dict(t=50, b=5, l=0, r=0))
151
+
152
+
153
+ # Display gauge charts
154
+ st.text("")
155
+ st.text("")
156
+ st.text("")
157
+ st.subheader("Emotion Detection")
158
+ st.text("")
159
+ st.plotly_chart(fig, use_container_width=True)
160
+
161
+ with _:
162
+ st.text("")
163
+
164
+
165
+ with HS:
166
+ # Display Hate Speech Classification
167
+ hate_detection = label_hs[predicted_probabilities_HS[0]['label']]
168
+ st.text("")
169
+ st.text("")
170
+ st.text("")
171
+ st.subheader("Hate Speech Analysis")
172
+ st.text("")
173
+ st.image(f"assets/{hate_detection}.jpg", width=200)
174
+ st.text("")
175
+ st.text("")
176
+ st.markdown(f"#### The given text is: {hate_detection}")
177
+
178
+ with __:
179
+ st.text("")
180
+
181
+ with SD:
182
+ label_SD = predicted_probabilities_SD[0]['label'].title()
183
+ st.text("")
184
+ st.text("")
185
+ st.text("")
186
+ st.subheader("Sexism Detection")
187
+ st.text("")
188
+ st.image(f"assets/{label_SD}.jpg", width=200)
189
+ st.text("")
190
+ st.text("")
191
+ st.markdown(f"#### The given text is: {label_SD}")
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+ hide_st_style = """
200
+ <style>
201
+ #MainMenu {visibility: hidden;}
202
+ footer {visibility: hidden;}
203
+ </style>
204
+ """
205
+ st.markdown(hide_st_style, unsafe_allow_html=True)
assets/Acceptable.jpg ADDED
assets/Inappropriate.jpg ADDED
assets/Not Sexist.jpg ADDED
assets/Offensive.jpg ADDED
assets/Sexist.jpg ADDED
assets/Violent.jpg ADDED
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ plotly==5.3.1
2
+ streamlit==1.22.0
3
+ requests==2.26.0
4
+ python-dotenv==0.19.1
5
+ protobuf==3.20.*
6
+ altair<5