init commit
Browse files- .gitignore +15 -0
- .streamlit/config.toml +6 -0
- Dockerfile +11 -0
- README.md +3 -1
- app.py +44 -0
- assets/css/styles.css +148 -0
- assets/dataset/final.csv +0 -0
- assets/dataset/master.csv +0 -0
- assets/dataset/output.csv +0 -0
- assets/dataset/temp_output_author.csv +2 -0
- assets/dataset/temp_output_combined.csv +55 -0
- assets/dataset/temp_output_combined2.csv +66 -0
- assets/dataset/temp_output_comments.csv +54 -0
- assets/html/about.html +9 -0
- assets/img/PCE.png +0 -0
- assets/img/background.jpg +0 -0
- assets/img/banner.png +0 -0
- assets/img/favicon.png +0 -0
- assets/img/omdena_logo.png +0 -0
- requirements.txt +0 -0
- st_pages/__init__.py +0 -0
- st_pages/about.py +50 -0
- st_pages/analyse.py +52 -0
- st_pages/dashboard.py +92 -0
- st_pages/home.py +55 -0
- utils/__init__.py +0 -0
- utils/constants.py +69 -0
- utils/generate_pdf.py +86 -0
- utils/graph_functions.py +270 -0
- utils/scraper.py +123 -0
- utils/utils.py +138 -0
.gitignore
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
env/
|
2 |
+
.venv/
|
3 |
+
misc/
|
4 |
+
__pycache__/
|
5 |
+
|
6 |
+
todo
|
7 |
+
.env
|
8 |
+
test.py
|
9 |
+
test2.py
|
10 |
+
logs.log
|
11 |
+
temp.ipynb
|
12 |
+
.streamlit/secrets.toml
|
13 |
+
test*
|
14 |
+
|
15 |
+
*copy*
|
.streamlit/config.toml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
primaryColor="#F63366"
|
3 |
+
backgroundColor="#FFFFFF"
|
4 |
+
secondaryBackgroundColor="#F0F2F6"
|
5 |
+
textColor="#262730"
|
6 |
+
font="sans serif"
|
Dockerfile
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM python:3.11
|
2 |
+
|
3 |
+
USER root
|
4 |
+
|
5 |
+
WORKDIR /code
|
6 |
+
|
7 |
+
COPY . .
|
8 |
+
|
9 |
+
RUN pip install -r requirements. -q
|
10 |
+
|
11 |
+
CMD ["streamlit", "run", "app.py"]
|
README.md
CHANGED
@@ -7,4 +7,6 @@ sdk: docker
|
|
7 |
pinned: false
|
8 |
---
|
9 |
|
10 |
-
|
|
|
|
|
|
7 |
pinned: false
|
8 |
---
|
9 |
|
10 |
+
# Omdena's Sentiment Analysis Tool for Political Actors in El Salvador Weba App
|
11 |
+
w
|
12 |
+
Link: https://omdena-irex-el-salvador-sentiment-analysis-app-demo.streamlit.app/
|
app.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
from st_on_hover_tabs import on_hover_tabs
|
4 |
+
|
5 |
+
from st_pages.home import home_page
|
6 |
+
from st_pages.analyse import analyse_page
|
7 |
+
from st_pages.dashboard import dashboard
|
8 |
+
from st_pages.about import about_us_page
|
9 |
+
from utils.constants import PAGE_FAVICON, CONTRIBUTORS
|
10 |
+
from utils.utils import load_css, init_session_state, load_header
|
11 |
+
|
12 |
+
st.set_page_config(page_title='Sentiment Analysis Tool', page_icon=PAGE_FAVICON, layout='wide')
|
13 |
+
|
14 |
+
load_css()
|
15 |
+
init_session_state()
|
16 |
+
|
17 |
+
with st.sidebar:
|
18 |
+
st.write('<br>'*4, unsafe_allow_html=True)
|
19 |
+
selected_task = on_hover_tabs(
|
20 |
+
tabName=['Home Page', 'Analyse Sentiment', 'Dashboard', 'About Us'],
|
21 |
+
iconName=['home', 'engineering', 'insert_chart', 'contact_support'],
|
22 |
+
styles = {
|
23 |
+
'navtab': {'background-color':'#fff'},
|
24 |
+
'tabOptionsStyle': {':hover :hover': {'color': '#170034', 'cursor': 'pointer'}},
|
25 |
+
},
|
26 |
+
default_choice=2)
|
27 |
+
|
28 |
+
if selected_task == 'Home Page':
|
29 |
+
home_page()
|
30 |
+
|
31 |
+
elif selected_task == 'Analyse Sentiment':
|
32 |
+
analyse_page()
|
33 |
+
|
34 |
+
elif selected_task == 'Dashboard':
|
35 |
+
if 'master_df' in st.session_state and st.session_state['master_df'] is None:
|
36 |
+
# load_header("Sentiment Analysis Dashboard")
|
37 |
+
# st.info("Please analyze a tweet first.")
|
38 |
+
st.session_state['master_df'] = pd.read_csv('assets/dataset/temp_output_combined.csv')
|
39 |
+
# else:
|
40 |
+
with st.spinner("Loading Dashboard..."):
|
41 |
+
dashboard()
|
42 |
+
|
43 |
+
elif selected_task == 'About Us':
|
44 |
+
about_us_page(CONTRIBUTORS)
|
assets/css/styles.css
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import url('https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.min.js');
|
2 |
+
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap');
|
3 |
+
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap');
|
4 |
+
@import url('https://fonts.googleapis.com/css2?family=Dosis:wght@200..800&display=swap');
|
5 |
+
|
6 |
+
|
7 |
+
h1 {
|
8 |
+
font-family: "Quicksand", sans-serif;
|
9 |
+
color: #000;
|
10 |
+
}
|
11 |
+
.top {
|
12 |
+
padding: 70px 0px 250px;
|
13 |
+
font-optical-sizing: auto;
|
14 |
+
font-style: normal;
|
15 |
+
}
|
16 |
+
.caption {
|
17 |
+
padding: 80px 0px;
|
18 |
+
}
|
19 |
+
|
20 |
+
.custom {
|
21 |
+
font-family: "Dosis", sans-serif;
|
22 |
+
font-optical-sizing: auto;
|
23 |
+
font-weight: 449;
|
24 |
+
font-style: normal;
|
25 |
+
}
|
26 |
+
|
27 |
+
section[data-testid='stSidebar'] * {
|
28 |
+
background-color: transparent;
|
29 |
+
flex-shrink: unset;
|
30 |
+
}
|
31 |
+
|
32 |
+
.stMarkdown {
|
33 |
+
background-color: transparent;
|
34 |
+
backdrop-filter: blur(10px);
|
35 |
+
}
|
36 |
+
|
37 |
+
div[data-testid="stDataFrameResizable"] * {
|
38 |
+
background-color: transparent;
|
39 |
+
}
|
40 |
+
|
41 |
+
button[data-testid='baseButton-secondary'] {
|
42 |
+
background-color: #ffffff10;
|
43 |
+
/* border-color: #ffffff95; */
|
44 |
+
backdrop-filter: blur(100px);
|
45 |
+
}
|
46 |
+
|
47 |
+
div[data-testid="stMultiSelect"] {
|
48 |
+
background-color: transparent;
|
49 |
+
}
|
50 |
+
|
51 |
+
.stSelectbox * {
|
52 |
+
background-color: transparent;
|
53 |
+
}
|
54 |
+
|
55 |
+
div[data-baseweb="select"] *
|
56 |
+
{
|
57 |
+
background-color: transparent;
|
58 |
+
}
|
59 |
+
|
60 |
+
div[data-baseweb="popover"] *
|
61 |
+
{
|
62 |
+
background-color: transparent !important;
|
63 |
+
}
|
64 |
+
|
65 |
+
.plotly * {
|
66 |
+
background-color: transparent !important;
|
67 |
+
}
|
68 |
+
|
69 |
+
svg[data-testid="stExpanderToggleIcon"]
|
70 |
+
{
|
71 |
+
opacity: 0%;
|
72 |
+
}
|
73 |
+
|
74 |
+
a {
|
75 |
+
text-decoration: none;
|
76 |
+
color: black !important;
|
77 |
+
}
|
78 |
+
|
79 |
+
@media(hover:hover) and (min-width: 600px) and (max-width: 769px){
|
80 |
+
|
81 |
+
header[data-testid="stHeader"] {
|
82 |
+
display:none;
|
83 |
+
}
|
84 |
+
|
85 |
+
section[data-testid='stSidebar'] {
|
86 |
+
height: 100%;
|
87 |
+
min-width:95px !important;
|
88 |
+
width: 95px !important;
|
89 |
+
margin-left: 305px;
|
90 |
+
position: relative;
|
91 |
+
z-index: 1;
|
92 |
+
top: 0;
|
93 |
+
left: 0;
|
94 |
+
background-color: transparent;
|
95 |
+
overflow-x: hidden;
|
96 |
+
transition: 0.5s ease;
|
97 |
+
padding-top: 60px;
|
98 |
+
white-space: nowrap;
|
99 |
+
}
|
100 |
+
|
101 |
+
/* section[data-testid='stSidebar']:hover{
|
102 |
+
min-width: 330px !important;
|
103 |
+
} */
|
104 |
+
|
105 |
+
button[kind="header"] {
|
106 |
+
display: none;
|
107 |
+
}
|
108 |
+
|
109 |
+
div[data-testid="collapsedControl"]{
|
110 |
+
display: none;
|
111 |
+
}
|
112 |
+
|
113 |
+
}
|
114 |
+
|
115 |
+
@media(hover: hover) and (min-width: 769px){
|
116 |
+
|
117 |
+
header[data-testid="stHeader"] {
|
118 |
+
display:none;
|
119 |
+
}
|
120 |
+
|
121 |
+
section[data-testid='stSidebar'] {
|
122 |
+
height: 100%;
|
123 |
+
min-width:95px !important;
|
124 |
+
width: 95px !important;
|
125 |
+
transform:translateX(0px);
|
126 |
+
position: relative;
|
127 |
+
z-index: 1;
|
128 |
+
top: 0;
|
129 |
+
left: 0;
|
130 |
+
background-color: transparent;
|
131 |
+
overflow-x: hidden;
|
132 |
+
transition: 0.5s ease;
|
133 |
+
padding-top: 60px;
|
134 |
+
white-space: nowrap;
|
135 |
+
}
|
136 |
+
|
137 |
+
/* section[data-testid='stSidebar']:hover{
|
138 |
+
min-width: 330px !important;
|
139 |
+
} */
|
140 |
+
|
141 |
+
button[kind="header"] {
|
142 |
+
display: none;
|
143 |
+
}
|
144 |
+
|
145 |
+
div[data-testid="collapsedControl"]{
|
146 |
+
display: none;
|
147 |
+
}
|
148 |
+
}
|
assets/dataset/final.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
assets/dataset/master.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
assets/dataset/output.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
assets/dataset/temp_output_author.csv
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
url,createdAt,id,isReply,inReplyToId,isRetweet,isQuote,viewCount,retweetCount,likeCount,replyCount,lang,author__createdAt,author__location,author__name,author__id,author__description,author__followers,author__verified,text
|
2 |
+
https://x.com/FoxNews/status/1799415711346929732,2024-06-08 12:18:31+00:00,1799415711346929732,False,,False,False,193196,352,2052,86,en,2007-03-17 19:01:26+00:00,U.S.A.,Fox News,1367531,"Follow America's #1 cable news network, delivering you breaking news, insightful analysis, and must-see videos. https://t.co/sXA1eVB5Gv",24471895,True,"Bukele has El Salvador poised to prosper after stopping murder, migration cold in first term https://t.co/RSHOJDbDrK"
|
assets/dataset/temp_output_combined.csv
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
url,createdAt,id,isReply,inReplyToId,isRetweet,isQuote,viewCount,retweetCount,likeCount,replyCount,lang,author__createdAt,author__location,author__followers,author__verified,text,sentiment_beto,sentiment_label,sentiment_beto_neu,sentiment_beto_pos,sentiment_beto_neg
|
2 |
+
https://x.com/FoxNews/status/1799415711346929732,2024-06-08 12:18:31+00:00,1799415711346929732,False,nan,False,False,193196,352,2052,86,en,2007-03-17 19:01:26+00:00,U.S.A.,24471895,True,"Bukele has El Salvador poised to prosper after stopping murder, migration cold in first term https://t.co/RSHOJDbDrK","AnalyzerOutput(output=NEG, probas={NEG: 0.398, NEU: 0.350, POS: 0.251})",NEG,0.3500336706638336,0.25147363543510437,0.3984927237033844
|
3 |
+
https://x.com/bankoftime01/status/1799415790636294438,2024-06-08 12:18:50+00:00,1799415790636294438,True,1.7994157113469297e+18,False,True,1033,0,0,0,qme,2023-11-07 11:35:32+00:00,,929,True,@FoxNews 👇👇🚨🚨,"AnalyzerOutput(output=NEU, probas={NEU: 0.723, NEG: 0.170, POS: 0.107})",NEU,0.7230793833732605,0.10709452629089355,0.16982606053352356
|
4 |
+
https://x.com/StandUnited76/status/1799415831136550937,2024-06-08 12:19:00+00:00,1799415831136550937,True,1.7994157113469297e+18,False,False,2182,0,5,12,en,2022-04-27 14:30:03+00:00,"Arizona, USA",3317,True,@FoxNews good let’s send our illegals there!,"AnalyzerOutput(output=NEU, probas={NEU: 0.468, POS: 0.419, NEG: 0.114})",NEU,0.46762776374816895,0.4186290204524994,0.11374317854642868
|
5 |
+
https://x.com/ChandanaJac/status/1799415857334063279,2024-06-08 12:19:06+00:00,1799415857334063279,True,1.7994157113469297e+18,False,True,2087,0,1,0,en,2023-11-20 20:06:31+00:00,,579,True,"@FoxNews He the best, unlike the puppetmaster😎","AnalyzerOutput(output=POS, probas={POS: 0.543, NEU: 0.413, NEG: 0.044})",POS,0.41318222880363464,0.5433173775672913,0.0435003899037838
|
6 |
+
https://x.com/jimomics/status/1799415932173140135,2024-06-08 12:19:24+00:00,1799415932173140135,True,1.7994157113469297e+18,False,False,812,0,0,2,en,2016-08-09 16:57:44+00:00,,15647,True,@FoxNews Just if Biden did 1/10th of this...,"AnalyzerOutput(output=NEU, probas={NEU: 0.581, NEG: 0.249, POS: 0.170})",NEU,0.5808106660842896,0.1697959154844284,0.24939334392547607
|
7 |
+
https://x.com/CBOhio62/status/1799415950569267652,2024-06-08 12:19:28+00:00,1799415950569267652,True,1.7994157113469297e+18,False,False,249,0,1,0,en,2014-01-23 17:31:10+00:00,Ohio,2910,False,@FoxNews They’ll be in better shape soon especially if Biden installed again.,"AnalyzerOutput(output=POS, probas={POS: 0.521, NEU: 0.413, NEG: 0.066})",POS,0.4127139449119568,0.5214764475822449,0.06580961495637894
|
8 |
+
https://x.com/janainajaja_7/status/1799416463675310481,2024-06-08 12:21:31+00:00,1799416463675310481,True,1.7994157113469297e+18,False,False,218,0,0,0,und,2013-05-31 17:13:17+00:00,Aqui ó,15,False,"@FoxNews yay
|
9 |
+
|
10 |
+
https://t.co/1iZWuz8Sep","AnalyzerOutput(output=NEU, probas={NEU: 0.555, POS: 0.319, NEG: 0.126})",NEU,0.554955005645752,0.3188256025314331,0.12621933221817017
|
11 |
+
https://x.com/CitizenCallerUS/status/1799416514732564840,2024-06-08 12:21:43+00:00,1799416514732564840,True,1.7994157113469297e+18,False,False,2975,2,30,2,en,2023-09-01 19:49:37+00:00,"Texas, USA",1192,True,"@FoxNews What's the philosophy behind this amazing turn around? Surely it's DEI or CRT or some kind of Woke stuff right?
|
12 |
+
|
13 |
+
Not a chance, it's just plain old common sense.","AnalyzerOutput(output=NEU, probas={NEU: 0.460, NEG: 0.440, POS: 0.100})",NEU,0.4598405361175537,0.10030308365821838,0.4398564100265503
|
14 |
+
https://x.com/PortoG1937/status/1799416603173364150,2024-06-08 12:22:04+00:00,1799416603173364150,True,1.7994157113469297e+18,False,False,541,0,0,2,en,2022-08-10 13:49:55+00:00,,636,False,"@FoxNews The population of ES is approx 6 Mio
|
15 |
+
|
16 |
+
It is a developing nation
|
17 |
+
|
18 |
+
Why would anyone want to migrate there?","AnalyzerOutput(output=NEU, probas={NEU: 0.641, NEG: 0.235, POS: 0.124})",NEU,0.6411659121513367,0.12401530146598816,0.23481878638267517
|
19 |
+
https://x.com/BiologicalWoma2/status/1799417233224986797,2024-06-08 12:24:34+00:00,1799417233224986797,True,1.7994157113469297e+18,False,False,1597,2,32,1,en,2021-06-01 18:05:40+00:00,"Florida, USA",70810,True,@FoxNews We need more leaders like Bukele 👍🏽,"AnalyzerOutput(output=POS, probas={POS: 0.760, NEU: 0.192, NEG: 0.048})",POS,0.1916222870349884,0.7602373361587524,0.04814037308096886
|
20 |
+
https://x.com/Patriot1690/status/1799417579486036421,2024-06-08 12:25:57+00:00,1799417579486036421,True,1.7994157113469297e+18,False,False,180,0,0,1,en,2009-09-30 03:20:53+00:00,,296,False,@FoxNews Rolf https://t.co/fJygdemihi,"AnalyzerOutput(output=NEU, probas={NEU: 0.620, POS: 0.268, NEG: 0.112})",NEU,0.6200147271156311,0.2683652937412262,0.11162002384662628
|
21 |
+
https://x.com/riyaz25161/status/1799417601443201318,2024-06-08 12:26:02+00:00,1799417601443201318,True,1.7994157113469297e+18,False,False,952,0,2,0,en,2023-11-04 15:56:55+00:00,Qatar,3177,True,@FoxNews Hope bukele is good leader,"AnalyzerOutput(output=POS, probas={POS: 0.763, NEU: 0.183, NEG: 0.054})",POS,0.18296284973621368,0.763419508934021,0.05361756309866905
|
22 |
+
https://x.com/PhuongVannareth/status/1799418041165623613,2024-06-08 12:27:47+00:00,1799418041165623613,True,1.7994157113469297e+18,False,False,191,0,0,0,qme,2021-12-22 23:47:09+00:00,,136,False,@FoxNews 🙄😁😘🥰 https://t.co/qVXvdnszjs,"AnalyzerOutput(output=NEU, probas={NEU: 0.731, POS: 0.162, NEG: 0.106})",NEU,0.7314165830612183,0.1623229831457138,0.10626043379306793
|
23 |
+
https://x.com/b658842c5ab4475/status/1799419293076987924,2024-06-08 12:32:45+00:00,1799419293076987924,True,1.7994157113469297e+18,False,False,223,0,1,0,en,2016-09-05 00:09:02+00:00,New York/New Jersey,169,False,"@FoxNews How he did ? Bukele summoned The legislative Assembly to
|
24 |
+
suspend the constitutional guarantees - civil liberties- for 30 days which then it was extended 12 times. Unusual & unconventional but he curved crime .
|
25 |
+
|
26 |
+
Can U.S Congress do such & then challenge at the federal court?","AnalyzerOutput(output=NEG, probas={NEG: 0.754, NEU: 0.180, POS: 0.066})",NEG,0.1798279881477356,0.0664113312959671,0.7537606954574585
|
27 |
+
https://x.com/SteveAn07575136/status/1799421077325852757,2024-06-08 12:39:51+00:00,1799421077325852757,True,1.7994157113469297e+18,False,False,248,0,0,1,en,2021-12-14 03:08:58+00:00,,203,False,@FoxNews They are all in the US now.,"AnalyzerOutput(output=NEU, probas={NEU: 0.502, NEG: 0.396, POS: 0.102})",NEU,0.5020391941070557,0.10181693732738495,0.3961438238620758
|
28 |
+
https://x.com/apmoore1234/status/1799426430260162662,2024-06-08 13:01:07+00:00,1799426430260162662,True,1.7994157113469297e+18,False,False,248,0,1,1,en,2022-11-14 13:26:48+00:00,,130,False,@FoxNews A lot of these countries are doing better because they’ve sent all their prisoners and criminals to America,"AnalyzerOutput(output=NEG, probas={NEG: 0.560, POS: 0.250, NEU: 0.190})",NEG,0.190254345536232,0.249982088804245,0.5597635507583618
|
29 |
+
https://x.com/Sarcornot/status/1799428980661178868,2024-06-08 13:11:15+00:00,1799428980661178868,True,1.7994157113469297e+18,False,False,176,0,1,8,en,2014-03-12 22:01:14+00:00,,1542,False,"@FoxNews He's a dictator! He has arrested and beat protesters. He's arresting ppl who have committed no crimes. Of course, Fox loves these types of dictators.","AnalyzerOutput(output=NEG, probas={NEG: 0.721, POS: 0.173, NEU: 0.106})",NEG,0.10611296445131302,0.17260140180587769,0.7212856411933899
|
30 |
+
https://x.com/Adub82UT/status/1799431150315958371,2024-06-08 13:19:52+00:00,1799431150315958371,True,1.7994157113469297e+18,False,False,237,0,2,0,en,2022-10-31 02:51:32+00:00,,27,False,"@FoxNews He brings God in, America is trying to take God out..🧐","AnalyzerOutput(output=NEU, probas={NEU: 0.827, POS: 0.093, NEG: 0.080})",NEU,0.8267660140991211,0.09320252388715744,0.08003143221139908
|
31 |
+
https://x.com/HerbertEsmahan/status/1799533895630655959,2024-06-08 20:08:09+00:00,1799533895630655959,True,1.7994157113469297e+18,False,False,4618,9,141,1,en,2021-02-03 02:58:21+00:00,El Salvador,20918,True,"@FoxNews @nayibbukele President @nayibbukele, through the grace of God, saved El Salvador! 🇸🇻","AnalyzerOutput(output=NEU, probas={NEU: 0.572, POS: 0.374, NEG: 0.055})",NEU,0.5715998411178589,0.37387949228286743,0.05452072247862816
|
32 |
+
https://x.com/Vianney41603586/status/1799533953591755117,2024-06-08 20:08:22+00:00,1799533953591755117,True,1.7994157113469297e+18,False,False,259,0,0,0,qme,2021-10-18 04:55:33+00:00,,33,False,@FoxNews @nayibbukele 👍👍🙏🏻👍👍,"AnalyzerOutput(output=NEU, probas={NEU: 0.690, POS: 0.209, NEG: 0.102})",NEU,0.689559817314148,0.20876464247703552,0.10167557746171951
|
33 |
+
https://x.com/PaoMarrohs/status/1799534180155482202,2024-06-08 20:09:16+00:00,1799534180155482202,True,1.7994157113469297e+18,False,False,1189,0,8,0,qme,2012-05-23 08:14:46+00:00,El Salvador,10076,True,@FoxNews 😎🇸🇻🙌🏻,"AnalyzerOutput(output=NEU, probas={NEU: 0.765, POS: 0.179, NEG: 0.055})",NEU,0.7654933333396912,0.17929233610630035,0.05521434545516968
|
34 |
+
https://x.com/cx_shop/status/1799535839258788277,2024-06-08 20:15:52+00:00,1799535839258788277,True,1.7994157113469297e+18,False,False,252,0,0,0,qme,2009-12-30 03:14:54+00:00,,142,False,@FoxNews 👍,"AnalyzerOutput(output=NEU, probas={NEU: 0.742, POS: 0.222, NEG: 0.036})",NEU,0.7422637343406677,0.2218593806028366,0.035876963287591934
|
35 |
+
https://x.com/SandraL24469181/status/1799536500855447910,2024-06-08 20:18:30+00:00,1799536500855447910,True,1.7994157113469297e+18,False,False,268,0,4,0,en,2022-06-15 21:16:34+00:00,,313,False,"@FoxNews We will continue fighting for our peace and freedom 🙏🏼
|
36 |
+
God bless El Salvador 🇸🇻","AnalyzerOutput(output=NEU, probas={NEU: 0.494, POS: 0.436, NEG: 0.069})",NEU,0.49438440799713135,0.43638357520103455,0.0692320168018341
|
37 |
+
https://x.com/lwrnjej/status/1799536830125093273,2024-06-08 20:19:48+00:00,1799536830125093273,True,1.7994157113469297e+18,False,False,142,0,1,0,en,2021-11-07 12:44:43+00:00,,276,False,@FoxNews @stacyherbert Wish the USA had a present like Bukele,"AnalyzerOutput(output=POS, probas={POS: 0.438, NEU: 0.356, NEG: 0.206})",POS,0.35599008202552795,0.4382016360759735,0.20580820739269257
|
38 |
+
https://x.com/carlostejada035/status/1799537452719145364,2024-06-08 20:22:17+00:00,1799537452719145364,True,1.7994157113469297e+18,False,False,233,0,1,0,en,2016-05-08 18:48:26+00:00,"San Salvador, El Salvador",661,False,@FoxNews He has data to back it up! Safest country in the Americas!,"AnalyzerOutput(output=POS, probas={POS: 0.894, NEU: 0.086, NEG: 0.020})",POS,0.08602020144462585,0.8940752148628235,0.019904570654034615
|
39 |
+
https://x.com/aradjkoemar/status/1799538546493083889,2024-06-08 20:26:37+00:00,1799538546493083889,True,1.7994157113469297e+18,False,False,898,0,12,0,en,2009-03-26 21:38:08+00:00,Suriname,94,True,@FoxNews @nayibbukele The man with balls of steel,"AnalyzerOutput(output=POS, probas={POS: 0.455, NEU: 0.419, NEG: 0.126})",POS,0.4194059371948242,0.45458629727363586,0.1260078400373459
|
40 |
+
https://x.com/Santiagosioso/status/1799540084267426010,2024-06-08 20:32:44+00:00,1799540084267426010,True,1.7994157113469297e+18,False,False,187,0,0,0,qme,2017-10-15 03:38:51+00:00,"Sonsonate, El Salvador",2392,False,@FoxNews 👏👏👏👏👏👏👏👏👏👏👏👏,"AnalyzerOutput(output=NEU, probas={NEU: 0.595, POS: 0.282, NEG: 0.123})",NEU,0.5948660969734192,0.2820890247821808,0.12304489314556122
|
41 |
+
https://x.com/EvelynC724698/status/1799541238447948050,2024-06-08 20:37:19+00:00,1799541238447948050,True,1.7994157113469297e+18,False,False,188,0,3,0,en,2022-06-08 21:36:32+00:00,,162,False,@FoxNews @waraujo64 The BEST PRESIDENT in the world. Other presidents should follow his lead and start protecting their citizens from criminals.,"AnalyzerOutput(output=POS, probas={POS: 0.678, NEU: 0.171, NEG: 0.150})",POS,0.17119131982326508,0.6783996224403381,0.15040911734104156
|
42 |
+
https://x.com/MelomanoSD/status/1799543744410378359,2024-06-08 20:47:17+00:00,1799543744410378359,True,1.7994157113469297e+18,False,False,453,0,0,0,en,2009-11-25 17:44:49+00:00,San Diego,239,True,@FoxNews @nayibbukele An article written full of entire paragraph quotes 🤣,"AnalyzerOutput(output=NEU, probas={NEU: 0.782, NEG: 0.114, POS: 0.104})",NEU,0.7818252444267273,0.1038544774055481,0.11432024836540222
|
43 |
+
https://x.com/BenedinD/status/1799544817900208361,2024-06-08 20:51:33+00:00,1799544817900208361,True,1.7994157113469297e+18,False,False,179,1,8,0,et,2023-10-12 23:03:28+00:00,,262,False,@FoxNews Bukele 😎😎😎🇸🇻🇸🇻🇸🇻 https://t.co/MSjDE9xByt,"AnalyzerOutput(output=NEU, probas={NEU: 0.732, POS: 0.135, NEG: 0.132})",NEU,0.7324954867362976,0.13508182764053345,0.13242268562316895
|
44 |
+
https://x.com/ReinaRomero79/status/1799548028157599987,2024-06-08 21:04:18+00:00,1799548028157599987,True,1.7994157113469297e+18,False,False,151,0,2,0,qme,2010-01-03 20:11:24+00:00,,976,False,@FoxNews ❤️❤️❤️❤️❤️❤️❤️🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻❤️❤️❤️❤️❤️❤️❤️❤️❤️ https://t.co/gO2s5xkI6j,"AnalyzerOutput(output=NEU, probas={NEU: 0.644, NEG: 0.260, POS: 0.096})",NEU,0.6437480449676514,0.09584653377532959,0.26040542125701904
|
45 |
+
https://x.com/MrElegantesv/status/1799551173986238666,2024-06-08 21:16:48+00:00,1799551173986238666,True,1.7994157113469297e+18,False,False,598,0,3,0,qme,2019-06-10 20:23:46+00:00,Te Sigue,46626,True,@FoxNews 🇸🇻,"AnalyzerOutput(output=NEU, probas={NEU: 0.820, POS: 0.116, NEG: 0.064})",NEU,0.8200681209564209,0.11629193276166916,0.06363990902900696
|
46 |
+
https://x.com/nolathoth/status/1799556598802862131,2024-06-08 21:38:21+00:00,1799556598802862131,True,1.7994157113469297e+18,False,False,122,0,2,0,en,2013-09-19 07:34:59+00:00,Ouray Colorado ,88,False,@FoxNews It is truly incredible what this man has done in a few short years!,"AnalyzerOutput(output=POS, probas={POS: 0.911, NEU: 0.046, NEG: 0.043})",POS,0.04624466970562935,0.9110117554664612,0.04274357855319977
|
47 |
+
https://x.com/Yazcklin/status/1799556919398425003,2024-06-08 21:39:38+00:00,1799556919398425003,True,1.7994157113469297e+18,False,False,459,1,5,0,qme,2011-04-17 05:17:37+00:00,El Salvador,23184,True,@FoxNews @nayibbukele 🇸🇻💪,"AnalyzerOutput(output=NEU, probas={NEU: 0.746, POS: 0.155, NEG: 0.099})",NEU,0.7461326122283936,0.15473179519176483,0.09913555532693863
|
48 |
+
https://x.com/Izalco257/status/1799557628533600301,2024-06-08 21:42:27+00:00,1799557628533600301,True,1.7994157113469297e+18,False,False,139,0,1,0,en,2022-10-09 04:22:26+00:00,,69,False,"@FoxNews When leaders are not corrupt, they are against corruption and do whatever it takes to finish it; at all cost.
|
49 |
+
There are some leaders that live off corruption, that is why they don't do anything to stop it.
|
50 |
+
|
51 |
+
And the most important point is they are against the will of God.","AnalyzerOutput(output=NEG, probas={NEG: 0.698, NEU: 0.175, POS: 0.127})",NEG,0.17493435740470886,0.12712764739990234,0.6979379653930664
|
52 |
+
https://x.com/uziel_Mazai/status/1799561018453938608,2024-06-08 21:55:55+00:00,1799561018453938608,True,1.7994157113469297e+18,False,False,48,0,0,0,ht,2022-07-28 04:00:39+00:00,universo C-137,407,False,@FoxNews Grande Nayib 👏❤️❤️❤️,"AnalyzerOutput(output=POS, probas={POS: 0.902, NEU: 0.084, NEG: 0.015})",POS,0.08354184031486511,0.9019206762313843,0.014537504874169827
|
53 |
+
https://x.com/SpaydiParodia/status/1799579807157551319,2024-06-08 23:10:35+00:00,1799579807157551319,True,1.7994157113469297e+18,False,False,310,0,4,0,en,2022-07-20 05:47:50+00:00,"Tampa, FL",13927,True,@FoxNews Facts. https://t.co/gK0bJbaaFm,"AnalyzerOutput(output=NEU, probas={NEU: 0.559, POS: 0.276, NEG: 0.164})",NEU,0.5592828989028931,0.27649542689323425,0.1642216295003891
|
54 |
+
https://x.com/Bandit12194161/status/1799609190857490827,2024-06-09 01:07:20+00:00,1799609190857490827,True,1.7994157113469297e+18,False,False,38,0,0,0,en,2024-04-26 20:31:34+00:00,,6,False,@FoxNews @nayibbukele The average wage in El Salvador is $300 a month. Cost of living is almost the same if not more expensive than the US,"AnalyzerOutput(output=NEU, probas={NEU: 0.576, NEG: 0.337, POS: 0.087})",NEU,0.5759305357933044,0.08714950084686279,0.3369199335575104
|
55 |
+
https://x.com/auvi_lu/status/1799665453704613979,2024-06-09 04:50:54+00:00,1799665453704613979,True,1.7994157113469297e+18,False,False,41,0,0,1,en,2016-03-25 03:26:05+00:00,,4370,False,"@FoxNews Yeah the dictator is great for the moment, until he isnt.","AnalyzerOutput(output=POS, probas={POS: 0.368, NEU: 0.328, NEG: 0.305})",POS,0.327534556388855,0.3677097260951996,0.3047557473182678
|
assets/dataset/temp_output_combined2.csv
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
url,createdAt,id,isReply,inReplyToId,isRetweet,isQuote,viewCount,retweetCount,likeCount,replyCount,lang,author__createdAt,author__location,author__followers,author__verified,text,sentiment,sentiment_label,sentiment_numeric,date
|
2 |
+
https://x.com/UHN_Plus/status/1754288067093950586,2024-02-04 23:37:22+00:00,1754288067093950586,False,None,False,False,3140522,7867,64116,841,es,2023-02-14 19:27:11+00:00,,740175,True,🇸🇻 | ÚLTIMA HORA: Nayib Bukele es reelecto como Presidente de El Salvador. https://t.co/6UQRk3KvkO,"AnalyzerOutput(output=NEU, probas={NEU: 0.648, NEG: 0.265, POS: 0.087})",NEU,POS,2024-02-04
|
3 |
+
https://x.com/pobreysintierra/status/1754288336112324883,2024-02-04 23:38:27+00:00,1754288336112324883,True,1754288067093950586,False,False,551,0,3,0,qme,2023-10-26 22:02:00+00:00,,10,False,@UHN_Plus 🥱,"AnalyzerOutput(output=NEG, probas={NEG: 0.555, NEU: 0.408, POS: 0.036})",NEG,POS,2024-02-04
|
4 |
+
https://x.com/Eduardo78122204/status/1754288437727834314,2024-02-04 23:38:51+00:00,1754288437727834314,True,1754288067093950586,False,False,1227,0,5,3,es,2015-11-13 13:12:21+00:00,"Santa Tecla, El Salvador",32,False,"@UHN_Plus Es ilegal!
|
5 |
+
Fraude !","AnalyzerOutput(output=NEG, probas={NEG: 0.872, NEU: 0.108, POS: 0.019})",NEG,POS,2024-02-04
|
6 |
+
https://x.com/Gabriel96070715/status/1754288592107589718,2024-02-04 23:39:28+00:00,1754288592107589718,True,1754288067093950586,False,False,40,0,0,0,es,2021-05-19 09:15:25+00:00,Argentina,823,False,@UHN_Plus Excelente noticia 😄👍🏻 https://t.co/ejKSGRldCm,"AnalyzerOutput(output=POS, probas={POS: 0.863, NEU: 0.126, NEG: 0.011})",POS,POS,2024-02-04
|
7 |
+
https://x.com/AaronRios90/status/1754288755345674340,2024-02-04 23:40:07+00:00,1754288755345674340,True,1754288067093950586,False,True,7964,7,40,1,es,2018-08-01 20:59:18+00:00,"Callao, Perú",1140,False,"@UHN_Plus #URGENTE. La encuestadora CIP Gallup le otorga el 87% de intención de voto al mandatario Nayib Bukele.
|
8 |
+
El presidente de El Salvador que optaba por la reelección logró una categórica victoria con números aún mejores de los sondeos previos.
|
9 |
+
https://t.co/AxHtWpxZ9W","AnalyzerOutput(output=NEU, probas={NEU: 0.715, POS: 0.175, NEG: 0.110})",NEU,POS,2024-02-04
|
10 |
+
https://x.com/Marfil37/status/1754288792859451823,2024-02-04 23:40:15+00:00,1754288792859451823,True,1754288067093950586,False,False,587,0,8,0,es,2011-05-21 20:24:58+00:00,Spain,420,False,@UHN_Plus Renace El Salvador ✝️,"AnalyzerOutput(output=NEU, probas={NEU: 0.715, POS: 0.223, NEG: 0.062})",NEU,POS,2024-02-04
|
11 |
+
https://x.com/LuisAld8/status/1754288827403829312,2024-02-04 23:40:24+00:00,1754288827403829312,True,1754288067093950586,False,False,427,0,2,1,es,2022-07-17 20:56:53+00:00,,0,False,@UHN_Plus La dictadura continúa!,"AnalyzerOutput(output=NEG, probas={NEG: 0.827, NEU: 0.148, POS: 0.025})",NEG,POS,2024-02-04
|
12 |
+
https://x.com/PepBohrquez/status/1754288963953578307,2024-02-04 23:40:56+00:00,1754288963953578307,True,1754288067093950586,False,False,617,0,2,0,es,2017-07-20 01:18:30+00:00,,999,False,@UHN_Plus Felicitaciones @nayibbukele saludos desde #Ecuador,"AnalyzerOutput(output=POS, probas={POS: 0.796, NEU: 0.187, NEG: 0.017})",POS,POS,2024-02-04
|
13 |
+
https://x.com/h_e_b_e/status/1754289021214249317,2024-02-04 23:41:10+00:00,1754289021214249317,True,1754288067093950586,False,False,4000,0,15,2,es,2014-06-15 15:13:08+00:00,,121,False,"@UHN_Plus Sin comentarios
|
14 |
+
|
15 |
+
Aún no ha nacido alguien q se pueda parar al lado de este señor 🤫","AnalyzerOutput(output=NEG, probas={NEG: 0.572, NEU: 0.413, POS: 0.014})",NEG,POS,2024-02-04
|
16 |
+
https://x.com/h_e_b_e/status/1754289048405823922,2024-02-04 23:41:16+00:00,1754289048405823922,True,1754288067093950586,False,False,1270,0,2,0,qme,2014-06-15 15:13:08+00:00,,121,False,@UHN_Plus 🫡,"AnalyzerOutput(output=NEU, probas={NEU: 0.793, POS: 0.123, NEG: 0.084})",NEU,POS,2024-02-04
|
17 |
+
https://x.com/EloyFe2626/status/1754289089711341727,2024-02-04 23:41:26+00:00,1754289089711341727,True,1754288067093950586,False,False,4529,1,34,3,es,2020-11-01 11:30:11+00:00,𝒩𝓊𝓃𝒸𝒶 𝒥𝒶𝓂𝒶𝓈,1458,False,@UHN_Plus Que proceso tan ordenado y rápido 😮 en cambio en Venezuela el dictador Nicolás Maduro tarda horas y horas para maquillar cifras con los software adulterados,"AnalyzerOutput(output=NEG, probas={NEG: 0.612, NEU: 0.353, POS: 0.034})",NEG,POS,2024-02-04
|
18 |
+
https://x.com/fonsi20201/status/1754289269667979597,2024-02-04 23:42:09+00:00,1754289269667979597,True,1754288067093950586,False,False,3426,0,5,8,es,2020-06-16 16:52:29+00:00,,3492,False,@UHN_Plus Otro @AlvaroUribeVel versión 2.0 y ya sabemos en que acaba todo,"AnalyzerOutput(output=NEG, probas={NEG: 0.635, NEU: 0.338, POS: 0.028})",NEG,POS,2024-02-04
|
19 |
+
https://x.com/bibipuchis4/status/1754289290731725300,2024-02-04 23:42:14+00:00,1754289290731725300,True,1754288067093950586,False,False,788,0,0,0,qme,2023-08-13 17:18:53+00:00,planet Earth,64,False,@UHN_Plus https://t.co/RWTXSfhmND,"AnalyzerOutput(output=NEU, probas={NEU: 0.482, POS: 0.331, NEG: 0.186})",NEU,POS,2024-02-04
|
20 |
+
https://x.com/Moral2095/status/1754289348340494721,2024-02-04 23:42:28+00:00,1754289348340494721,True,1754288067093950586,False,False,2540,0,3,1,es,2017-12-31 03:45:21+00:00,"Santa Ana, El Salvador",666,False,@UHN_Plus El tiempo de votar va terminando... si es lo más probable que gane pero quién lo ha dado como ganador oficialmente?,"AnalyzerOutput(output=NEU, probas={NEU: 0.887, NEG: 0.078, POS: 0.035})",NEU,POS,2024-02-04
|
21 |
+
https://x.com/Cesi20557320/status/1754289438379651237,2024-02-04 23:42:49+00:00,1754289438379651237,True,1754288067093950586,False,False,2673,0,0,4,es,2019-06-27 16:41:30+00:00,Santiago,1846,False,@UHN_Plus Cuantos bitcoin habra pagado ?,"AnalyzerOutput(output=NEU, probas={NEU: 0.766, NEG: 0.174, POS: 0.060})",NEU,POS,2024-02-04
|
22 |
+
https://x.com/BenjaminSG94/status/1754289486702227567,2024-02-04 23:43:01+00:00,1754289486702227567,True,1754288067093950586,False,False,1341,0,1,0,es,2023-01-09 20:54:03+00:00,,2,False,@UHN_Plus Sabiamos que iba a ganar lo que hay que preguntarse es por cuanto,"AnalyzerOutput(output=NEU, probas={NEU: 0.754, NEG: 0.149, POS: 0.096})",NEU,POS,2024-02-04
|
23 |
+
https://x.com/JaviXCubaLibre2/status/1754289498715049994,2024-02-04 23:43:04+00:00,1754289498715049994,True,1754288067093950586,False,False,42521,9,639,7,es,2022-08-03 22:28:40+00:00,"Austin, TX",10419,True,@UHN_Plus La ONU se muere de envidia 👌,"AnalyzerOutput(output=NEU, probas={NEU: 0.566, POS: 0.300, NEG: 0.134})",NEU,POS,2024-02-04
|
24 |
+
https://x.com/lamb503/status/1754289716369703252,2024-02-04 23:43:56+00:00,1754289716369703252,True,1754288067093950586,False,False,1389,0,7,0,es,2022-05-29 04:52:37+00:00,El Salvador,43,False,@UHN_Plus No mamen si a penas está iniciando el conteo preliminar.,"AnalyzerOutput(output=NEG, probas={NEG: 0.875, NEU: 0.110, POS: 0.015})",NEG,POS,2024-02-04
|
25 |
+
https://x.com/CarlosM88582762/status/1754289777073860765,2024-02-04 23:44:10+00:00,1754289777073860765,True,1754288067093950586,False,False,349,0,2,0,es,2021-03-12 16:58:41+00:00,"Cali, Colombia",155,False,@UHN_Plus @claudia04213250 Excelente el nuevo orden mundial llora.,"AnalyzerOutput(output=NEG, probas={NEG: 0.537, NEU: 0.393, POS: 0.070})",NEG,POS,2024-02-04
|
26 |
+
https://x.com/Argelado77/status/1754289931768287410,2024-02-04 23:44:47+00:00,1754289931768287410,True,1754288067093950586,False,False,166,0,0,0,qme,2023-09-04 20:51:10+00:00,,247,False,@UHN_Plus @DANTE_eloficial https://t.co/R4ev3T69k1,"AnalyzerOutput(output=NEU, probas={NEU: 0.455, POS: 0.357, NEG: 0.187})",NEU,POS,2024-02-04
|
27 |
+
https://x.com/FloresGuer2335/status/1754290072906592569,2024-02-04 23:45:21+00:00,1754290072906592569,True,1754288067093950586,False,False,667,0,7,0,es,2023-07-01 00:26:07+00:00,,33,False,@UHN_Plus Por supuesto que fue lo mejor un presidente con huevos en la mañana en la tarde y en la noche eso hace falta aquí para vivir tranquilos,"AnalyzerOutput(output=POS, probas={POS: 0.967, NEU: 0.028, NEG: 0.005})",POS,POS,2024-02-04
|
28 |
+
https://x.com/dha4nos/status/1754290579033280519,2024-02-04 23:47:21+00:00,1754290579033280519,True,1754288067093950586,False,False,260,0,0,0,es,2023-03-25 15:48:15+00:00,,8,False,"@UHN_Plus @DANTE_eloficial Aunque sabemos que @nayibbukele ganará, no den información adelantada. Son las 5:47 pm en El Salvador y a penas están en conteo de votos manuales. Cómo dije seguramente hemos vencido otra vez pero paciencia, los resultados preliminares estarán listos en las próximas horas.","AnalyzerOutput(output=NEU, probas={NEU: 0.785, NEG: 0.166, POS: 0.049})",NEU,POS,2024-02-04
|
29 |
+
https://x.com/avainavale/status/1754290655516336440,2024-02-04 23:47:40+00:00,1754290655516336440,True,1754288067093950586,False,False,390,0,1,0,es,2022-11-03 00:11:02+00:00,Aquí mismo ,3,False,@UHN_Plus Y lo dudaban...,"AnalyzerOutput(output=NEG, probas={NEG: 0.489, NEU: 0.446, POS: 0.065})",NEG,POS,2024-02-04
|
30 |
+
https://x.com/nombreusuariom/status/1754290800446345237,2024-02-04 23:48:14+00:00,1754290800446345237,True,1754288067093950586,False,False,9,0,0,0,es,2023-10-09 02:48:23+00:00,que es palestina se come,56,False,@UHN_Plus Cuál es la noticia?😜,"AnalyzerOutput(output=NEU, probas={NEU: 0.856, POS: 0.111, NEG: 0.034})",NEU,POS,2024-02-04
|
31 |
+
https://x.com/MaTerry50/status/1754290893157179729,2024-02-04 23:48:36+00:00,1754290893157179729,True,1754288067093950586,False,False,608,0,1,0,qme,2020-04-29 21:20:22+00:00,,586,False,@UHN_Plus @YannisEst 👏👏👏👏👏,"AnalyzerOutput(output=NEU, probas={NEU: 0.613, POS: 0.266, NEG: 0.121})",NEU,POS,2024-02-04
|
32 |
+
https://x.com/UltimatusVirsus/status/1754290974950400254,2024-02-04 23:48:56+00:00,1754290974950400254,True,1754288067093950586,False,False,628,0,1,0,es,2018-02-27 05:34:38+00:00,,78,False,@UHN_Plus Tan rápido? No ha pasado ni un día XD,"AnalyzerOutput(output=NEG, probas={NEG: 0.728, NEU: 0.237, POS: 0.035})",NEG,POS,2024-02-04
|
33 |
+
https://x.com/PEPE19241899/status/1754291105217089578,2024-02-04 23:49:27+00:00,1754291105217089578,True,1754288067093950586,False,False,2050,0,10,3,es,2020-08-21 16:34:21+00:00,,382,False,@UHN_Plus La nueva dictadura,"AnalyzerOutput(output=NEG, probas={NEG: 0.712, NEU: 0.234, POS: 0.054})",NEG,POS,2024-02-04
|
34 |
+
https://x.com/JafetAntonioo/status/1754291111206477930,2024-02-04 23:49:28+00:00,1754291111206477930,True,1754288067093950586,False,False,508,0,0,0,und,2017-10-26 05:23:18+00:00,🇵🇦,388,False,@UHN_Plus Eso 🔥🔥🔥😎💪,"AnalyzerOutput(output=NEU, probas={NEU: 0.649, POS: 0.189, NEG: 0.162})",NEU,POS,2024-02-04
|
35 |
+
https://x.com/YannisEst/status/1754292650658705603,2024-02-04 23:55:35+00:00,1754292650658705603,True,1754288067093950586,False,False,38815,19,445,5,es,2011-03-27 01:50:59+00:00,"Miami, FL",70793,True,@UHN_Plus Comienza el llanto desconsolado de los “Soros’ employees”.,"AnalyzerOutput(output=NEG, probas={NEG: 0.856, NEU: 0.136, POS: 0.008})",NEG,POS,2024-02-04
|
36 |
+
https://x.com/OlmedoVive/status/1754293234468090163,2024-02-04 23:57:54+00:00,1754293234468090163,True,1754288067093950586,False,False,43637,18,382,11,es,2012-11-17 14:13:02+00:00,Siempre en la Libertad,5725,True,"Bien por el pueblo de El Salvador 👏 ellos confían en la mano dura de Bukele contra el terrorismo y las pandillas, el pueblo ve la obra social y la obra pública en un país que era el más violento del mundo hasta que llegó este joven Presidente.
|
37 |
+
La gente de cualquier parte del mundo aplaude el cambio radical que se ve en El Salvador, obviamente la clase política que no tienen siquiera el 10% de credibilidad y aceptación dicen de todo para intentar desestabilizar y desacreditar","AnalyzerOutput(output=NEG, probas={NEG: 0.456, POS: 0.410, NEU: 0.135})",NEG,POS,2024-02-04
|
38 |
+
https://x.com/Inforojita/status/1754295371327537577,2024-02-05 00:06:24+00:00,1754295371327537577,True,1754288067093950586,False,False,43695,115,365,242,es,2010-04-28 18:41:36+00:00,Venezuela,100174,True,"@UHN_Plus Si Maduro se postula a la reelección, apegado a la Constitución de Venezuela, es porque es ""un dictador que quiere perpetuarse en el poder""... Pero si lo hace Bukele violando la Constitución, es un ""democrata"" para la prensa tarifada...","AnalyzerOutput(output=NEG, probas={NEG: 0.909, NEU: 0.081, POS: 0.009})",NEG,POS,2024-02-05
|
39 |
+
https://x.com/cranss_/status/1754298195033612656,2024-02-05 00:17:37+00:00,1754298195033612656,True,1754288067093950586,False,False,10035,0,6,0,et,2014-04-16 02:28:43+00:00,サンティアゴ、チリ,306,True,@UHN_Plus 😎🚬 cine,"AnalyzerOutput(output=NEU, probas={NEU: 0.749, POS: 0.216, NEG: 0.036})",NEU,POS,2024-02-05
|
40 |
+
https://x.com/aesagt/status/1754300533232304484,2024-02-05 00:26:55+00:00,1754300533232304484,True,1754288067093950586,False,False,9771,0,3,0,es,2009-03-25 23:27:55+00:00,GT,2488,True,@UHN_Plus Bien!,"AnalyzerOutput(output=POS, probas={POS: 0.765, NEU: 0.177, NEG: 0.059})",POS,POS,2024-02-05
|
41 |
+
https://x.com/YoelDanielR/status/1754300817761284202,2024-02-05 00:28:02+00:00,1754300817761284202,True,1754288067093950586,False,False,5102,0,2,0,es,2020-02-27 14:40:02+00:00,🌎,728,True,@UHN_Plus Amén,"AnalyzerOutput(output=NEU, probas={NEU: 0.461, POS: 0.377, NEG: 0.162})",NEU,POS,2024-02-05
|
42 |
+
https://x.com/VeraMReyes/status/1754301445929636176,2024-02-05 00:30:32+00:00,1754301445929636176,True,1754288067093950586,False,False,5325,0,13,6,ca,2010-05-22 02:04:17+00:00,México,461,True,"@UHN_Plus El inconstitucional, el impostor.","AnalyzerOutput(output=NEG, probas={NEG: 0.636, NEU: 0.327, POS: 0.037})",NEG,POS,2024-02-05
|
43 |
+
https://x.com/VeraMReyes/status/1754301959715053699,2024-02-05 00:32:35+00:00,1754301959715053699,True,1754288067093950586,False,False,18445,8,62,21,es,2010-05-22 02:04:17+00:00,México,461,True,"@UHN_Plus Lo declararon cuando ni siquiera han hecho el conteo. Ese es el fraude al haber impuesto a un candidato inconstitucional y ya hasta lo declararon presidente, que bárbaros que burdos.","AnalyzerOutput(output=NEG, probas={NEG: 0.978, NEU: 0.017, POS: 0.005})",NEG,POS,2024-02-05
|
44 |
+
https://x.com/TzaTza416/status/1754303762858901823,2024-02-05 00:39:45+00:00,1754303762858901823,True,1754288067093950586,False,False,19419,6,94,40,es,2021-08-01 19:03:04+00:00,Chalatenango. Te Sigue ,3775,True,@UHN_Plus Es reelecto ILEGALMENTE,"AnalyzerOutput(output=NEG, probas={NEG: 0.710, NEU: 0.236, POS: 0.054})",NEG,POS,2024-02-05
|
45 |
+
https://x.com/rolanrama/status/1754305631572402590,2024-02-05 00:47:10+00:00,1754305631572402590,True,1754288067093950586,False,False,4774,0,12,0,qme,2011-09-14 02:13:42+00:00,Guatemala Ciudad,1848,True,@UHN_Plus https://t.co/zBD7ff6Go9,"AnalyzerOutput(output=NEU, probas={NEU: 0.482, POS: 0.331, NEG: 0.186})",NEU,POS,2024-02-05
|
46 |
+
https://x.com/ClaudiaYadette1/status/1754306944494395555,2024-02-05 00:52:23+00:00,1754306944494395555,True,1754288067093950586,False,False,8811,0,4,0,es,2021-10-17 18:39:01+00:00,"Minnesota,USA",2783,True,"@UHN_Plus Estan super update, me parece que fueron los primeros en decir @nayibbukele revalidó!! 👏👏👏","AnalyzerOutput(output=POS, probas={POS: 0.625, NEU: 0.340, NEG: 0.035})",POS,POS,2024-02-05
|
47 |
+
https://x.com/UHN_Plus/status/1754309043928121508,2024-02-05 01:00:44+00:00,1754309043928121508,True,1754288067093950586,False,False,47946,59,649,15,es,2023-02-14 19:27:11+00:00,,740175,True,"Nayib Bukele ganó la reelección con más del 85% de los votos. A las 9:00 pm, hora local, está previsto que el Presidente se dirija al país y al mundo, desde el Palacio Nacional.","AnalyzerOutput(output=NEU, probas={NEU: 0.722, POS: 0.236, NEG: 0.042})",NEU,POS,2024-02-05
|
48 |
+
https://x.com/lumbrerablog/status/1754310859730362459,2024-02-05 01:07:57+00:00,1754310859730362459,True,1754288067093950586,False,False,5497,0,9,0,es,2010-06-24 14:40:50+00:00,De Rep. Dom (en gringolandia),21401,True,@UHN_Plus Se lo merece.,"AnalyzerOutput(output=POS, probas={POS: 0.868, NEU: 0.106, NEG: 0.026})",POS,POS,2024-02-05
|
49 |
+
https://x.com/TheDesertLynx/status/1754316408895217848,2024-02-05 01:30:00+00:00,1754316408895217848,True,1754288067093950586,False,True,10494,0,9,1,qme,2012-02-04 01:47:29+00:00,New Hampshire,13028,True,@UHN_Plus https://t.co/rMdzEy0cux,"AnalyzerOutput(output=NEU, probas={NEU: 0.482, POS: 0.331, NEG: 0.186})",NEU,POS,2024-02-05
|
50 |
+
https://x.com/SaulQCh_/status/1754319753378664863,2024-02-05 01:43:17+00:00,1754319753378664863,True,1754288067093950586,False,False,5393,0,1,0,qme,2014-12-11 01:26:15+00:00,Planet Earth 🌎,280,True,@UHN_Plus 💯,"AnalyzerOutput(output=NEU, probas={NEU: 0.614, POS: 0.333, NEG: 0.053})",NEU,POS,2024-02-05
|
51 |
+
https://x.com/rios_saryriver/status/1754349092736487819,2024-02-05 03:39:52+00:00,1754349092736487819,True,1754288067093950586,False,False,71,0,0,0,es,2017-12-13 18:15:04+00:00,,207,False,"@UHN_Plus Felicitaciones al pueblo salvadoreño, qué tenga un exitoso periodo de su nuevo mandato","AnalyzerOutput(output=POS, probas={POS: 0.945, NEU: 0.048, NEG: 0.007})",POS,POS,2024-02-05
|
52 |
+
https://x.com/jimmynewsES/status/1754362183192850834,2024-02-05 04:31:53+00:00,1754362183192850834,True,1754288067093950586,False,True,5354,2,28,0,qme,2023-04-07 14:21:40+00:00,,1271,True,@UHN_Plus https://t.co/haVq0b1bKg,"AnalyzerOutput(output=NEU, probas={NEU: 0.482, POS: 0.331, NEG: 0.186})",NEU,POS,2024-02-05
|
53 |
+
https://x.com/Red4293/status/1754401957828050974,2024-02-05 07:09:56+00:00,1754401957828050974,True,1754288067093950586,False,False,943,0,0,0,es,2009-07-02 18:47:39+00:00,"Community of Madrid, Spain",602,True,@UHN_Plus Wow que sorpresa. ! 😳,"AnalyzerOutput(output=POS, probas={POS: 0.497, NEU: 0.450, NEG: 0.053})",POS,POS,2024-02-05
|
54 |
+
https://x.com/GUnderground_TV/status/1754406809031372889,2024-02-05 07:29:13+00:00,1754406809031372889,True,1754288067093950586,False,False,1742,0,1,0,qme,2013-10-16 13:54:32+00:00,"Dubai, United Arab Emirates",143201,True,@UHN_Plus https://t.co/2vr9kG91Pv,"AnalyzerOutput(output=NEU, probas={NEU: 0.482, POS: 0.331, NEG: 0.186})",NEU,POS,2024-02-05
|
55 |
+
https://x.com/DAmericasFuture/status/1799118639615860770,2024-06-07 16:38:04+00:00,1799118639615860770,False,None,False,False,1001778,104,718,499,en,2024-05-24 16:18:12+00:00,,122,True,"The radical Left has LOST THEIR MINDS!
|
56 |
+
|
57 |
+
SIGN YOUR NAME TO SEND A PRAYER TO PRESIDENT TRUMP >>>","AnalyzerOutput(output=NEG, probas={NEG: 0.745, NEU: 0.171, POS: 0.084})",NEG,POS,2024-06-07
|
58 |
+
https://x.com/DAmericasFuture/status/1799118639615860770,2024-06-07 16:38:04+00:00,1799118639615860770,False,None,False,False,1001778,104,718,499,en,2024-05-24 16:18:12+00:00,,122,True,"The radical Left has LOST THEIR MINDS!
|
59 |
+
|
60 |
+
SIGN YOUR NAME TO SEND A PRAYER TO PRESIDENT TRUMP >>>","AnalyzerOutput(output=NEG, probas={NEG: 0.745, NEU: 0.171, POS: 0.084})",NEG,POS,2024-06-07
|
61 |
+
https://x.com/DAmericasFuture/status/1799118639615860770,2024-06-07 16:38:04+00:00,1799118639615860770,False,None,False,False,1001778,104,718,499,en,2024-05-24 16:18:12+00:00,,122,True,"The radical Left has LOST THEIR MINDS!
|
62 |
+
|
63 |
+
SIGN YOUR NAME TO SEND A PRAYER TO PRESIDENT TRUMP >>>","AnalyzerOutput(output=NEG, probas={NEG: 0.745, NEU: 0.171, POS: 0.084})",NEG,POS,2024-06-07
|
64 |
+
https://x.com/DAmericasFuture/status/1799118639615860770,2024-06-07 16:38:04+00:00,1799118639615860770,False,None,False,False,1001778,104,718,499,en,2024-05-24 16:18:12+00:00,,122,True,"The radical Left has LOST THEIR MINDS!
|
65 |
+
|
66 |
+
SIGN YOUR NAME TO SEND A PRAYER TO PRESIDENT TRUMP >>>","AnalyzerOutput(output=NEG, probas={NEG: 0.745, NEU: 0.171, POS: 0.084})",NEG,POS,2024-06-07
|
assets/dataset/temp_output_comments.csv
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
url,createdAt,id,isReply,inReplyToId,isRetweet,isQuote,viewCount,retweetCount,likeCount,replyCount,lang,author__createdAt,author__location,author__followers,author__verified,text
|
2 |
+
https://x.com/HerbertEsmahan/status/1799533895630655959,2024-06-08 20:08:09+00:00,1799533895630655959,True,1799415711346929732,False,False,4618,9,141,1,en,2021-02-03 02:58:21+00:00,El Salvador,20918,True,"@FoxNews @nayibbukele President @nayibbukele, through the grace of God, saved El Salvador! 🇸🇻"
|
3 |
+
https://x.com/CitizenCallerUS/status/1799416514732564840,2024-06-08 12:21:43+00:00,1799416514732564840,True,1799415711346929732,False,False,2975,2,30,2,en,2023-09-01 19:49:37+00:00,"Texas, USA",1192,True,"@FoxNews What's the philosophy behind this amazing turn around? Surely it's DEI or CRT or some kind of Woke stuff right?
|
4 |
+
|
5 |
+
Not a chance, it's just plain old common sense."
|
6 |
+
https://x.com/aradjkoemar/status/1799538546493083889,2024-06-08 20:26:37+00:00,1799538546493083889,True,1799415711346929732,False,False,898,0,12,0,en,2009-03-26 21:38:08+00:00,Suriname,94,True,@FoxNews @nayibbukele The man with balls of steel
|
7 |
+
https://x.com/BiologicalWoma2/status/1799417233224986797,2024-06-08 12:24:34+00:00,1799417233224986797,True,1799415711346929732,False,False,1597,2,32,1,en,2021-06-01 18:05:40+00:00,"Florida, USA",70810,True,@FoxNews We need more leaders like Bukele 👍🏽
|
8 |
+
https://x.com/StandUnited76/status/1799415831136550937,2024-06-08 12:19:00+00:00,1799415831136550937,True,1799415711346929732,False,False,2182,0,5,12,en,2022-04-27 14:30:03+00:00,"Arizona, USA",3317,True,@FoxNews good let’s send our illegals there!
|
9 |
+
https://x.com/PaoMarrohs/status/1799534180155482202,2024-06-08 20:09:16+00:00,1799534180155482202,True,1799415711346929732,False,False,1189,0,8,0,qme,2012-05-23 08:14:46+00:00,El Salvador,10076,True,@FoxNews 😎🇸🇻🙌🏻
|
10 |
+
https://x.com/Yazcklin/status/1799556919398425003,2024-06-08 21:39:38+00:00,1799556919398425003,True,1799415711346929732,False,False,459,1,5,0,qme,2011-04-17 05:17:37+00:00,El Salvador,23184,True,@FoxNews @nayibbukele 🇸🇻💪
|
11 |
+
https://x.com/MrElegantesv/status/1799551173986238666,2024-06-08 21:16:48+00:00,1799551173986238666,True,1799415711346929732,False,False,598,0,3,0,qme,2019-06-10 20:23:46+00:00,Te Sigue,46626,True,@FoxNews 🇸🇻
|
12 |
+
https://x.com/ChandanaJac/status/1799415857334063279,2024-06-08 12:19:06+00:00,1799415857334063279,True,1799415711346929732,False,True,2087,0,1,0,en,2023-11-20 20:06:31+00:00,,579,True,"@FoxNews He the best, unlike the puppetmaster😎"
|
13 |
+
https://x.com/SpaydiParodia/status/1799579807157551319,2024-06-08 23:10:35+00:00,1799579807157551319,True,1799415711346929732,False,False,310,0,4,0,en,2022-07-20 05:47:50+00:00,"Tampa, FL",13927,True,@FoxNews Facts. https://t.co/gK0bJbaaFm
|
14 |
+
https://x.com/riyaz25161/status/1799417601443201318,2024-06-08 12:26:02+00:00,1799417601443201318,True,1799415711346929732,False,False,952,0,2,0,en,2023-11-04 15:56:55+00:00,Qatar,3177,True,@FoxNews Hope bukele is good leader
|
15 |
+
https://x.com/MelomanoSD/status/1799543744410378359,2024-06-08 20:47:17+00:00,1799543744410378359,True,1799415711346929732,False,False,453,0,0,0,en,2009-11-25 17:44:49+00:00,San Diego,239,True,@FoxNews @nayibbukele An article written full of entire paragraph quotes 🤣
|
16 |
+
https://x.com/jimomics/status/1799415932173140135,2024-06-08 12:19:24+00:00,1799415932173140135,True,1799415711346929732,False,False,812,0,0,2,en,2016-08-09 16:57:44+00:00,,15647,True,@FoxNews Just if Biden did 1/10th of this...
|
17 |
+
https://x.com/bankoftime01/status/1799415790636294438,2024-06-08 12:18:50+00:00,1799415790636294438,True,1799415711346929732,False,True,1033,0,0,0,qme,2023-11-07 11:35:32+00:00,,929,True,@FoxNews 👇👇🚨🚨
|
18 |
+
https://x.com/PortoG1937/status/1799416603173364150,2024-06-08 12:22:04+00:00,1799416603173364150,True,1799415711346929732,False,False,541,0,0,2,en,2022-08-10 13:49:55+00:00,,636,False,"@FoxNews The population of ES is approx 6 Mio
|
19 |
+
|
20 |
+
It is a developing nation
|
21 |
+
|
22 |
+
Why would anyone want to migrate there?"
|
23 |
+
https://x.com/SteveAn07575136/status/1799421077325852757,2024-06-08 12:39:51+00:00,1799421077325852757,True,1799415711346929732,False,False,248,0,0,1,en,2021-12-14 03:08:58+00:00,,203,False,@FoxNews They are all in the US now.
|
24 |
+
https://x.com/auvi_lu/status/1799665453704613979,2024-06-09 04:50:54+00:00,1799665453704613979,True,1799415711346929732,False,False,41,0,0,1,en,2016-03-25 03:26:05+00:00,,4370,False,"@FoxNews Yeah the dictator is great for the moment, until he isnt."
|
25 |
+
https://x.com/Bandit12194161/status/1799609190857490827,2024-06-09 01:07:20+00:00,1799609190857490827,True,1799415711346929732,False,False,38,0,0,0,en,2024-04-26 20:31:34+00:00,,6,False,@FoxNews @nayibbukele The average wage in El Salvador is $300 a month. Cost of living is almost the same if not more expensive than the US
|
26 |
+
https://x.com/SandraL24469181/status/1799536500855447910,2024-06-08 20:18:30+00:00,1799536500855447910,True,1799415711346929732,False,False,268,0,4,0,en,2022-06-15 21:16:34+00:00,,313,False,"@FoxNews We will continue fighting for our peace and freedom 🙏🏼
|
27 |
+
God bless El Salvador 🇸🇻"
|
28 |
+
https://x.com/cx_shop/status/1799535839258788277,2024-06-08 20:15:52+00:00,1799535839258788277,True,1799415711346929732,False,False,252,0,0,0,qme,2009-12-30 03:14:54+00:00,,142,False,@FoxNews 👍
|
29 |
+
https://x.com/Izalco257/status/1799557628533600301,2024-06-08 21:42:27+00:00,1799557628533600301,True,1799415711346929732,False,False,139,0,1,0,en,2022-10-09 04:22:26+00:00,,69,False,"@FoxNews When leaders are not corrupt, they are against corruption and do whatever it takes to finish it; at all cost.
|
30 |
+
There are some leaders that live off corruption, that is why they don't do anything to stop it.
|
31 |
+
|
32 |
+
And the most important point is they are against the will of God."
|
33 |
+
https://x.com/carlostejada035/status/1799537452719145364,2024-06-08 20:22:17+00:00,1799537452719145364,True,1799415711346929732,False,False,233,0,1,0,en,2016-05-08 18:48:26+00:00,"San Salvador, El Salvador",661,False,@FoxNews He has data to back it up! Safest country in the Americas!
|
34 |
+
https://x.com/nolathoth/status/1799556598802862131,2024-06-08 21:38:21+00:00,1799556598802862131,True,1799415711346929732,False,False,122,0,2,0,en,2013-09-19 07:34:59+00:00,Ouray Colorado ,88,False,@FoxNews It is truly incredible what this man has done in a few short years!
|
35 |
+
https://x.com/Vianney41603586/status/1799533953591755117,2024-06-08 20:08:22+00:00,1799533953591755117,True,1799415711346929732,False,False,259,0,0,0,qme,2021-10-18 04:55:33+00:00,,33,False,@FoxNews @nayibbukele 👍👍🙏🏻👍👍
|
36 |
+
https://x.com/EvelynC724698/status/1799541238447948050,2024-06-08 20:37:19+00:00,1799541238447948050,True,1799415711346929732,False,False,188,0,3,0,en,2022-06-08 21:36:32+00:00,,162,False,@FoxNews @waraujo64 The BEST PRESIDENT in the world. Other presidents should follow his lead and start protecting their citizens from criminals.
|
37 |
+
https://x.com/Adub82UT/status/1799431150315958371,2024-06-08 13:19:52+00:00,1799431150315958371,True,1799415711346929732,False,False,237,0,2,0,en,2022-10-31 02:51:32+00:00,,27,False,"@FoxNews He brings God in, America is trying to take God out..🧐"
|
38 |
+
https://x.com/janainajaja_7/status/1799416463675310481,2024-06-08 12:21:31+00:00,1799416463675310481,True,1799415711346929732,False,False,218,0,0,0,und,2013-05-31 17:13:17+00:00,Aqui ó,15,False,"@FoxNews yay
|
39 |
+
|
40 |
+
https://t.co/1iZWuz8Sep"
|
41 |
+
https://x.com/apmoore1234/status/1799426430260162662,2024-06-08 13:01:07+00:00,1799426430260162662,True,1799415711346929732,False,False,248,0,1,1,en,2022-11-14 13:26:48+00:00,,130,False,@FoxNews A lot of these countries are doing better because they’ve sent all their prisoners and criminals to America
|
42 |
+
https://x.com/lwrnjej/status/1799536830125093273,2024-06-08 20:19:48+00:00,1799536830125093273,True,1799415711346929732,False,False,142,0,1,0,en,2021-11-07 12:44:43+00:00,,276,False,@FoxNews @stacyherbert Wish the USA had a present like Bukele
|
43 |
+
https://x.com/PhuongVannareth/status/1799418041165623613,2024-06-08 12:27:47+00:00,1799418041165623613,True,1799415711346929732,False,False,191,0,0,0,qme,2021-12-22 23:47:09+00:00,,136,False,@FoxNews 🙄😁😘🥰 https://t.co/qVXvdnszjs
|
44 |
+
https://x.com/ReinaRomero79/status/1799548028157599987,2024-06-08 21:04:18+00:00,1799548028157599987,True,1799415711346929732,False,False,151,0,2,0,qme,2010-01-03 20:11:24+00:00,,976,False,@FoxNews ❤️❤️❤️❤️❤️❤️❤️🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻🇸🇻❤️❤️❤️❤️❤️❤️❤️❤️❤️ https://t.co/gO2s5xkI6j
|
45 |
+
https://x.com/Santiagosioso/status/1799540084267426010,2024-06-08 20:32:44+00:00,1799540084267426010,True,1799415711346929732,False,False,187,0,0,0,qme,2017-10-15 03:38:51+00:00,"Sonsonate, El Salvador",2392,False,@FoxNews 👏👏👏👏👏👏👏👏👏👏👏👏
|
46 |
+
https://x.com/uziel_Mazai/status/1799561018453938608,2024-06-08 21:55:55+00:00,1799561018453938608,True,1799415711346929732,False,False,48,0,0,0,ht,2022-07-28 04:00:39+00:00,universo C-137,407,False,@FoxNews Grande Nayib 👏❤️❤️❤️
|
47 |
+
https://x.com/BenedinD/status/1799544817900208361,2024-06-08 20:51:33+00:00,1799544817900208361,True,1799415711346929732,False,False,179,1,8,0,et,2023-10-12 23:03:28+00:00,,262,False,@FoxNews Bukele 😎😎😎🇸🇻🇸🇻🇸🇻 https://t.co/MSjDE9xByt
|
48 |
+
https://x.com/b658842c5ab4475/status/1799419293076987924,2024-06-08 12:32:45+00:00,1799419293076987924,True,1799415711346929732,False,False,223,0,1,0,en,2016-09-05 00:09:02+00:00,New York/New Jersey,169,False,"@FoxNews How he did ? Bukele summoned The legislative Assembly to
|
49 |
+
suspend the constitutional guarantees - civil liberties- for 30 days which then it was extended 12 times. Unusual & unconventional but he curved crime .
|
50 |
+
|
51 |
+
Can U.S Congress do such & then challenge at the federal court?"
|
52 |
+
https://x.com/CBOhio62/status/1799415950569267652,2024-06-08 12:19:28+00:00,1799415950569267652,True,1799415711346929732,False,False,249,0,1,0,en,2014-01-23 17:31:10+00:00,Ohio,2910,False,@FoxNews They’ll be in better shape soon especially if Biden installed again.
|
53 |
+
https://x.com/Patriot1690/status/1799417579486036421,2024-06-08 12:25:57+00:00,1799417579486036421,True,1799415711346929732,False,False,180,0,0,1,en,2009-09-30 03:20:53+00:00,,296,False,@FoxNews Rolf https://t.co/fJygdemihi
|
54 |
+
https://x.com/Sarcornot/status/1799428980661178868,2024-06-08 13:11:15+00:00,1799428980661178868,True,1799415711346929732,False,False,176,0,1,8,en,2014-03-12 22:01:14+00:00,,1542,False,"@FoxNews He's a dictator! He has arrested and beat protesters. He's arresting ppl who have committed no crimes. Of course, Fox loves these types of dictators."
|
assets/html/about.html
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="text-align: center">
|
2 |
+
<br>
|
3 |
+
<table>
|
4 |
+
<tbody class="table">
|
5 |
+
<th width="20%" colspan="3">Team Members</th>
|
6 |
+
<tr width="20%">{team}</tr>
|
7 |
+
</tbody>
|
8 |
+
</table>
|
9 |
+
</div>
|
assets/img/PCE.png
ADDED
assets/img/background.jpg
ADDED
assets/img/banner.png
ADDED
assets/img/favicon.png
ADDED
assets/img/omdena_logo.png
ADDED
requirements.txt
ADDED
Binary file (728 Bytes). View file
|
|
st_pages/__init__.py
ADDED
File without changes
|
st_pages/about.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from utils.utils import load_header
|
3 |
+
from utils.constants import CONTRIBUTORS
|
4 |
+
|
5 |
+
def about_us_page(contributors):
|
6 |
+
load_header("Meet our CONTRIBUTORS")
|
7 |
+
|
8 |
+
data = contributors
|
9 |
+
full_string = ""
|
10 |
+
|
11 |
+
for i in range(0, len(data), 3):
|
12 |
+
try:
|
13 |
+
contributor1_name, contributor1_link = data[i]
|
14 |
+
contributor2_name, contributor2_link = data[i+1]
|
15 |
+
contributor3_name, contributor3_link = data[i+2]
|
16 |
+
|
17 |
+
CONTRIBUTORS = f"""<tr>
|
18 |
+
<td><a href='{contributor1_link}'>{contributor1_name}</a></td>
|
19 |
+
<td><a href='{contributor2_link}'>{contributor2_name}</a></td>
|
20 |
+
<td><a href='{contributor3_link}'>{contributor3_name}</a></td>
|
21 |
+
</tr>
|
22 |
+
"""
|
23 |
+
full_string += CONTRIBUTORS
|
24 |
+
|
25 |
+
except IndexError:
|
26 |
+
if len(data[i:])==2:
|
27 |
+
full_string += f"""<tr>
|
28 |
+
<td>
|
29 |
+
<a href='{data[i:][0][1]}'>{data[i:][0][0]}</a>
|
30 |
+
</td>
|
31 |
+
<td>
|
32 |
+
<a href='{data[i:][1][1]}'>{data[i:][1][0]}</a>
|
33 |
+
</td>
|
34 |
+
</tr>
|
35 |
+
"""
|
36 |
+
elif len(data[i:])==1:
|
37 |
+
full_string += f"""<tr>
|
38 |
+
<td>
|
39 |
+
<a href='{data[i:][0][1]}'>{data[i:][0][0]}</a> <a
|
40 |
+
</td>
|
41 |
+
</tr>
|
42 |
+
"""
|
43 |
+
with open('assets/html/about.html', 'r', encoding='utf-8') as file:
|
44 |
+
html_content = file.read()
|
45 |
+
|
46 |
+
st.write(html_content.format(team=full_string), unsafe_allow_html=True)
|
47 |
+
|
48 |
+
|
49 |
+
if __name__ == "__main__":
|
50 |
+
about_us_page(CONTRIBUTORS)
|
st_pages/analyse.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
from utils.scraper import fetch_main_tweet_dataframe, fetch_comments_dataframe
|
4 |
+
from utils.utils import load_header, is_valid_twitter_url, combine_author_and_comments_df
|
5 |
+
|
6 |
+
def analyse_page():
|
7 |
+
load_header("Analizar Tweet")
|
8 |
+
|
9 |
+
cols = st.columns([5,1,1])
|
10 |
+
|
11 |
+
with cols[0]:
|
12 |
+
twitter_url = st.text_input("Paste your link here:", placeholder="https://x.com/Google/status/1790555395041472948").strip()
|
13 |
+
|
14 |
+
with cols[1]:
|
15 |
+
st.write("<br>", unsafe_allow_html=True)
|
16 |
+
submitted = st.button("Submit", use_container_width=True)
|
17 |
+
|
18 |
+
if submitted and not is_valid_twitter_url(twitter_url):
|
19 |
+
st.toast("⚠️ Invalid URL")
|
20 |
+
|
21 |
+
if submitted and is_valid_twitter_url(twitter_url):
|
22 |
+
if 'master_df' not in st.session_state:
|
23 |
+
st.session_state['master_df'] = None
|
24 |
+
|
25 |
+
with st.spinner("Scraping data..."):
|
26 |
+
df_author = fetch_main_tweet_dataframe(twitter_url)
|
27 |
+
df_comments = fetch_comments_dataframe(twitter_url)
|
28 |
+
|
29 |
+
# df_author = pd.read_csv('assets/dataset/temp_output_author.csv')
|
30 |
+
# df_comments = pd.read_csv('assets/dataset/temp_output_comments.csv')
|
31 |
+
|
32 |
+
master_df = combine_author_and_comments_df(df_author, df_comments)
|
33 |
+
st.session_state['master_df'] = master_df
|
34 |
+
|
35 |
+
# master_df = pd.read_csv('assets/dataset/temp_output_combined2.csv')
|
36 |
+
# master_df = master_df.astype({'id': str, 'inReplyToId': str})
|
37 |
+
# st.session_state['master_df'] = master_df
|
38 |
+
|
39 |
+
if 'master_df' in st.session_state and st.session_state['master_df'] is not None:
|
40 |
+
st.dataframe(st.session_state['master_df'], height=450, use_container_width=True)
|
41 |
+
|
42 |
+
with cols[2]:
|
43 |
+
st.write("<br>", unsafe_allow_html=True)
|
44 |
+
st.download_button(label="Download CSV",
|
45 |
+
data=st.session_state['master_df'].to_csv(index=False).encode('utf-8'),
|
46 |
+
file_name="output.csv",
|
47 |
+
use_container_width=True)
|
48 |
+
|
49 |
+
if __name__=="__main__":
|
50 |
+
st.set_page_config(page_title="Sentiment Analysis Dashboard", page_icon="💬", layout="wide")
|
51 |
+
with st.spinner("Loading Dashboard..."):
|
52 |
+
analyse_page()
|
st_pages/dashboard.py
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
from utils.constants import TEXT_COLOR
|
4 |
+
from utils.generate_pdf import construct_pdf
|
5 |
+
from utils.utils import load_header, add_columns_for_graphs
|
6 |
+
from utils.graph_functions import *
|
7 |
+
|
8 |
+
|
9 |
+
def dashboard():
|
10 |
+
master_df = st.session_state['master_df']
|
11 |
+
|
12 |
+
if st.session_state['tweet_data'] is None:
|
13 |
+
st.session_state['tweet_data'], st.session_state['master_df'] = add_columns_for_graphs(master_df)
|
14 |
+
tweet_data = st.session_state['tweet_data']
|
15 |
+
|
16 |
+
load_header("Sentiment Analysis Dashboard")
|
17 |
+
metrics_bar(tweet_data, master_df)
|
18 |
+
|
19 |
+
cols = st.columns([2, 2, 1.6])
|
20 |
+
|
21 |
+
with cols[0]:
|
22 |
+
if st.session_state['sentiment_over_date'] is None and st.session_state['display_target_count'] is None:
|
23 |
+
st.session_state['sentiment_over_date'] = sentiment_over_date(master_df)
|
24 |
+
st.session_state['display_target_count'] = display_target_count(master_df)
|
25 |
+
|
26 |
+
for graph in [st.session_state['sentiment_over_date'], st.session_state['display_target_count']]:
|
27 |
+
with st.container(border=True):
|
28 |
+
st.plotly_chart(graph, use_container_width=True)
|
29 |
+
|
30 |
+
with cols[1]:
|
31 |
+
if st.session_state["most_common_trigrams"] is None and st.session_state["display_word_cloud"] is None:
|
32 |
+
st.session_state["most_common_trigrams"] = most_common_trigrams(master_df)
|
33 |
+
st.session_state["crear_grafico_dispersion"] = crear_grafico_dispersion(master_df)
|
34 |
+
|
35 |
+
# for graph in [st.session_state["most_common_trigrams"], st.session_state["display_word_cloud"]]:
|
36 |
+
for graph in [st.session_state["most_common_trigrams"], st.session_state["crear_grafico_dispersion"]]:
|
37 |
+
with st.container(border=True):
|
38 |
+
st.plotly_chart(graph, use_container_width=True)
|
39 |
+
|
40 |
+
with cols[2]:
|
41 |
+
with st.container(border=True):
|
42 |
+
# st.write("###### Post Analysis Report")
|
43 |
+
cols = st.columns(2)
|
44 |
+
with cols[0]:
|
45 |
+
st.metric(label="Views 👁️", value=tweet_data["viewCount"])
|
46 |
+
st.metric(label="Likes ❤️", value=tweet_data["likeCount"])
|
47 |
+
st.metric(label="Retweets 🔁", value=tweet_data["retweetCount"])
|
48 |
+
st.download_button(label="Download PDF", data=construct_pdf(), file_name="sentiment_analysis_report.pdf", use_container_width=True)
|
49 |
+
with cols[1]:
|
50 |
+
st.metric(label="Followers 👥", value=tweet_data["author__followers"])
|
51 |
+
st.metric(label="Replies 💬", value=tweet_data["replyCount"])
|
52 |
+
st.metric(label="Is Verified 🔐", value=tweet_data["is_author_verified"])
|
53 |
+
st.link_button("Go to Tweet", url=tweet_data["url"], use_container_width=True)
|
54 |
+
|
55 |
+
with st.container(border=True):
|
56 |
+
st.session_state["display_word_cloud"] = display_word_cloud(master_df)
|
57 |
+
st.plotly_chart(st.session_state["display_word_cloud"], use_container_width=True)
|
58 |
+
|
59 |
+
# st.write("###### Sentiment Breakdown")
|
60 |
+
# pos, neu, neg = st.columns(3)
|
61 |
+
# st.info(f"##### **Overall Sentiment**: :{TEXT_COLOR[tweet_data['overall_sentiment'].lower()]}[**{tweet_data['overall_sentiment']}**]")
|
62 |
+
# pos.metric(label=":green[Positive]", value=tweet_data["positive"])
|
63 |
+
# neu.metric(label=":gray[Neutral]", value=tweet_data["neutral"])
|
64 |
+
# neg.metric(label=":red[Negative]", value=tweet_data["negative"])
|
65 |
+
|
66 |
+
with st.container(border=True):
|
67 |
+
cols = st.columns(3)
|
68 |
+
|
69 |
+
charts = [bubble_fig, hist_fig, stacked_bar_fig]
|
70 |
+
|
71 |
+
for i in range(3):
|
72 |
+
with cols[i]:
|
73 |
+
st.plotly_chart(charts[i](master_df), use_container_width=True)
|
74 |
+
|
75 |
+
|
76 |
+
if __name__ == "__main__":
|
77 |
+
from utils.utils import init_session_state
|
78 |
+
|
79 |
+
st.set_page_config(page_title="Sentiment Analysis Dashboard", page_icon="💬", layout="wide")
|
80 |
+
init_session_state()
|
81 |
+
|
82 |
+
df = pd.read_csv('assets/dataset/master.csv')
|
83 |
+
st.session_state['master_df'] = pd.read_csv('assets/dataset/temp_output_combined.csv')
|
84 |
+
|
85 |
+
df_author = pd.read_csv('assets/dataset/temp_output_author.csv')
|
86 |
+
df_comments = pd.read_csv('assets/dataset/temp_output_comments.csv')
|
87 |
+
|
88 |
+
# with st.spinner("Analyzing Tweets..."):
|
89 |
+
# master_df, tweet_data = construct_master_df(df_author, df_comments)
|
90 |
+
|
91 |
+
# with st.spinner("Loading Dashboard..."):
|
92 |
+
# dashboard(master_df, tweet_data)
|
st_pages/home.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from streamlit_lottie import st_lottie
|
3 |
+
from utils.constants import PAGE_BANNER, PAGE_FAVICON
|
4 |
+
|
5 |
+
def home_page():
|
6 |
+
with st.columns([1,2,1])[1]:
|
7 |
+
st.image(PAGE_BANNER, use_column_width="auto")
|
8 |
+
|
9 |
+
st.write("""
|
10 |
+
<center>
|
11 |
+
<h1 class="top">Herramienta de Analisis de Sentimientos de Omdena para Actores Políticos en El Salvador</h1>
|
12 |
+
<p class="caption">
|
13 |
+
Este proyecto tiene como objetivo desarrollar una herramienta de analisis de sentimientos impulsada por IA que categorice las opiniones públicas sobre los actores políticos en El Salvador en sentimientos positivos, negativos y neutrales. Al automatizar el proceso de analisis de sentimientos, pretendemos ofrecer información mas rapida y precisa para los analistas políticos y los responsables de la formulación de políticas.
|
14 |
+
<hr>
|
15 |
+
</p>
|
16 |
+
</center>
|
17 |
+
""", unsafe_allow_html=True)
|
18 |
+
|
19 |
+
cols1 = st.columns([0.2, 1, 0.05, 1, 0.2])
|
20 |
+
padding_row = "<br>"
|
21 |
+
|
22 |
+
with cols1[1]:
|
23 |
+
st.write("""
|
24 |
+
<h3>Impacto en el Analisis Político y la Toma de Decisiones</h3>
|
25 |
+
<p>El ritmo lento y las posibles inexactitudes del analisis de sentimientos manual tienen implicaciones significativas para el analisis político y la toma de decisiones en El Salvador. La demora en obtener información impide a los analistas y responsables de políticas responder proactivamente al sentimiento público, lo que puede resultar en oportunidades perdidas para interactuar o intervenir. Ademas, las inexactitudes en el analisis manual pueden llevar a estrategias mal informadas, que no solo podrían fallar en alcanzar sus objetivos, sino también exacerbar el descontento o la desconfianza pública, afectando la estabilidad política y socavando el proceso democratico.</p>
|
26 |
+
""", unsafe_allow_html=True)
|
27 |
+
st.write(padding_row, unsafe_allow_html=True)
|
28 |
+
|
29 |
+
st_lottie("https://lottie.host/4bbcd636-eece-482f-8613-0e3ed93dafec/4ezAdnro3W.json", height=325)
|
30 |
+
st.write(padding_row, unsafe_allow_html=True)
|
31 |
+
|
32 |
+
st.write("""
|
33 |
+
<h3>Empoderando a Analistas y Formuladores de politícas</h3>
|
34 |
+
<p>El objetivo de esta iniciativa es proporcionar a los analistas políticos y responsables de políticas en El Salvador información precisa y en tiempo real sobre el sentimiento público, mediante una interfaz web para el analisis y visualización instantanea, mejorando así la capacidad de respuesta y la efectividad de las estrategias y políticas políticas.</p>
|
35 |
+
""", unsafe_allow_html=True)
|
36 |
+
|
37 |
+
with cols1[3]:
|
38 |
+
st_lottie("https://lottie.host/a786afd8-9903-4bed-8952-12b21b8016bd/PBO8x4JBEQ.json", height=325)
|
39 |
+
st.write(padding_row, unsafe_allow_html=True)
|
40 |
+
|
41 |
+
st.write(f"""
|
42 |
+
<br>
|
43 |
+
<h3>La necesidad de una solucion automatizada</h3>
|
44 |
+
<p>El desarrollo de una herramienta de analisis de sentimientos impulsada por IA es esencial para superar los desafíos del analisis manual, proporcionando un proceso mas preciso y rapido al aplicar técnicas avanzadas de Procesamiento del Lenguaje Natural (NLP) a diversas fuentes de datos.</p>
|
45 |
+
{'<br>'*5}
|
46 |
+
""", unsafe_allow_html=True)
|
47 |
+
st.write(padding_row, unsafe_allow_html=True)
|
48 |
+
|
49 |
+
st_lottie("https://lottie.host/9c945dc7-e5d7-4148-b7f6-dfd748e1eb38/q0oJidkFyf.json", height=325)
|
50 |
+
|
51 |
+
|
52 |
+
if __name__=="__main__":
|
53 |
+
st.set_page_config(page_title='Sentiment Analysis Tool', page_icon=PAGE_FAVICON, layout='wide')
|
54 |
+
st.markdown('<style>' + open('./assets/css/styles.css').read() + '</style>', unsafe_allow_html=True)
|
55 |
+
home_page()
|
utils/__init__.py
ADDED
File without changes
|
utils/constants.py
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
PAGE_BANNER = "assets/img/banner.png"
|
2 |
+
PAGE_FAVICON = "assets/img/favicon.png"
|
3 |
+
PAGE_BACKGROUND = "assets/img/background.jpg"
|
4 |
+
|
5 |
+
ANALYSIS_REPORT_TEMPLATE = """
|
6 |
+
### Analysis Report
|
7 |
+
|
8 |
+
Here's the analysis report for the given text:
|
9 |
+
|
10 |
+
---
|
11 |
+
|
12 |
+
##### Sentiment Category: {sentiment_category}
|
13 |
+
##### Sentiment Score: {sentiment_score}
|
14 |
+
"""
|
15 |
+
|
16 |
+
CONTRIBUTORS = [
|
17 |
+
["John Doe", "https://www.linkedin.com/"],
|
18 |
+
["John Doe", "https://www.linkedin.com/"],
|
19 |
+
["John Doe", "https://www.linkedin.com/"],
|
20 |
+
["John Doe", "https://www.linkedin.com/"],
|
21 |
+
["John Doe", "https://www.linkedin.com/"],
|
22 |
+
["John Doe", "https://www.linkedin.com/"],
|
23 |
+
["John Doe", "https://www.linkedin.com/"],
|
24 |
+
["John Doe", "https://www.linkedin.com/"],
|
25 |
+
["John Doe", "https://www.linkedin.com/"],
|
26 |
+
["John Doe", "https://www.linkedin.com/"],
|
27 |
+
["John Doe", "https://www.linkedin.com/"],
|
28 |
+
["John Doe", "https://www.linkedin.com/"],
|
29 |
+
["John Doe", "https://www.linkedin.com/"],
|
30 |
+
["John Doe", "https://www.linkedin.com/"],
|
31 |
+
]
|
32 |
+
|
33 |
+
TEXT_COLOR = {
|
34 |
+
"positive": "green",
|
35 |
+
"neutral": "gray",
|
36 |
+
"negative": "red"
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
from sklearn.feature_extraction import text as sklearn_text
|
41 |
+
|
42 |
+
spanish_stop_words = sklearn_text.ENGLISH_STOP_WORDS.union(set([
|
43 |
+
'a', 'acá', 'ahí', 'al', 'algo', 'algunas', 'algunos', 'allá', 'allí', 'ambos', 'ante', 'antes', 'aquel', 'aquellas',
|
44 |
+
'aquellos', 'aquí', 'arriba', 'así', 'atras', 'aun', 'aunque', 'bajo', 'bastante', 'bien', 'cada', 'casi', 'cerca',
|
45 |
+
'cierto', 'ciertos', 'como', 'con', 'conmigo', 'contigo', 'contra', 'cual', 'cuales', 'cuando', 'cuanta', 'cuantas',
|
46 |
+
'cuanto', 'cuantos', 'de', 'dejar', 'del', 'demás', 'dentro', 'desde', 'donde', 'dos', 'el', 'él', 'ella', 'ellas',
|
47 |
+
'ellos', 'en', 'encima', 'entonces', 'entre', 'era', 'erais', 'eran', 'eras', 'eres', 'es', 'esa', 'esas', 'ese',
|
48 |
+
'eso', 'esos', 'esta', 'estaba', 'estabais', 'estaban', 'estabas', 'estad', 'estada', 'estadas', 'estado', 'estados',
|
49 |
+
'estamos', 'estando', 'estar', 'estaremos', 'estará', 'estarán', 'estarás', 'estaré', 'estaréis', 'estaría', 'estaríais',
|
50 |
+
'estaríamos', 'estarían', 'estarías', 'estas', 'este', 'estemos', 'esto', 'estos', 'estoy', 'estuve', 'estuviera',
|
51 |
+
'estuvierais', 'estuvieran', 'estuvieras', 'estuvieron', 'estuviese', 'estuvieseis', 'estuviesen', 'estuvieses', 'estuvimos',
|
52 |
+
'estuviste', 'estuvisteis', 'estuviéramos', 'estuviésemos', 'estuvo', 'ex', 'excepto', 'fue', 'fuera', 'fuerais', 'fueran',
|
53 |
+
'fueras', 'fueron', 'fuese', 'fueseis', 'fuesen', 'fueses', 'fui', 'fuimos', 'fuiste', 'fuisteis', 'gran', 'grandes', 'ha',
|
54 |
+
'habéis', 'había', 'habíais', 'habíamos', 'habían', 'habías', 'habida', 'habidas', 'habido', 'habidos', 'habiendo', 'habrá',
|
55 |
+
'habrán', 'habrás', 'habré', 'habréis', 'habría', 'habríais', 'habríamos', 'habrían', 'habrías', 'hace', 'haceis', 'hacemos',
|
56 |
+
'hacen', 'hacer', 'hacerlo', 'hacerme', 'hacernos', 'haceros', 'hacerse', 'haces', 'hacia', 'hago', 'han', 'hasta', 'incluso',
|
57 |
+
'intenta', 'intentais', 'intentamos', 'intentan', 'intentar', 'intentas', 'intento', 'ir', 'jamás', 'junto', 'juntos', 'la',
|
58 |
+
'largo', 'las', 'le', 'les', 'lo', 'los', 'mas', 'me', 'menos', 'mi', 'mía', 'mías', 'mientras', 'mío', 'míos', 'mis', 'misma',
|
59 |
+
'mismas', 'mismo', 'mismos', 'modo', 'mucha', 'muchas', 'muchísima', 'muchísimas', 'muchísimo', 'muchísimos', 'mucho', 'muchos',
|
60 |
+
'muy', 'nada', 'ni', 'ninguna', 'ningunas', 'ninguno', 'ningunos', 'no', 'nos', 'nosotras', 'nosotros', 'nuestra', 'nuestras',
|
61 |
+
'nuestro', 'nuestros', 'nunca', 'os', 'otra', 'otras', 'otro', 'otros', 'para', 'parecer', 'pero', 'poca', 'pocas', 'poco',
|
62 |
+
'pocos', 'podéis', 'podemos', 'poder', 'podría', 'podríais', 'podríamos', 'podrían', 'podrías', 'poner', 'por', 'por qué', 'porque',
|
63 |
+
'primero', 'puede', 'pueden', 'puedo', 'pues', 'que', 'qué', 'querer', 'quien', 'quién', 'quienes', 'quiénes', 'quiere', 'se',
|
64 |
+
'según', 'ser', 'si', 'sí', 'siempre', 'siendo', 'sin', 'sino', 'sobre', 'sois', 'solamente', 'solo', 'somos', 'soy', 'su', 'sus',
|
65 |
+
'también', 'tampoco', 'tan', 'tanto', 'te', 'teneis', 'tenemos', 'tener', 'tengo', 'ti', 'tiempo', 'tiene', 'tienen', 'toda',
|
66 |
+
'todas', 'todavía', 'todo', 'todos', 'tu', 'tú', 'tus', 'un', 'una', 'unas', 'uno', 'unos', 'usa', 'usas', 'usáis', 'usamos',
|
67 |
+
'usan', 'usar', 'usas', 'uso', 'usted', 'ustedes', 'va', 'vais', 'valor', 'vamos', 'van', 'varias', 'varios', 'vaya', 'verdad',
|
68 |
+
'verdadera', 'vosotras', 'vosotros', 'voy', 'vuestra', 'vuestras', 'vuestro', 'vuestros', 'y', 'ya', 'yo'
|
69 |
+
]))
|
utils/generate_pdf.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from io import BytesIO
|
2 |
+
import streamlit as st
|
3 |
+
from reportlab.pdfgen import canvas
|
4 |
+
from reportlab.lib.pagesizes import letter
|
5 |
+
from reportlab.lib.utils import ImageReader
|
6 |
+
|
7 |
+
def generate_pdf(fig1=None, fig2=None, fig3=None, fig4=None, filename="output.pdf"):
|
8 |
+
try:
|
9 |
+
buffer = BytesIO()
|
10 |
+
|
11 |
+
c = canvas.Canvas(buffer, pagesize=letter)
|
12 |
+
c.setFont("Helvetica", 20)
|
13 |
+
c.drawString(100, 750, "Sentiment Analysis Report")
|
14 |
+
|
15 |
+
#### page 1
|
16 |
+
buffer1 = BytesIO()
|
17 |
+
fig1[1].write_image(buffer1, format='png')
|
18 |
+
buffer1.seek(0)
|
19 |
+
c.setFont("Helvetica", 12)
|
20 |
+
c.drawString(100, 680, fig1[0])
|
21 |
+
image1 = ImageReader(buffer1)
|
22 |
+
c.drawImage(image1, 100, 480, width=400, height=150)
|
23 |
+
|
24 |
+
buffer2 = BytesIO()
|
25 |
+
fig2[1].write_image(buffer2, format='png')
|
26 |
+
buffer2.seek(0)
|
27 |
+
c.drawString(100, 370, fig2[0])
|
28 |
+
image2 = ImageReader(buffer2)
|
29 |
+
c.drawImage(image2, 100, 165, width=400, height=150)
|
30 |
+
|
31 |
+
c.showPage()
|
32 |
+
|
33 |
+
#### page 2
|
34 |
+
buffer3 = BytesIO()
|
35 |
+
fig3[1].write_image(buffer3, format='png')
|
36 |
+
buffer3.seek(0)
|
37 |
+
c.setFont("Helvetica", 12)
|
38 |
+
c.drawString(100, 680, fig3[0])
|
39 |
+
image3 = ImageReader(buffer3)
|
40 |
+
c.drawImage(image3, 100, 480, width=400, height=150)
|
41 |
+
|
42 |
+
buffer4 = BytesIO()
|
43 |
+
fig4[1].write_image(buffer4, format='png')
|
44 |
+
buffer4.seek(0)
|
45 |
+
c.drawString(100, 350, fig4[0])
|
46 |
+
image4 = ImageReader(buffer4)
|
47 |
+
c.drawImage(image4, 100, 60, width=400, height=250)
|
48 |
+
|
49 |
+
c.showPage()
|
50 |
+
c.save()
|
51 |
+
|
52 |
+
buffer.seek(0)
|
53 |
+
|
54 |
+
with open(filename, "wb") as f:
|
55 |
+
f.write(buffer.getbuffer())
|
56 |
+
|
57 |
+
return "Successfully generated PDF"
|
58 |
+
|
59 |
+
except Exception as e:
|
60 |
+
return f"Error: {e}"
|
61 |
+
|
62 |
+
def construct_pdf():
|
63 |
+
fig1 = st.session_state["sentiment_over_date"]
|
64 |
+
fig2 = st.session_state["display_target_count"]
|
65 |
+
fig3 = st.session_state["most_common_trigrams"]
|
66 |
+
fig4 = st.session_state["display_word_cloud"]
|
67 |
+
|
68 |
+
return generate_pdf(fig1, fig2, fig3, fig4)
|
69 |
+
|
70 |
+
if __name__=="__main__":
|
71 |
+
import pandas as pd
|
72 |
+
from utils.graph_functions import sentiment_over_date, \
|
73 |
+
display_target_count, \
|
74 |
+
most_common_trigrams, \
|
75 |
+
display_word_cloud, \
|
76 |
+
display_word_cloud
|
77 |
+
|
78 |
+
master_df = pd.read_csv('assets/dataset/temp_output_combined.csv')
|
79 |
+
df = pd.read_csv('assets/dataset/master.csv')
|
80 |
+
|
81 |
+
fig1 = "Sentiment Over Date", sentiment_over_date(master_df)
|
82 |
+
fig2 = "Display Target Count", display_target_count(master_df)
|
83 |
+
fig3 = "Most Common Trigrams", most_common_trigrams(master_df, pdf=True)
|
84 |
+
fig4 = "Display Word Cloud", display_word_cloud(master_df)
|
85 |
+
|
86 |
+
print(generate_pdf(fig1, fig2, fig3, fig4))
|
utils/graph_functions.py
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import warnings
|
3 |
+
import pandas as pd
|
4 |
+
from PIL import Image
|
5 |
+
import streamlit as st
|
6 |
+
from wordcloud import WordCloud
|
7 |
+
import plotly.express as px
|
8 |
+
import plotly.graph_objects as go
|
9 |
+
from plotly.subplots import make_subplots
|
10 |
+
import nltk
|
11 |
+
from nltk.corpus import stopwords
|
12 |
+
from nltk.tokenize import word_tokenize
|
13 |
+
from utils.utils import get_top_ngram
|
14 |
+
|
15 |
+
warnings.filterwarnings('ignore')
|
16 |
+
|
17 |
+
try:
|
18 |
+
nltk.data.find('corpora/stopwords.zip')
|
19 |
+
except LookupError:
|
20 |
+
nltk.download('stopwords')
|
21 |
+
|
22 |
+
try:
|
23 |
+
nltk.data.find('tokenizers/punkt.zip')
|
24 |
+
except LookupError:
|
25 |
+
nltk.download('punkt')
|
26 |
+
|
27 |
+
@st.cache_data
|
28 |
+
def load_data(df):
|
29 |
+
# df = pd.read_csv(file_path, dtype={'text': 'string', 'sentiment_label': 'category'})
|
30 |
+
df['createdAt'] = pd.to_datetime(df['createdAt'])
|
31 |
+
df['date'] = df['createdAt'].dt.strftime('%Y-%m-%d')
|
32 |
+
return df
|
33 |
+
|
34 |
+
@st.cache_data
|
35 |
+
def process_texts(texts):
|
36 |
+
stop_words = set(stopwords.words('english'))
|
37 |
+
tokenized_texts = texts.apply(word_tokenize)
|
38 |
+
tokenized_texts = tokenized_texts.apply(lambda x: [word.lower() for word in x if word.lower() not in stop_words])
|
39 |
+
texts_cleaned = tokenized_texts.apply(lambda x: ' '.join(x))
|
40 |
+
return texts_cleaned
|
41 |
+
|
42 |
+
def custom_color_func(word, font_size, position, orientation, font_path, random_state):
|
43 |
+
color_palette = ['#ff2b2b', '#83c9ff', '#0068c9']
|
44 |
+
return random.choice(color_palette)
|
45 |
+
|
46 |
+
def display_word_cloud(dataframe):
|
47 |
+
all_text = ' '.join(dataframe['text'])
|
48 |
+
wordcloud = WordCloud(background_color="#fff", colormap="autumn", color_func=custom_color_func).generate(all_text)
|
49 |
+
wordcloud_image = wordcloud.to_array()
|
50 |
+
|
51 |
+
fig = go.Figure()
|
52 |
+
fig.add_layout_image(
|
53 |
+
dict(
|
54 |
+
source=Image.fromarray(wordcloud_image),
|
55 |
+
x=0, y=1,
|
56 |
+
sizex=1,
|
57 |
+
sizey=1.3,
|
58 |
+
opacity=1,
|
59 |
+
)
|
60 |
+
)
|
61 |
+
fig.update_layout(
|
62 |
+
autosize=False,
|
63 |
+
height=170,
|
64 |
+
width=500,
|
65 |
+
margin=dict(l=0, r=0, t=0, b=0),
|
66 |
+
xaxis=dict(visible=False),
|
67 |
+
yaxis=dict(visible=False)
|
68 |
+
)
|
69 |
+
|
70 |
+
return fig
|
71 |
+
|
72 |
+
def most_common_trigrams(df, pdf=False):
|
73 |
+
stop_words = set(stopwords.words('english'))
|
74 |
+
|
75 |
+
colors = ['#ff2b2b', '#83c9ff', '#0068c9']
|
76 |
+
fig = make_subplots(rows=1, cols=3)
|
77 |
+
|
78 |
+
sentiment_list = ["positive", "neutral", "negative"]
|
79 |
+
sentiment_list2 = ["POS", "NEU", "NEG"]
|
80 |
+
|
81 |
+
for i in range(3):
|
82 |
+
texts = df[df["sentiment_label"] == sentiment_list2[i]]['text']
|
83 |
+
texts_cleaned = process_texts(texts)
|
84 |
+
|
85 |
+
top_n_bigrams = get_top_ngram(texts_cleaned, 2)[:15]
|
86 |
+
x, y = map(list, zip(*top_n_bigrams))
|
87 |
+
|
88 |
+
fig.add_trace(go.Bar(
|
89 |
+
x=y,
|
90 |
+
orientation='h',
|
91 |
+
type="bar",
|
92 |
+
name=sentiment_list[i].title(),
|
93 |
+
marker=dict(color=colors[i]),
|
94 |
+
text=x,
|
95 |
+
textposition='inside',
|
96 |
+
hovertemplate="%{text}: %{y}"
|
97 |
+
), 1, i+1)
|
98 |
+
|
99 |
+
fig.update_layout(
|
100 |
+
autosize=False,
|
101 |
+
margin=dict(t=0, b=0, l=0, r=0),
|
102 |
+
height=250,
|
103 |
+
)
|
104 |
+
|
105 |
+
return fig
|
106 |
+
|
107 |
+
def display_target_count(df):
|
108 |
+
colors = ['#83c9ff', '#ff2b2b', '#0068c9']
|
109 |
+
fig = make_subplots(rows=1, cols=2, specs=[[{"type": "pie"}, {"type": "bar"}]])
|
110 |
+
fig.add_trace(go.Pie(labels=df.sentiment_label.value_counts().index,
|
111 |
+
values=df.sentiment_label.value_counts().values), 1, 1)
|
112 |
+
fig.update_traces(hoverinfo='label+percent',
|
113 |
+
textfont_size=18,
|
114 |
+
marker=dict(
|
115 |
+
colors=colors,
|
116 |
+
line=dict(
|
117 |
+
color='#fff',
|
118 |
+
width=1
|
119 |
+
)
|
120 |
+
)
|
121 |
+
)
|
122 |
+
fig.add_trace(go.Bar(
|
123 |
+
x=df.sentiment_label.value_counts().index,
|
124 |
+
y=df.sentiment_label.value_counts().values,
|
125 |
+
marker_color = colors
|
126 |
+
), 1,2)
|
127 |
+
fig.update_layout(
|
128 |
+
title_text="Sentiment Distribution",
|
129 |
+
title_y=1,
|
130 |
+
title_font=dict(color='#808495', size=15),
|
131 |
+
autosize=True,
|
132 |
+
height=250,
|
133 |
+
margin=dict(l=0, r=0, t=25, b=10),
|
134 |
+
xaxis=dict(visible=False),
|
135 |
+
yaxis=dict(visible=False)
|
136 |
+
)
|
137 |
+
|
138 |
+
return fig
|
139 |
+
|
140 |
+
def sentiment_over_date(df):
|
141 |
+
df = load_data(df)
|
142 |
+
grouped = df.groupby(['date', 'sentiment_label']).size().unstack(fill_value=0)
|
143 |
+
|
144 |
+
fig = go.Figure()
|
145 |
+
|
146 |
+
colors = ['#ff2b2b', '#83c9ff', '#0068c9'][::-1]
|
147 |
+
for idx, sentiment_label in enumerate(grouped.columns):
|
148 |
+
fig.add_trace(go.Scatter(
|
149 |
+
x=grouped.index, y=grouped[sentiment_label],
|
150 |
+
mode='lines',
|
151 |
+
name=sentiment_label.capitalize(),
|
152 |
+
stackgroup='one',
|
153 |
+
line=dict(width=2, color=colors[idx]),
|
154 |
+
fillcolor=colors[idx],
|
155 |
+
hoverinfo='y+name'
|
156 |
+
))
|
157 |
+
fig.update_xaxes(showgrid=False)
|
158 |
+
fig.update_yaxes(showgrid=False)
|
159 |
+
fig.update_layout(
|
160 |
+
title={
|
161 |
+
'text': 'Sentiment Over Time',
|
162 |
+
'x': 0.2,
|
163 |
+
'y': 1,
|
164 |
+
'xanchor': 'center',
|
165 |
+
'yanchor': 'top',
|
166 |
+
'font': {'size': 15, 'color': '#808495', 'family': 'Arial'}
|
167 |
+
},
|
168 |
+
xaxis_title='Date',
|
169 |
+
yaxis_title='Sentiment Count',
|
170 |
+
hovermode='x',
|
171 |
+
showlegend=True,
|
172 |
+
autosize=False,
|
173 |
+
height=250,
|
174 |
+
width=500,
|
175 |
+
margin=dict(l=0, r=0, t=40, b=0),
|
176 |
+
plot_bgcolor='white',
|
177 |
+
paper_bgcolor='white',
|
178 |
+
)
|
179 |
+
|
180 |
+
return fig
|
181 |
+
|
182 |
+
##############################################################################################################################
|
183 |
+
|
184 |
+
def crear_grafico_dispersion(df):
|
185 |
+
fig = px.scatter(
|
186 |
+
df,
|
187 |
+
x='likeCount',
|
188 |
+
y='sentiment_label',
|
189 |
+
color='sentiment_label',
|
190 |
+
labels={'likeCount': 'Número de Likes', 'sentiment_label': 'Etiqueta de Sentimiento'},
|
191 |
+
title='Relación entre Número de Likes y Etiquetas de Sentimiento'
|
192 |
+
)
|
193 |
+
|
194 |
+
fig.update_layout(
|
195 |
+
title_y=1,
|
196 |
+
title_font=dict(color='#808495', size=15),
|
197 |
+
autosize=True,
|
198 |
+
height=250,
|
199 |
+
margin=dict(l=0, r=0, t=20, b=0),
|
200 |
+
# xaxis=dict(visible=False),
|
201 |
+
# yaxis=dict(visible=False)
|
202 |
+
)
|
203 |
+
|
204 |
+
return fig
|
205 |
+
|
206 |
+
def bubble_fig(df):
|
207 |
+
bubble_chart_data = df.groupby('account_creation_time').size().reset_index(name='user_count')
|
208 |
+
bubble_fig = px.scatter(
|
209 |
+
bubble_chart_data, x='account_creation_time', y='user_count', size='user_count',
|
210 |
+
title='Tiempo de Creación de Cuenta<br>vs. Número de Usuarios',
|
211 |
+
labels={'account_creation_time': 'Tiempo de Creación de Cuenta (meses)', 'user_count': 'Número de Usuarios'}
|
212 |
+
)
|
213 |
+
return bubble_fig
|
214 |
+
|
215 |
+
def hist_fig(df):
|
216 |
+
hist_fig = px.histogram(
|
217 |
+
df, x='account_creation_time',
|
218 |
+
title='Distribución del Tiempo de Creación de Cuenta',
|
219 |
+
labels={'account_creation_time': 'Tiempo de Creación de Cuenta (meses)', 'user_count': 'Número de Usuarios'},
|
220 |
+
nbins=25
|
221 |
+
)
|
222 |
+
|
223 |
+
return hist_fig
|
224 |
+
|
225 |
+
def stacked_bar_fig(df):
|
226 |
+
stacked_bar_fig = px.histogram(
|
227 |
+
df, x='account_creation_time', color='sentiment_label',
|
228 |
+
title='Distribución del Tiempo de <br>Creación de Cuenta por Sentimiento de Comentario',
|
229 |
+
labels={'account_creation_time': 'Tiempo de Creación de Cuenta (meses)', 'count': 'Número de Usuarios', 'sentiment_beto': 'Sentimiento'},
|
230 |
+
barmode='stack',
|
231 |
+
nbins=25
|
232 |
+
)
|
233 |
+
return stacked_bar_fig
|
234 |
+
|
235 |
+
def metrics_bar(tweet_data, df):
|
236 |
+
st.write("""
|
237 |
+
<style>
|
238 |
+
div[data-testid="stMetric"]
|
239 |
+
{
|
240 |
+
background-color: #00000005;
|
241 |
+
color: black;
|
242 |
+
padding: 10px 0 0 10px;
|
243 |
+
border-radius: 5px;
|
244 |
+
}
|
245 |
+
</style>
|
246 |
+
|
247 |
+
""", unsafe_allow_html=True)
|
248 |
+
|
249 |
+
avg_time = df['account_creation_time'].mean()
|
250 |
+
min_time = df['account_creation_time'].min()
|
251 |
+
max_time = df['account_creation_time'].max()
|
252 |
+
|
253 |
+
left, right = st.columns([2,1])
|
254 |
+
|
255 |
+
with left:
|
256 |
+
with st.container(border=True):
|
257 |
+
# st.write("###### Analysis of Time Metrics")
|
258 |
+
col1, col2, col3 = st.columns(3)
|
259 |
+
col1.metric("Tiempo Promedio", f"{round(avg_time/12)} años")
|
260 |
+
col2.metric("### Tiempo Mínimo", f"{min_time} meses")
|
261 |
+
col3.metric("Tiempo Máximo", f"{round(max_time/12)} años")
|
262 |
+
|
263 |
+
with right:
|
264 |
+
with st.container(border=True):
|
265 |
+
# st.write("###### Sentiment Breakdown")
|
266 |
+
pos, neu, neg = st.columns(3)
|
267 |
+
# st.info(f"##### **Overall Sentiment**: :{TEXT_COLOR[tweet_data['overall_sentiment'].lower()]}[**{tweet_data['overall_sentiment']}**]")
|
268 |
+
pos.metric(label=":green[Positive]", value=tweet_data["positive"])
|
269 |
+
neu.metric(label=":gray[Neutral]", value=tweet_data["neutral"])
|
270 |
+
neg.metric(label=":red[Negative]", value=tweet_data["negative"])
|
utils/scraper.py
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import streamlit as st
|
3 |
+
from apify_client import ApifyClient
|
4 |
+
|
5 |
+
# Constants
|
6 |
+
TWEETS_COLUMNS_LIST = [
|
7 |
+
"url",
|
8 |
+
"createdAt",
|
9 |
+
"id",
|
10 |
+
"isReply",
|
11 |
+
"inReplyToId",
|
12 |
+
"isRetweet",
|
13 |
+
"isQuote",
|
14 |
+
"viewCount",
|
15 |
+
"retweetCount",
|
16 |
+
"likeCount",
|
17 |
+
"replyCount",
|
18 |
+
"lang",
|
19 |
+
"author__createdAt",
|
20 |
+
"author__location",
|
21 |
+
"author__name",
|
22 |
+
"author__id",
|
23 |
+
"author__description",
|
24 |
+
"author__followers",
|
25 |
+
"author__verified",
|
26 |
+
"text"
|
27 |
+
]
|
28 |
+
|
29 |
+
REMOVE_COLUMNS_COMMENTS = [
|
30 |
+
"author__name",
|
31 |
+
"author__id",
|
32 |
+
"author__description",
|
33 |
+
]
|
34 |
+
|
35 |
+
INT_COLUMNS = [
|
36 |
+
"viewCount",
|
37 |
+
"retweetCount",
|
38 |
+
"likeCount",
|
39 |
+
"replyCount",
|
40 |
+
"author__followers"
|
41 |
+
]
|
42 |
+
|
43 |
+
APIFY_ACTOR_ID = '61RPP7dywgiy0JPD0'
|
44 |
+
APIFY_TOKEN = st.secrets['APIFY_TOKEN']
|
45 |
+
|
46 |
+
# Start client
|
47 |
+
client = ApifyClient(APIFY_TOKEN)
|
48 |
+
|
49 |
+
|
50 |
+
def flatten_response(response):
|
51 |
+
""" Returns a flat dictionary with unnested values """
|
52 |
+
|
53 |
+
return {
|
54 |
+
"url": response.get("url"),
|
55 |
+
"createdAt": pd.to_datetime(response.get("createdAt")),
|
56 |
+
"id": response.get("id"),
|
57 |
+
"isReply": response.get("isReply"),
|
58 |
+
"inReplyToId": response.get("inReplyToId", None), # Uses None if inReply is false
|
59 |
+
"isRetweet": response.get("isRetweet"),
|
60 |
+
"isQuote": response.get("isQuote"),
|
61 |
+
"viewCount": response.get("viewCount"),
|
62 |
+
"retweetCount": response.get("retweetCount"),
|
63 |
+
"likeCount": response.get("likeCount"),
|
64 |
+
"replyCount": response.get("replyCount"),
|
65 |
+
"lang": response.get("lang"),
|
66 |
+
"author__createdAt": pd.to_datetime(response["author"].get("createdAt")),
|
67 |
+
"author__location": response["author"].get("location"),
|
68 |
+
"author__name": response["author"].get("name"),
|
69 |
+
"author__id": response["author"].get("id"),
|
70 |
+
"author__description": response["author"].get("description"),
|
71 |
+
"author__followers": response["author"].get("followers"),
|
72 |
+
"author__verified": response["author"].get("isVerified"),
|
73 |
+
"text": response.get("text")
|
74 |
+
}
|
75 |
+
|
76 |
+
|
77 |
+
def fetch_main_tweet_dataframe(url):
|
78 |
+
""" Given a tweet URL, returns a dataframe for it """
|
79 |
+
|
80 |
+
# Input validation
|
81 |
+
if 'x.com' not in url and 'twitter.com' not in url:
|
82 |
+
return {'error': 'Input is not a tweet URL'}
|
83 |
+
|
84 |
+
run_input = {
|
85 |
+
"startUrls": [url],
|
86 |
+
}
|
87 |
+
|
88 |
+
run = client.actor(APIFY_ACTOR_ID).call(run_input=run_input)
|
89 |
+
|
90 |
+
response = [dictionary for dictionary in client.dataset(run["defaultDatasetId"]).iterate_items()][0]
|
91 |
+
|
92 |
+
flattened_data = flatten_response(response)
|
93 |
+
|
94 |
+
# Convert the flattened dictionary to a DataFrame and return
|
95 |
+
return pd.DataFrame([flattened_data], columns=TWEETS_COLUMNS_LIST)
|
96 |
+
|
97 |
+
|
98 |
+
def fetch_comments_dataframe(url):
|
99 |
+
""" Given a tweet URL, returns a dataframe for the comments related to that tweet """
|
100 |
+
|
101 |
+
# Input validation
|
102 |
+
if 'x.com' not in url and 'twitter.com' not in url:
|
103 |
+
return {'error': 'Input is not a tweet URL'}
|
104 |
+
|
105 |
+
one_tweet_id = str(url.split('/')[-1])
|
106 |
+
|
107 |
+
run_input_comment = {
|
108 |
+
"conversationIds": [one_tweet_id],
|
109 |
+
"tweetLanguage": "es",
|
110 |
+
"maxItems": 50
|
111 |
+
}
|
112 |
+
|
113 |
+
run_comment = client.actor(APIFY_ACTOR_ID).call(run_input=run_input_comment)
|
114 |
+
|
115 |
+
response_comment = [dictionary for dictionary in client.dataset(run_comment["defaultDatasetId"]).iterate_items()]
|
116 |
+
|
117 |
+
flattened_responses = [flatten_response(response) for response in response_comment]
|
118 |
+
|
119 |
+
include_columns = [column for column in TWEETS_COLUMNS_LIST if column not in REMOVE_COLUMNS_COMMENTS]
|
120 |
+
|
121 |
+
# Convert the flattened dictionary to a DataFrame and return
|
122 |
+
return pd.DataFrame(flattened_responses, columns=include_columns)
|
123 |
+
|
utils/utils.py
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import streamlit as st
|
5 |
+
from pysentimiento import create_analyzer
|
6 |
+
from sklearn.feature_extraction.text import CountVectorizer
|
7 |
+
|
8 |
+
def load_css():
|
9 |
+
st.markdown('<style>' + open('./assets/css/styles.css').read() + '</style>', unsafe_allow_html=True)
|
10 |
+
|
11 |
+
def load_header(title):
|
12 |
+
cols = st.columns([4,1,0.7,1.5])
|
13 |
+
with cols[0]:
|
14 |
+
st.write("""<h2 class='custom' style='color:#00000099'>{}</h2>""".format(title), unsafe_allow_html=True)
|
15 |
+
with cols[2]:
|
16 |
+
st.image("assets/img/PCE.png", use_column_width=True)
|
17 |
+
with cols[3]:
|
18 |
+
st.image("assets/img/omdena_logo.png", use_column_width=True)
|
19 |
+
# st.write("---")
|
20 |
+
|
21 |
+
def tokenize(text):
|
22 |
+
""" basic tokenize method with word character, non word character and digits """
|
23 |
+
text = re.sub(r" +", " ", str(text))
|
24 |
+
text = re.split(r"(\d+|[a-zA-ZğüşıöçĞÜŞİÖÇ]+|\W)", text)
|
25 |
+
text = list(filter(lambda x: x != '' and x != ' ', text))
|
26 |
+
sent_tokenized = ' '.join(text)
|
27 |
+
return sent_tokenized
|
28 |
+
|
29 |
+
def get_top_ngram(corpus, n=None):
|
30 |
+
vec = CountVectorizer(ngram_range=(n, n),
|
31 |
+
max_df=0.9,
|
32 |
+
).fit(corpus)
|
33 |
+
bag_of_words = vec.transform(corpus)
|
34 |
+
sum_words = bag_of_words.sum(axis=0)
|
35 |
+
words_freq = [(word, sum_words[0, idx])
|
36 |
+
for word, idx in vec.vocabulary_.items()]
|
37 |
+
words_freq = sorted(words_freq, key=lambda x: x[1], reverse=True)
|
38 |
+
return words_freq[:15]
|
39 |
+
|
40 |
+
def is_valid_twitter_url(url):
|
41 |
+
pattern = r"^https://(www\.)?(twitter|x)\.com/.+/status/\d+$"
|
42 |
+
return re.match(pattern, url) is not None
|
43 |
+
|
44 |
+
def combine_author_and_comments_df(df_author, df_comments):
|
45 |
+
if 'author__name' in df_comments:
|
46 |
+
df_comments, df_author = df_author, df_comments
|
47 |
+
|
48 |
+
master_df = pd.concat([df_comments, df_author.drop(['author__name', 'author__id', 'author__description'], axis=1)], ignore_index=True)
|
49 |
+
master_df = master_df.astype({'id': str, 'inReplyToId': str})
|
50 |
+
master_df.sort_values(by='createdAt', inplace=True)
|
51 |
+
|
52 |
+
return master_df
|
53 |
+
|
54 |
+
def tokenize(text):
|
55 |
+
""" basic tokenize method with word character, non word character and digits """
|
56 |
+
text = re.sub(r" +", " ", str(text))
|
57 |
+
text = re.split(r"(\d+|[a-zA-ZğüşıöçĞÜŞİÖÇ]+|\W)", text)
|
58 |
+
text = list(filter(lambda x: x != '' and x != ' ', text))
|
59 |
+
sent_tokenized = ' '.join(text)
|
60 |
+
return sent_tokenized
|
61 |
+
|
62 |
+
def add_columns_for_graphs(master_df):
|
63 |
+
data = {
|
64 |
+
"viewCount": master_df.viewCount.iloc[0],
|
65 |
+
"likeCount": master_df.likeCount.iloc[0],
|
66 |
+
"retweetCount": master_df.retweetCount.iloc[0],
|
67 |
+
"replyCount": master_df.replyCount.iloc[0],
|
68 |
+
"author__followers": master_df.author__followers.iloc[0],
|
69 |
+
"is_author_verified": master_df.author__verified.iloc[0],
|
70 |
+
"text": master_df.text.iloc[0],
|
71 |
+
"url": master_df.url.iloc[0],
|
72 |
+
}
|
73 |
+
|
74 |
+
analyzer = create_analyzer(task="sentiment", lang="es")
|
75 |
+
master_df['sentiment'] = master_df['text'].apply(lambda x: analyzer.predict(x))
|
76 |
+
master_df['sentiment_label'] = master_df['sentiment'].apply(lambda x: x.output)
|
77 |
+
master_df['sentiment_numeric'] = master_df['sentiment'].apply(lambda x: max(x.probas))
|
78 |
+
|
79 |
+
# master_df["tokenized_review"] = master_df.text.apply(lambda x: tokenize(x))
|
80 |
+
master_df['createdAt'] = pd.to_datetime(master_df['createdAt'])
|
81 |
+
master_df['date'] = master_df['createdAt'].dt.strftime('%Y-%m-%d')
|
82 |
+
|
83 |
+
grouped = master_df.groupby(['date', 'sentiment_label']).size().unstack(fill_value=0)
|
84 |
+
|
85 |
+
pos_sum = grouped.get('POS', 0).sum()
|
86 |
+
neu_sum = grouped.get('NEU', 0).sum()
|
87 |
+
neg_sum = grouped.get('NEG', 0).sum()
|
88 |
+
|
89 |
+
sums = {"Positive": pos_sum, "Neutral": neu_sum, "Negative": neg_sum}
|
90 |
+
overall_sentiment = max(sums, key=sums.get)
|
91 |
+
|
92 |
+
data.update({
|
93 |
+
"overall_sentiment": overall_sentiment,
|
94 |
+
"positive": pos_sum,
|
95 |
+
"neutral": neu_sum,
|
96 |
+
"negative": neg_sum
|
97 |
+
})
|
98 |
+
|
99 |
+
# master_df['createdAt'] = pd.to_datetime(master_df['createdAt'])
|
100 |
+
master_df['author__createdAt'] = pd.to_datetime(master_df['author__createdAt'])
|
101 |
+
master_df['account_creation_time'] = ((master_df['createdAt'] - master_df['author__createdAt']) / np.timedelta64(1, 'm')).astype(int)
|
102 |
+
|
103 |
+
return data, master_df
|
104 |
+
|
105 |
+
def init_session_state():
|
106 |
+
if 'master_df' not in st.session_state:
|
107 |
+
st.session_state['master_df'] = None
|
108 |
+
|
109 |
+
if 'sentiment_over_date' not in st.session_state:
|
110 |
+
st.session_state['sentiment_over_date'] = None
|
111 |
+
|
112 |
+
if 'display_target_count' not in st.session_state:
|
113 |
+
st.session_state['display_target_count'] = None
|
114 |
+
|
115 |
+
if 'most_common_trigrams' not in st.session_state:
|
116 |
+
st.session_state['most_common_trigrams'] = None
|
117 |
+
|
118 |
+
if 'display_word_cloud' not in st.session_state:
|
119 |
+
st.session_state['display_word_cloud'] = None
|
120 |
+
|
121 |
+
if 'graphs_created' not in st.session_state:
|
122 |
+
st.session_state['graphs_created'] = False
|
123 |
+
|
124 |
+
if 'tweet_data' not in st.session_state:
|
125 |
+
st.session_state['tweet_data'] = None
|
126 |
+
|
127 |
+
# graphs
|
128 |
+
if "sentiment_over_date" not in st.session_state:
|
129 |
+
st.session_state["sentiment_over_date"] = None
|
130 |
+
|
131 |
+
if "display_target_count" not in st.session_state:
|
132 |
+
st.session_state["display_target_count"] = None
|
133 |
+
|
134 |
+
if "most_common_trigrams" not in st.session_state:
|
135 |
+
st.session_state["most_common_trigrams"] = None
|
136 |
+
|
137 |
+
if "display_word_cloud" not in st.session_state:
|
138 |
+
st.session_state["display_word_cloud"] = None
|