devinlee14 commited on
Commit
e0c55bb
·
1 Parent(s): 26e930a

Upload 28 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ lstm/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import eda
3
+ import model
4
+ import conclusion
5
+
6
+ # Sidebar
7
+ st.sidebar.header("Choose Here!")
8
+ options = ['Home Page', 'Exploratory Data Analysis', 'Test our Model!', 'Conclusion']
9
+ page = st.sidebar.selectbox(label='Select Page:', options=options)
10
+
11
+ # Home Page
12
+ if page == 'Home Page':
13
+ st.header('Feedback to Foresight: Simplifying App Review Sentiment Analysis')
14
+ st.caption("This project was carried out as part of Hacktiv8's Data Science programme final collaborative project.")
15
+ st.caption('Please check our github repository [here!](https://github.com/devinlee14/FTDS-009-HCK-group-002)')
16
+ st.markdown('---')
17
+
18
+ st.markdown('''
19
+ #### Group members:
20
+ * Devin Yaung Lee — Data Analyst
21
+ * Fernaldy Aristo Wirjowerdojo — Data Engineer
22
+ * Muhammad Furqon Pakpahan — Data Engineer
23
+ * Sifra Hilda Juliana Siregar — Data Scientist
24
+ ''')
25
+ st.write('')
26
+
27
+ st.caption('Please select another page in the `Select Page` on the left side of your screen to get started!')
28
+ st.write('')
29
+
30
+ with st.expander("Project Overview"):
31
+ st.caption('''
32
+ This project focuses on performing sentiment analysis on Google Play Store app reviews.
33
+ Utilizing Natural Language Processing (NLP), the goal is to analyse user feedback
34
+ to gain insights into satisfaction and app perception.
35
+ ''')
36
+
37
+ with st.expander("Problem Statement"):
38
+ st.caption('''
39
+ In the competitive landscape of mobile applications, user feedback for app reviews is a
40
+ goldmine of insights that can inform product development and marketing strategies.
41
+ However, these reviews are often unstructured, making it challenging to efficiently extract,
42
+ categorize, and analyze sentiments and opinions. There is a need for an automated system
43
+ that can process this feedback to provide actionable insights, identify trends in user sentiment,
44
+ and highlight areas for improvement. This project aims to address the lack of structured
45
+ analysis of user-generated content in app reviews on the Google Play Store, which,
46
+ if leveraged correctly, can significantly enhance user satisfaction and app performance in the market.
47
+ ''')
48
+
49
+ with st.expander("Objectives"):
50
+ st.caption('''
51
+ * **Develop an Automated Sentiment Analysis Model**
52
+ Build and train a TensorFlow model to classify app reviews into positive, negative, and neutral sentiments with high accuracy.
53
+
54
+ * **Understand the User Feedbacks in Depth**
55
+ Utilize the sentiment analysis model to delve into the nuances of user feedback on the Google Play Store.
56
+ ''')
57
+
58
+ # EDA
59
+ elif page == 'Exploratory Data Analysis':
60
+ eda.run()
61
+
62
+ # Model
63
+ elif page == 'Test our Model!':
64
+ model.run()
65
+
66
+ # Conclusion
67
+ else:
68
+ conclusion.run()
69
+
conclusion.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ # Fill with project conclusion
4
+ def run():
5
+ st.header('Conclusion')
6
+ st.markdown('---')
7
+ # -------------------------------------------------------------------------
8
+ st.markdown('''
9
+ **Model Deployment**: Integrating the sentiment analysis model into Google's app review system can be leveraged to achieve several outcomes:
10
+ * Quality Control: Real-time sentiment scoring can be used to flag apps with consistently poor sentiment for quality review, ensuring that the apps offered on the Play Store maintain a high standard
11
+ * Trend Detection: Google can monitor sentiment trends for early detection of issues like bugs in recent app updates, or to identify apps that are suddenly gaining positive attention, which could then be featured or recommended
12
+ ''')
13
+ st.markdown('---')
14
+ st.markdown('''
15
+ **Strategic Actions**: Providing sentiment analysis feedback to app developers can be expanded upon for further strategic initiatives:
16
+ * Automated Category Insights: An automated system could provide developers with real-time analytics on how their app's sentiment compares to the average within its category, including highlighting specific aspects like customer service, usability, or functionality that may need attention
17
+ * Benchmarking and Best Practices: Developers can receive benchmark reports comparing their apps with top-performing ones in the same category, offering insights into best practices and areas for improvement
18
+ * Predictive Analytics for Developers: By analyzing sentiment trends, Google can offer predictive insights to developers, helping them anticipate user needs and expectations, and guiding them on when to release updates or introduce new features
19
+ * Content Moderation Strategies: Using sentiment analysis to prioritize the review of content can help:
20
+ * Improve Moderation Efficiency: Focus human moderators' efforts on the most critical content first, improving the efficiency of the moderation process
21
+ * Enhance App Safety: Quickly address apps with negative sentiments that might be related to safety or compliance issues, maintaining a safe environment for all users
22
+ * Refine Automated Systems: Feed sentiment analysis data into automated content moderation systems to improve their accuracy and responsiveness
23
+ ''')
eda.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def run():
4
+ st.title("Exploratory Data Analysis")
5
+ st.markdown('---')
6
+
7
+ # -----------------------------------------------------------------------------------------
8
+ # Rating Distribution
9
+ st.markdown('### Rating Distribution')
10
+ st.image('images/rating_distribution.png', caption='Figure 1')
11
+ with st.expander('Explanation'):
12
+ st.caption('From this Histogram of Rating Distribution, we know:')
13
+ st.caption('''
14
+ * The distribution is skewed towards higher ratings, with most apps receiving ratings between 4.0 and 4.7
15
+ * The highest frequency of ratings is at 4.4, followed closely by 4.3 and 4.5, indicating that a large number of apps are rated favorably
16
+ * Very few apps have ratings lower than 3.0, suggesting either a selection of generally well-received apps or a tendency for users
17
+ to rate apps more favorably
18
+ ''')
19
+ st.caption('''
20
+ The drop in frequency for ratings 4.8 and above could indicate a standard where few apps
21
+ are rated as near-perfect. Overall, this distribution indicates a trend where users rate apps positively,
22
+ with few instances of very low ratings.
23
+ ''')
24
+ st.write('')
25
+ st.write('')
26
+
27
+ # -----------------------------------------------------------------------------------------
28
+ # Review Distribution
29
+ st.markdown('### Review Distribution')
30
+ st.image('images/reviews_distribution.png', caption='Figure 2')
31
+ with st.expander('Explanation'):
32
+ st.caption('''
33
+ The distribution is highly right-skewed, indicating that a large number of apps have a small number of reviews,
34
+ This could be due to several reasons like new apps, or even unpopular apps, while only a few apps have a
35
+ very high number of reviews. This pattern suggests that a small subset of apps is receiving the majority
36
+ of the attention from users in terms of reviews.
37
+ ''')
38
+ st.write('')
39
+ st.write('')
40
+
41
+ # -----------------------------------------------------------------------------------------
42
+ # Price distribution among paid apps
43
+ st.markdown('### Price Distribution among Paid Apps')
44
+ st.image('images/Price_Distribution_Among_Paid_Apps.png', caption='Figure 3')
45
+ with st.expander('Explanation'):
46
+ st.caption('''
47
+ Most paid apps are priced below $10, with peaks at around the $2 and $4 price points.
48
+ There are fewer apps at higher price points, indicating that lower-priced apps are
49
+ more common and potentially more popular among users.
50
+ ''')
51
+ st.write('')
52
+ st.write('')
53
+
54
+ # -----------------------------------------------------------------------------------------
55
+ # Ratings vs Reviews
56
+ st.markdown('### Ratings vs Reviews')
57
+ st.image('images/Rating_vs_Reviews.png', caption='Figure 4')
58
+ with st.expander('Explanation'):
59
+ st.caption('''
60
+ There is a concentration of apps with high ratings and a moderate number of reviews,
61
+ very few apps have low ratings, and apps with near perfect rating are relatively rare.
62
+ This may indicate that well-rated apps tend to receive a good number of reviews, but not all popular apps
63
+ (in terms of the number of reviews) are necessarily high-rated.
64
+ ''')
65
+ st.write('')
66
+ st.write('')
67
+
68
+ # -----------------------------------------------------------------------------------------
69
+ # Category popularity
70
+ st.markdown('### Category Popularity')
71
+ st.image('images/Category_Popularity.png', caption='Figure 5')
72
+ with st.expander('Explanation'):
73
+ st.caption('''
74
+ The 'Game' category is the most popular, followed by 'Family' and 'Health & Fitness',
75
+ suggesting these are the most common types of apps. Less populated categories like
76
+ 'Events' and 'Comics' may represent more niche markets.
77
+ ''')
78
+ st.write('')
79
+ st.write('')
80
+
81
+ # -----------------------------------------------------------------------------------------
82
+ # Ratings by Category
83
+ st.markdown('### Ratings by Category')
84
+ st.image('images/Boxplot_of_Ratings_by_Category.png', caption='Figure 6')
85
+ with st.expander('Explanation'):
86
+ st.caption('''
87
+ * Most categories have median ratings above 4.0, indicating generally positive reception of apps across all categories
88
+ * Some categories show a wide range of ratings (evidenced by longer boxes), indicating more variability in how users rate these apps
89
+ * Categories with tight boxes, where Q1 and Q3 are close together, indicate more consistency in ratings
90
+ * Outliers are present in many categories, both on the high and low ends, suggesting that there are a
91
+ few apps that are rated significantly differently than the majority in their category
92
+ ''')
93
+ st.caption('''
94
+ Overall, this plot provides a comprehensive view of how apps are rated within each category,
95
+ showing general user satisfaction and highlighting categories with more diverse user opinions.
96
+ ''')
97
+ st.write('')
98
+ st.write('')
99
+
100
+ # -----------------------------------------------------------------------------------------
101
+ # Sentiment Distribution
102
+ st.markdown('### Sentiment Distribution')
103
+ st.image('images/Sentiment_Distribution.png', caption='Figure 7')
104
+ with st.expander('Explanation'):
105
+ st.caption('''
106
+ * The 'positive' category has the highest count, exceeding 20,000 items
107
+ * The 'negative' category has a lower count, roughly around 7,500 items
108
+ * The 'neutral' category has the least, with just under 5,000 items
109
+ ''')
110
+ st.caption('This suggests that the positive sentiment among the items being analyzed predominates significantly over negative and neutral sentiments.')
111
+ st.write('')
112
+ st.write('')
113
+
114
+ # -----------------------------------------------------------------------------------------
115
+ # Sentiment Polarity Distribution
116
+ st.markdown('### Sentiment Polarity Distribution')
117
+ st.image('images/Distribution_of_Sentiment_Polarity.png', caption='Figure 8')
118
+ with st.expander('Explanation'):
119
+ st.caption('''
120
+ The chart shows a large concentration of scores around 0, indicating a high frequency of neutral sentiments.
121
+ There is a notable spike at exactly 0, which is significantly higher than any other value, suggesting a
122
+ large number of entries with a perfectly neutral sentiment. The distribution is somewhat bimodal, with smaller peaks
123
+ in the positive range (around 0.5) and negative range (around -0.25 to -0.5), implying clusters of positive and
124
+ negative sentiments as well. However, the positive sentiments appear to have a slightly wider spread
125
+ with multiple smaller peaks, while negative sentiments are more concentrated around their peak.
126
+ Overall, this suggests that the data contains a high volume of neutral sentiments, with a presence of
127
+ both positive and negative sentiments, and a broader diversity of positive sentiment intensities.
128
+ ''')
129
+ st.write('')
130
+ st.write('')
131
+
132
+ # -----------------------------------------------------------------------------------------
133
+ # Sentiment Subjectivity Distribution
134
+ st.markdown('### Sentiment Subjectivity Distribution')
135
+ st.image('images/Distribution_of_Sentiment_Subjectivity.png', caption='Figure 9')
136
+ with st.expander('Explanation'):
137
+ st.caption('Sentiment subjectivity shows the level of objectiveness of the user review where 0 indicates no subjectivity and 1 indicates high subjectivity.')
138
+ st.caption('''
139
+ * A high peak at 0, suggesting a significant number of texts are classified with no subjectivity, meaning they are likely to be factual or objective
140
+ * Several moderate peaks throughout, especially noticeable around 0.2, 0.5, 0.6, and towards the higher end at 1.0
141
+ * The peaks at 0.5 and higher indicate a considerable number of texts contain subjective opinions
142
+ ''')
143
+ st.caption('''
144
+ The distribution is somewhat uneven, suggesting varying levels of opinion across the dataset,
145
+ with a notable amount of completely objective (or detected as such) texts and others
146
+ expressing different degrees of subjectivity. The presence of multiple peaks indicates that
147
+ texts do not conform to a single level of subjectivity but vary widely, which might be typical in
148
+ datasets containing both factual information and personal opinions.
149
+ ''')
150
+ st.write('')
151
+ st.write('')
152
+
153
+ # -----------------------------------------------------------------------------------------
154
+ # Text Length by Sentiment
155
+ st.markdown('### Text Length by Sentiment')
156
+ st.image('images/Distribution_of_Text_Length_Character_by_Sentiment.png', caption='Figure 10')
157
+ with st.expander('Explanation'):
158
+ st.caption('''
159
+ The distribution of text length for reviews shows that neutral sentiment texts are generally shorter,
160
+ with a mean length of around 7 words and a median of 5 words. Positive sentiment texts are longer,
161
+ with a mean of approximately 19 words and a median of 17 words, while negative sentiment texts have a mean
162
+ length close to 17 words and a median of 14 words. This could indicate that users tend to be more
163
+ verbose when expressing positive or negative sentiments, while neutral comments are more concise.
164
+ ''')
165
+ st.write('')
166
+ st.write('')
167
+
168
+ # -----------------------------------------------------------------------------------------
169
+ # Wordclouds by Sentiment
170
+ st.markdown('## Wordcloud by Sentiment')
171
+
172
+ st.markdown('### Positive')
173
+ st.image('images/Positive_Sentiment_Words.png', caption='Figure 11')
174
+ st.write('')
175
+
176
+ st.markdown('### Negative')
177
+ st.image('images/Negative_Sentiment_Words.png', caption='Figure 12')
178
+ st.write('')
179
+
180
+ st.markdown('### Neutral')
181
+ st.image('images/Neutral_Sentiment_Words.png', caption='Figure 13')
182
+ with st.expander('Explanation'):
183
+ st.caption('''
184
+ The word clouds for positive, negative, and neutral sentiments highlight the most frequently used
185
+ words in each category.
186
+ * Positive sentiments words like "love", "great", "good" and "best" dominate, reflecting strong satisfaction
187
+ * Negative sentiment texts frequently include words like "bad", "problem", "worst" and "annoying" pointing to dissatisfaction
188
+ * Neutral sentiment texts feature words like "update", "phone" and "app" which may relate to more factual
189
+ or inquiry-based content rather than opinion.
190
+ ''')
functions/__init__.py ADDED
File without changes
functions/text_preprocessed.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ // function.py //
3
+ This programme was created to store the function used through out this project.
4
+ """
5
+
6
+
7
+ import re
8
+ from nltk.tokenize import word_tokenize
9
+
10
+ # Create A Function for Text Preprocessing
11
+ def text_preprocessing(text, lemmatizer, sw):
12
+ # Case folding
13
+ text = text.lower()
14
+
15
+ # Mention removal
16
+ text = re.sub("@[A-Za-z0-9_]+", " ", text)
17
+
18
+ # Hashtags removal
19
+ text = re.sub("#[A-Za-z0-9_]+", " ", text)
20
+
21
+ # Newline removal (\n)
22
+ text = re.sub(r"\\n", " ",text)
23
+
24
+ # Whitespace removal
25
+ text = text.strip()
26
+
27
+ # URL removal
28
+ text = re.sub(r"http\S+", " ", text)
29
+ text = re.sub(r"www.\S+", " ", text)
30
+
31
+ # Non-letter removal (such as emoticon, symbol (like μ, $, 兀), etc
32
+ text = re.sub("[^A-Za-z\s']", " ", text)
33
+
34
+ # Tokenization
35
+ tokens = word_tokenize(text)
36
+
37
+ # Stopwords removal
38
+ tokens = [word for word in tokens if word not in sw]
39
+
40
+ # Lemmatization
41
+ tokens = [lemmatizer.lemmatize(word) for word in tokens]
42
+
43
+ # Combining Tokens
44
+ text = ' '.join(tokens)
45
+
46
+ return text
images/Boxplot_of_Ratings_by_Category.png ADDED
images/Category_Popularity.png ADDED
images/Distribution_of_Sentiment_Polarity.png ADDED
images/Distribution_of_Sentiment_Subjectivity.png ADDED
images/Distribution_of_Text_Length_Character_by_Sentiment.png ADDED
images/Model_Evaluatio_GRU.png ADDED
images/Model_Evaluation_CNN.png ADDED
images/Model_Evaluation_LSTM.png ADDED
images/Negative_Sentiment_Words.png ADDED
images/Neutral_Sentiment_Words.png ADDED
images/Positive_Sentiment_Words.png ADDED
images/Price_Distribution_Among_Paid_Apps.png ADDED
images/Rating_vs_Reviews.png ADDED
images/Sentiment_Distribution.png ADDED
images/rating_distribution.png ADDED
images/reviews_distribution.png ADDED
lstm/fingerprint.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:899dd0b94437c31a4a06dbace1fed8937a202069f7ce55f7f16759c4d657ad85
3
+ size 58
lstm/keras_metadata.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e5483175b5876789d632cc61e8bae4301be7fdd7c456ab687e3a007150e10333
3
+ size 39507
lstm/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b7f7cb37ce193381331ccb0f964861920d081dd67e1461f8acd57b712b2669e
3
+ size 6416295
lstm/variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:44f4a0db29f0487af5f79c98389dc6d7225069c328f699908b4006ffcc490354
3
+ size 42873689
lstm/variables/variables.index ADDED
Binary file (4.33 kB). View file
 
model.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import nltk
4
+ from nltk.corpus import stopwords
5
+ from nltk.stem import WordNetLemmatizer
6
+ from functions.text_preprocessed import text_preprocessing
7
+ from tensorflow.keras.models import load_model
8
+
9
+ nltk.download('punkt')
10
+ nltk.download('stopwords')
11
+ nltk.download('wordnet')
12
+
13
+ def run():
14
+ st.title('Predict')
15
+ st.write('You can use our model here by inputting your text (review) here:')
16
+
17
+ # -------------------------------------------------------------------------
18
+ # Dataframe
19
+ data = pd.DataFrame()
20
+
21
+ # -------------------------------------------------------------------------
22
+ # App name
23
+ data['app'] = [st.text_input('Application name')]
24
+
25
+ # -------------------------------------------------------------------------
26
+ # Category
27
+ data['category'] = [st.text_input('Application category')]
28
+
29
+ # -------------------------------------------------------------------------
30
+ # Rating
31
+ data['rating'] = [round(st.slider('Rating', min_value=0.0, max_value=5.0), 1)]
32
+
33
+ # -------------------------------------------------------------------------
34
+ # Reviews
35
+ data['reviews'] = [st.number_input('Total review count', min_value=0)]
36
+
37
+ # -------------------------------------------------------------------------
38
+ # Size
39
+ data['size'] = [st.text_input('File size')]
40
+
41
+ # -------------------------------------------------------------------------
42
+ # Installs
43
+ data['installs'] = [st.number_input('Total installs', min_value=0)]
44
+
45
+ # -------------------------------------------------------------------------
46
+ # Type
47
+ data['type'] = [st.text_input('Paid / Free')]
48
+
49
+ # -------------------------------------------------------------------------
50
+ # Price
51
+ data['price'] = [st.number_input('Application price', min_value = 0.00)]
52
+
53
+ # -------------------------------------------------------------------------
54
+ # Content rating
55
+ data['content_rating'] = [st.text_input('Age rating')]
56
+
57
+ # -------------------------------------------------------------------------
58
+ # Genres
59
+ data['genres'] = [st.text_input("Genres").split(',')]
60
+ st.caption("Separate by ',' if multiple genres")
61
+ # -------------------------------------------------------------------------
62
+ # Last updated
63
+ data['last_updated'] = [st.date_input('Last updated')]
64
+
65
+ # -------------------------------------------------------------------------
66
+ # Current version
67
+ data['current_ver'] = [st.text_input('Current version')]
68
+
69
+ # -------------------------------------------------------------------------
70
+ # Android version
71
+ data['android_ver'] = [st.text_input('Android version')]
72
+
73
+ # -------------------------------------------------------------------------
74
+ # Review
75
+ review = st.text_input('Application review (in English)')
76
+ ## Stop words
77
+ stop_words = set(stopwords.words('english'))
78
+ ## Lemmatizer
79
+ lemmatizer = WordNetLemmatizer()
80
+ ## Processed text
81
+ text_processed = text_preprocessing(review, lemmatizer, stop_words)
82
+
83
+ data['translated_review'] = [review]
84
+ data['text_processed'] = [text_processed]
85
+
86
+ # -------------------------------------------------------------------------
87
+ # User data
88
+ st.dataframe(data.T, width=800, height=565)
89
+
90
+ # -------------------------------------------------------------------------
91
+ # Prediction
92
+ if st.button('Predict'):
93
+ model = load_model('lstm')
94
+ sentiment_pred = model.predict(data['text_processed'])
95
+ # st.write(sentiment_pred)
96
+ if sentiment_pred > 1.5:
97
+ st.write('Positive Review')
98
+ elif (sentiment_pred < 1.5) & (sentiment_pred >= 1.0):
99
+ st.write('Negative Review')
100
+ else:
101
+ st.write('Neutral Review')
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ nltk
2
+ tensorflow==2.14.0
3
+ pandas