Spaces:
Runtime error
Runtime error
Merge pull request #90 from Demea9000/61-present-the-data-from-the-database
Browse files- app.py +59 -57
- data/twitterdata.csv +0 -2
- textclassifier/TextClassifier.py +5 -5
app.py
CHANGED
@@ -7,89 +7,91 @@ import time
|
|
7 |
USER_LIST = ['jimmieakesson', 'BuschEbba', 'annieloof', 'JohanPehrson', 'bolund', 'martastenevi', 'SwedishPM',
|
8 |
'dadgostarnooshi']
|
9 |
|
|
|
|
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
This function returns a summary statistics of the dataframe. Returns a string with the summary statistics.
|
14 |
-
:param dataframe: dataframe
|
15 |
-
:return: str
|
16 |
-
"""
|
17 |
-
summary_statistics = dataframe.describe()
|
18 |
-
return summary_statistics.to_string()
|
19 |
-
|
20 |
-
|
21 |
-
def summary_categorical(dataframe):
|
22 |
-
"""
|
23 |
-
This function returns a string of a summary of categorical variables of a dataframe
|
24 |
-
:param dataframe:
|
25 |
-
:return:
|
26 |
-
"""
|
27 |
-
# First find all numeric columns in the dataframe
|
28 |
-
numeric_columns = dataframe._get_numeric_data().columns
|
29 |
-
# Then find all categorical columns in the dataframe
|
30 |
-
categorical_columns = dataframe.select_dtypes(include=['object']).columns
|
31 |
-
print("Numeric columns: " + str(numeric_columns) + "\n" + "Categorical columns: " + str(categorical_columns))
|
32 |
-
# Then find the summary statistics of each categorical column
|
33 |
-
summary = ""
|
34 |
-
for column in categorical_columns:
|
35 |
-
# skip 'tweet', 'urls' and 'date' columns
|
36 |
-
if column == 'tweet' or column == 'date' or column == 'urls':
|
37 |
-
continue
|
38 |
-
else:
|
39 |
-
summary += column + ": " + str(dataframe[column].value_counts()) + "\n"
|
40 |
-
# Return a nice decoration of summary
|
41 |
-
return "Summary of categorical variables:\n" + summary
|
42 |
|
43 |
|
44 |
-
def show_all_stats(
|
45 |
dataframe = pd.read_csv("{}/data/twitterdata.csv".format(tc.ROOT_PATH))
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
|
49 |
def main(From,
|
50 |
To,
|
51 |
Username,
|
|
|
52 |
Nbr_Of_Tweets_To_Classify,
|
|
|
|
|
53 |
):
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
58 |
|
59 |
text_classifier = tc.TextClassifier(
|
60 |
from_date=From,
|
61 |
to_date=To,
|
62 |
-
|
63 |
num_tweets=int(Nbr_Of_Tweets_To_Classify))
|
64 |
|
65 |
text_classifier.run_main_pipeline()
|
66 |
dataframe = text_classifier.get_dataframe()
|
|
|
|
|
|
|
67 |
|
68 |
-
return dataframe, show_all_stats(
|
69 |
|
70 |
|
71 |
if __name__ == "__main__":
|
72 |
from datetime import date
|
73 |
|
74 |
demo = gr.Interface(
|
75 |
-
article="From = The date from which you want to start the analysis
|
76 |
-
"
|
77 |
-
"= The
|
78 |
-
"
|
79 |
-
|
80 |
-
|
81 |
-
"=2ahUKEwiF36vKwZb5AhX6YPEDHbLJCRYQ_AUoAXoECAIQAw&biw=2560&bih=1274&dpr=1#imgrc=TA2JaVySjUQVsM",
|
82 |
-
analytics_enabled=True,
|
83 |
theme="default",
|
84 |
title="Twitter data analysis",
|
85 |
fn=main,
|
86 |
-
inputs=[
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
USER_LIST = ['jimmieakesson', 'BuschEbba', 'annieloof', 'JohanPehrson', 'bolund', 'martastenevi', 'SwedishPM',
|
8 |
'dadgostarnooshi']
|
9 |
|
10 |
+
UserNameDict = dict(zip(['Jimmie Åkesson', 'Ebba Busch', 'Annie Lööf', 'Johan Pehrson', 'Per Bolund',
|
11 |
+
'Märta Stenevi', 'Magdalena Andersson', 'Nooshi Dadgostar'], USER_LIST))
|
12 |
|
13 |
+
Columns = ['username', 'nlikes', 'nreplies', 'nretweets', 'main_topic', 'sub_topic', 'sentiment', 'target', 'tweet',
|
14 |
+
'date', 'urls', 'id', 'class_tuple', 'user_id']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
|
17 |
+
def show_all_stats(ListChoices, SeeFullStats):
|
18 |
dataframe = pd.read_csv("{}/data/twitterdata.csv".format(tc.ROOT_PATH))
|
19 |
+
if SeeFullStats:
|
20 |
+
return dataframe[ListChoices]
|
21 |
+
else:
|
22 |
+
return pd.DataFrame()
|
23 |
+
|
24 |
+
|
25 |
+
def fixChoicesCorrectOrder(Choices):
|
26 |
+
ListChoices = [x for x in Columns if x in Choices]
|
27 |
+
return ListChoices
|
28 |
+
|
29 |
+
|
30 |
+
def MatchNameToUser(Name):
|
31 |
+
return UserNameDict[Name]
|
32 |
|
33 |
|
34 |
def main(From,
|
35 |
To,
|
36 |
Username,
|
37 |
+
UserNameChoices,
|
38 |
Nbr_Of_Tweets_To_Classify,
|
39 |
+
ListChoices,
|
40 |
+
SeeFullStats
|
41 |
):
|
42 |
+
def WhoToScrape():
|
43 |
+
if Username == "":
|
44 |
+
return MatchNameToUser(UserNameChoices[0])
|
45 |
+
else:
|
46 |
+
return Username
|
47 |
|
48 |
text_classifier = tc.TextClassifier(
|
49 |
from_date=From,
|
50 |
to_date=To,
|
51 |
+
user_list=WhoToScrape(),
|
52 |
num_tweets=int(Nbr_Of_Tweets_To_Classify))
|
53 |
|
54 |
text_classifier.run_main_pipeline()
|
55 |
dataframe = text_classifier.get_dataframe()
|
56 |
+
dataframe = dataframe[
|
57 |
+
['username', 'nlikes', 'nreplies', 'nretweets', 'main_topic', 'sub_topic', 'sentiment', 'target', 'tweet',
|
58 |
+
'date', 'urls', 'id', 'class_tuple', 'user_id']]
|
59 |
|
60 |
+
return dataframe[fixChoicesCorrectOrder(ListChoices)], show_all_stats(ListChoices, SeeFullStats)
|
61 |
|
62 |
|
63 |
if __name__ == "__main__":
|
64 |
from datetime import date
|
65 |
|
66 |
demo = gr.Interface(
|
67 |
+
article="</a><br>From = The date from which you want to start the analysis.</a><br> To = The date to which "
|
68 |
+
"you want to end "
|
69 |
+
"the analysis.</a><br> Username = The username of the user you want to analyze.</a><br> How many "
|
70 |
+
"tweets to classify = "
|
71 |
+
"The number of tweets you want to analyze.</a><br>",
|
72 |
+
analytics_enabled=False,
|
|
|
|
|
73 |
theme="default",
|
74 |
title="Twitter data analysis",
|
75 |
fn=main,
|
76 |
+
inputs=[gr.components.Textbox(label="From", value='2022-01-01'),
|
77 |
+
gr.components.Textbox(label="To", value='2022-01-25'),
|
78 |
+
gr.components.Textbox(label="Username", value="BuschEbba"),
|
79 |
+
gr.components.Checkboxgroup(
|
80 |
+
choices=['Jimmie Åkesson', 'Ebba Busch', 'Annie Lööf', 'Johan Pehrson', 'Per Bolund',
|
81 |
+
'Märta Stenevi',
|
82 |
+
'Magdalena Andersson', 'Nooshi Dadgostar'], label=""),
|
83 |
+
gr.components.Textbox(label="How many Tweets to Classify", value="20"),
|
84 |
+
gr.components.Checkboxgroup(label="Options",
|
85 |
+
choices=['username', 'nlikes', 'nreplies', 'nretweets', 'main_topic',
|
86 |
+
'sub_topic', 'sentiment', 'target', 'tweet', 'date', 'urls', 'id',
|
87 |
+
'class_tuple', 'user_id'],
|
88 |
+
value=['username', 'nlikes', 'nreplies', 'nretweets', 'main_topic',
|
89 |
+
'sub_topic', 'sentiment', 'target', 'tweet', 'date']
|
90 |
+
),
|
91 |
+
gr.components.Checkbox(label="Show full statistics")
|
92 |
+
],
|
93 |
+
outputs=[
|
94 |
+
gr.components.DataFrame(label="Summary statistics of the intervall you selected", max_rows=None),
|
95 |
+
gr.components.DataFrame(label="Summary statistics of the total database", max_rows=None, )])
|
96 |
+
|
97 |
+
demo.launch(share=False)
|
data/twitterdata.csv
CHANGED
@@ -64,7 +64,6 @@ id,tweet,date,user_id,username,urls,nlikes,nreplies,nretweets,class_tuple,main_t
|
|
64 |
1518584979193745408,Vad vi också har gemensamt är åsikten att Polisen behöver fler och bättre verktyg för att återuppbygga tryggheten. Inte minst förra helgens islamistkravaller visar behovet av det.,2022-04-25 15:37:27,95972673,jimmieakesson,[],748,29,36,"(policing, law enforcement, positive, police)",,,,
|
65 |
1518584871718948867,"Idag gjorde jag och Ebba Busch ett verksamhetsbesök inom äldrevården i Karlskrona. Vi är överens om att äldrevården behöver bli bättre, något som båda våra partier prioriterar. https://t.co/iBwx2QiCxK",2022-04-25 15:37:02,95972673,jimmieakesson,[],2109,103,116,"(healthcare, elderly care, positive, healthcare)",,,,
|
66 |
1517463287897731074,@Ygeman Anders Ygeman är själv expert på att undgå att ta ansvar för dom misslyckanden som hans egen regering har orsakat. Så det är inte oväntat att han är kritisk till vårt förslag om ökat familjeansvar.,2022-04-22 13:20:15,95972673,jimmieakesson,[],256,9,13,"(familjeansvar, ökat familjeansvar, negativ, anders ygeman)",,,,
|
67 |
-
|
68 |
1503355595994374144,Bidraget på tusen kronor per bilägare slår extremt snett. Det betyder att den som åker och handlar varannan vecka och den familj som har arbetsresor och fotbollsträningar får samma summa. Det är ett politiskt bländverk.,2022-03-14 14:01:19,1407151866,BuschEbba,[],1175,67,80,"(economy, taxes, negative, middle-class families)",economy,taxes,negative,middle-class families
|
69 |
1503355593637212164,"Regeringens besked om drivmedelschocken är en stor besvikelse. 1,30 kronor i sänkt pris vid pump och ingen sänkning av den dyra inblandningen av biodrivmedel. Samtidigt säger folk upp sig från jobbet och åkeriföretag ställer in uppdrag för att de inte har råd att tanka!",2022-03-14 14:01:19,1407151866,BuschEbba,[],2219,95,173,"(fuel prices, governmental response, negative, swedish citizens)",fuel prices,governmental response,negative,swedish citizens
|
70 |
1503301741118377987,"Det är för dyrt att vara svensk. Vi vill sänka dieselpriset med över 9 kr, bensinpriset med 5 kr och vi skattebefriar jord- och skogsbruket. Ett vidsträckt och glesbefolkat land som Sverige kan inte och ska inte ha en av världens högsta prisnivåer. https://t.co/mnpSD3Jiqm",2022-03-14 10:27:19,1407151866,BuschEbba,['https://fb.watch/bKMCTmXWgH/'],1705,112,163,"(economy, taxation, negative, swedish government)",economy,taxation,negative,swedish government
|
@@ -156,7 +155,6 @@ id,tweet,date,user_id,username,urls,nlikes,nreplies,nretweets,class_tuple,main_t
|
|
156 |
1239960095993331712,"Vissa drabbas hårdare än andra, men det är bara genom gemensamma ansträngningar vi kan utmana och övervinna krisen.",2020-03-17 18:01:38,95972673,jimmieakesson,[],109,1,7,"(covid-19, government response, positive, swedish citizens)",covid-19,government response,positive,swedish citizens
|
157 |
1239960079929090048,"Det kan inte nog betonas att vi befinner oss i ett riktigt allvarligt läge. Belastningen på samhället är redan hård, och allt tyder på att vi har en lång och svår period framför oss.",2020-03-17 18:01:35,95972673,jimmieakesson,[],153,3,10,"(covid-19, sweden's response, negative, the government)",covid-19,sweden's response,negative,the government
|
158 |
1239960040028557312,Vi välkomnar naturligtvis dessa besked. Att minimera sociala kontakter är avgörande för att vi ska ha möjlighet att bromsa smittspridningen. Låt oss nu hoppas att besked om grundskolan kommer snarast.,2020-03-17 18:01:25,95972673,jimmieakesson,[],127,2,11,"(covid-19, swedish government response, positive, swedish people)",covid-19,swedish government response,positive,swedish people
|
159 |
-
|
160 |
1015143098547089408,#Almedalen https://t.co/8YESYKYHjL,2018-07-06 09:59:09,95972673,jimmieakesson,[],776,67,105,"(political parties, almedalen, positive, almedalen)",political parties,almedalen,positive,almedalen
|
161 |
957572132921331714,En av Sveriges främsta entreprenörer har gått ur tiden. Tack Ingvar Kamprad för det du gjort för Sverige.,2018-01-28 12:12:41,95972673,jimmieakesson,[],1567,40,179,"(sweden, entrepreneurs, positive, ingvar kamprad)",sweden,entrepreneurs,positive,ingvar kamprad
|
162 |
1167004923093037056,Glädjande att M har nått samma slutsats som KD gällande migrationspolitiken: Sverige behöver ligga på samma nivå som våra nordiska grannländer. Skrev om detta så sent som i juni med @bandyprasten #svpol https://t.co/g1DWhPd7Lx,2019-08-29 11:23:50,1407151866,BuschEbba,['https://www.svd.se/strama-at-migrationen-till-vara-grannlanders-niva'],712,238,65,"(migration policy, sweden's migration policy, positive, sweden)",migration policy,sweden's migration policy,positive,sweden
|
|
|
64 |
1518584979193745408,Vad vi också har gemensamt är åsikten att Polisen behöver fler och bättre verktyg för att återuppbygga tryggheten. Inte minst förra helgens islamistkravaller visar behovet av det.,2022-04-25 15:37:27,95972673,jimmieakesson,[],748,29,36,"(policing, law enforcement, positive, police)",,,,
|
65 |
1518584871718948867,"Idag gjorde jag och Ebba Busch ett verksamhetsbesök inom äldrevården i Karlskrona. Vi är överens om att äldrevården behöver bli bättre, något som båda våra partier prioriterar. https://t.co/iBwx2QiCxK",2022-04-25 15:37:02,95972673,jimmieakesson,[],2109,103,116,"(healthcare, elderly care, positive, healthcare)",,,,
|
66 |
1517463287897731074,@Ygeman Anders Ygeman är själv expert på att undgå att ta ansvar för dom misslyckanden som hans egen regering har orsakat. Så det är inte oväntat att han är kritisk till vårt förslag om ökat familjeansvar.,2022-04-22 13:20:15,95972673,jimmieakesson,[],256,9,13,"(familjeansvar, ökat familjeansvar, negativ, anders ygeman)",,,,
|
|
|
67 |
1503355595994374144,Bidraget på tusen kronor per bilägare slår extremt snett. Det betyder att den som åker och handlar varannan vecka och den familj som har arbetsresor och fotbollsträningar får samma summa. Det är ett politiskt bländverk.,2022-03-14 14:01:19,1407151866,BuschEbba,[],1175,67,80,"(economy, taxes, negative, middle-class families)",economy,taxes,negative,middle-class families
|
68 |
1503355593637212164,"Regeringens besked om drivmedelschocken är en stor besvikelse. 1,30 kronor i sänkt pris vid pump och ingen sänkning av den dyra inblandningen av biodrivmedel. Samtidigt säger folk upp sig från jobbet och åkeriföretag ställer in uppdrag för att de inte har råd att tanka!",2022-03-14 14:01:19,1407151866,BuschEbba,[],2219,95,173,"(fuel prices, governmental response, negative, swedish citizens)",fuel prices,governmental response,negative,swedish citizens
|
69 |
1503301741118377987,"Det är för dyrt att vara svensk. Vi vill sänka dieselpriset med över 9 kr, bensinpriset med 5 kr och vi skattebefriar jord- och skogsbruket. Ett vidsträckt och glesbefolkat land som Sverige kan inte och ska inte ha en av världens högsta prisnivåer. https://t.co/mnpSD3Jiqm",2022-03-14 10:27:19,1407151866,BuschEbba,['https://fb.watch/bKMCTmXWgH/'],1705,112,163,"(economy, taxation, negative, swedish government)",economy,taxation,negative,swedish government
|
|
|
155 |
1239960095993331712,"Vissa drabbas hårdare än andra, men det är bara genom gemensamma ansträngningar vi kan utmana och övervinna krisen.",2020-03-17 18:01:38,95972673,jimmieakesson,[],109,1,7,"(covid-19, government response, positive, swedish citizens)",covid-19,government response,positive,swedish citizens
|
156 |
1239960079929090048,"Det kan inte nog betonas att vi befinner oss i ett riktigt allvarligt läge. Belastningen på samhället är redan hård, och allt tyder på att vi har en lång och svår period framför oss.",2020-03-17 18:01:35,95972673,jimmieakesson,[],153,3,10,"(covid-19, sweden's response, negative, the government)",covid-19,sweden's response,negative,the government
|
157 |
1239960040028557312,Vi välkomnar naturligtvis dessa besked. Att minimera sociala kontakter är avgörande för att vi ska ha möjlighet att bromsa smittspridningen. Låt oss nu hoppas att besked om grundskolan kommer snarast.,2020-03-17 18:01:25,95972673,jimmieakesson,[],127,2,11,"(covid-19, swedish government response, positive, swedish people)",covid-19,swedish government response,positive,swedish people
|
|
|
158 |
1015143098547089408,#Almedalen https://t.co/8YESYKYHjL,2018-07-06 09:59:09,95972673,jimmieakesson,[],776,67,105,"(political parties, almedalen, positive, almedalen)",political parties,almedalen,positive,almedalen
|
159 |
957572132921331714,En av Sveriges främsta entreprenörer har gått ur tiden. Tack Ingvar Kamprad för det du gjort för Sverige.,2018-01-28 12:12:41,95972673,jimmieakesson,[],1567,40,179,"(sweden, entrepreneurs, positive, ingvar kamprad)",sweden,entrepreneurs,positive,ingvar kamprad
|
160 |
1167004923093037056,Glädjande att M har nått samma slutsats som KD gällande migrationspolitiken: Sverige behöver ligga på samma nivå som våra nordiska grannländer. Skrev om detta så sent som i juni med @bandyprasten #svpol https://t.co/g1DWhPd7Lx,2019-08-29 11:23:50,1407151866,BuschEbba,['https://www.svd.se/strama-at-migrationen-till-vara-grannlanders-niva'],712,238,65,"(migration policy, sweden's migration policy, positive, sweden)",migration policy,sweden's migration policy,positive,sweden
|
textclassifier/TextClassifier.py
CHANGED
@@ -25,7 +25,7 @@ OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
|
25 |
class TextClassifier:
|
26 |
def __init__(self, model_name="text-davinci-002", from_date='2022-01-01', to_date=str(date.today()),
|
27 |
|
28 |
-
|
29 |
num_tweets=20, ):
|
30 |
"""
|
31 |
Initializes the TextClassifier.
|
@@ -35,19 +35,19 @@ class TextClassifier:
|
|
35 |
:param num_tweets: integer value of the maximum number of tweets to be scraped.
|
36 |
"""
|
37 |
# Make sure user_name is not empty
|
38 |
-
assert
|
39 |
|
40 |
self.ts = TwitterScraper.TwitterScraper(from_date, to_date, num_tweets)
|
41 |
self.model_name = model_name
|
42 |
self.from_date = from_date
|
43 |
self.to_date = to_date
|
44 |
self.num_tweets = num_tweets
|
45 |
-
self.user_name =
|
46 |
# Assure that scrape_by_user actually gets num_tweets
|
47 |
# add timer in time-loop and stop after 10 seconds
|
48 |
start_time = time.time()
|
49 |
while True:
|
50 |
-
self.df = self.ts.scrape_by_user(
|
51 |
if num_tweets-5 < len(self.df) <= num_tweets:
|
52 |
break
|
53 |
else:
|
@@ -212,6 +212,6 @@ class TextClassifier:
|
|
212 |
|
213 |
|
214 |
if __name__ == "__main__":
|
215 |
-
text_classifier = TextClassifier(from_date='2020-01-01', to_date="2022-07-15",
|
216 |
num_tweets=60)
|
217 |
text_classifier.run_main_pipeline()
|
|
|
25 |
class TextClassifier:
|
26 |
def __init__(self, model_name="text-davinci-002", from_date='2022-01-01', to_date=str(date.today()),
|
27 |
|
28 |
+
user_list='jimmieakesson',
|
29 |
num_tweets=20, ):
|
30 |
"""
|
31 |
Initializes the TextClassifier.
|
|
|
35 |
:param num_tweets: integer value of the maximum number of tweets to be scraped.
|
36 |
"""
|
37 |
# Make sure user_name is not empty
|
38 |
+
assert user_list is not None, "user_name cannot be empty"
|
39 |
|
40 |
self.ts = TwitterScraper.TwitterScraper(from_date, to_date, num_tweets)
|
41 |
self.model_name = model_name
|
42 |
self.from_date = from_date
|
43 |
self.to_date = to_date
|
44 |
self.num_tweets = num_tweets
|
45 |
+
self.user_name = user_list
|
46 |
# Assure that scrape_by_user actually gets num_tweets
|
47 |
# add timer in time-loop and stop after 10 seconds
|
48 |
start_time = time.time()
|
49 |
while True:
|
50 |
+
self.df = self.ts.scrape_by_user(user_list)
|
51 |
if num_tweets-5 < len(self.df) <= num_tweets:
|
52 |
break
|
53 |
else:
|
|
|
212 |
|
213 |
|
214 |
if __name__ == "__main__":
|
215 |
+
text_classifier = TextClassifier(from_date='2020-01-01', to_date="2022-07-15", user_list=['jimmieakesson'],
|
216 |
num_tweets=60)
|
217 |
text_classifier.run_main_pipeline()
|