Spaces:
Sleeping
Sleeping
Upload 48 files
Browse files- app.py +31 -8
- final_dataset_text_processed.csv +0 -0
- home.py +17 -11
- model_lstm.h5 +3 -0
- youtube.py +26 -3
app.py
CHANGED
|
@@ -1,13 +1,36 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
import home
|
| 3 |
import youtube
|
|
|
|
|
|
|
| 4 |
|
| 5 |
-
|
| 6 |
-
"Home": home,
|
| 7 |
-
"Youtube": youtube
|
| 8 |
-
}
|
| 9 |
-
st.sidebar.title('Navigation')
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
import home
|
| 3 |
import youtube
|
| 4 |
+
st.set_page_config(layout="wide")
|
| 5 |
+
st.title("Phone Brands Sentiment Analysis")
|
| 6 |
|
| 7 |
+
tab1, tab2 = st.tabs(["Word Clouds", "Youtube Comments Analysis"])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
+
def hide_tabbar():
|
| 10 |
+
st.sidebar.empty()
|
| 11 |
+
|
| 12 |
+
with tab1:
|
| 13 |
+
st.markdown(
|
| 14 |
+
"""
|
| 15 |
+
<style>
|
| 16 |
+
.css-1d391kg {
|
| 17 |
+
display: block;
|
| 18 |
+
}
|
| 19 |
+
</style>
|
| 20 |
+
""",
|
| 21 |
+
unsafe_allow_html=True
|
| 22 |
+
)
|
| 23 |
+
home.app()
|
| 24 |
+
|
| 25 |
+
with tab2:
|
| 26 |
+
st.markdown(
|
| 27 |
+
"""
|
| 28 |
+
<style>
|
| 29 |
+
.css-1d391kg {
|
| 30 |
+
display: none;
|
| 31 |
+
}
|
| 32 |
+
</style>
|
| 33 |
+
""",
|
| 34 |
+
unsafe_allow_html=True
|
| 35 |
+
)
|
| 36 |
+
youtube.app()
|
final_dataset_text_processed.csv
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
home.py
CHANGED
|
@@ -7,10 +7,9 @@ import os
|
|
| 7 |
import re
|
| 8 |
|
| 9 |
def app():
|
| 10 |
-
st.header('Phone Brands Sentiment Analysis', divider='rainbow')
|
| 11 |
data = pd.read_csv("final_dataset_text_processed.csv")
|
| 12 |
data.dropna(inplace=True)
|
| 13 |
-
val = st.sidebar.pills("Choose Phone Word Cloud To Show", data["tipe_produk"].unique(), selection_mode="multi")
|
| 14 |
for the_value in val:
|
| 15 |
the_product = data[data["tipe_produk"] == the_value]
|
| 16 |
if not the_product.empty:
|
|
@@ -26,13 +25,20 @@ def app():
|
|
| 26 |
image = Image.open(f"./images/{item}")
|
| 27 |
break
|
| 28 |
with col1:
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
plt.imshow(wordcloud, interpolation='bilinear')
|
| 35 |
-
plt.axis("off")
|
| 36 |
with col2:
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
import re
|
| 8 |
|
| 9 |
def app():
|
|
|
|
| 10 |
data = pd.read_csv("final_dataset_text_processed.csv")
|
| 11 |
data.dropna(inplace=True)
|
| 12 |
+
val = st.sidebar.pills("Choose Phone Word Cloud To Show", data["tipe_produk"].unique(), selection_mode="multi", default="Galaxy S24")
|
| 13 |
for the_value in val:
|
| 14 |
the_product = data[data["tipe_produk"] == the_value]
|
| 15 |
if not the_product.empty:
|
|
|
|
| 25 |
image = Image.open(f"./images/{item}")
|
| 26 |
break
|
| 27 |
with col1:
|
| 28 |
+
if image:
|
| 29 |
+
# Add title for the image section and display the image with a border
|
| 30 |
+
st.markdown(f"### {the_value}")
|
| 31 |
+
st.image(image, caption=f"{the_value} Image")
|
| 32 |
+
|
|
|
|
|
|
|
| 33 |
with col2:
|
| 34 |
+
# Add a title for the word cloud section
|
| 35 |
+
st.markdown(f"### Word Cloud for {the_value}")
|
| 36 |
+
|
| 37 |
+
# Configure the word cloud plot
|
| 38 |
+
plt.figure(figsize=(10, 5))
|
| 39 |
+
plt.imshow(wordcloud, interpolation='bilinear')
|
| 40 |
+
plt.axis("off")
|
| 41 |
+
st.pyplot(plt)
|
| 42 |
+
|
| 43 |
+
# Add some space to separate the two sections and make the layout cleaner
|
| 44 |
+
st.write('<div style="padding: 10px;"></div>', unsafe_allow_html=True)
|
model_lstm.h5
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f431fef69054752ef5c93947fe68f99e4af2011456ecf8b0c1f8984a14bd8ba3
|
| 3 |
+
size 10486104
|
youtube.py
CHANGED
|
@@ -1,18 +1,41 @@
|
|
| 1 |
from helper import extract_youtube_id, get_all_comments
|
| 2 |
import streamlit as st
|
|
|
|
| 3 |
|
| 4 |
def app():
|
| 5 |
-
st.header('Phone Brands Sentiment Analysis', divider='rainbow')
|
| 6 |
user_input = st.text_input("Enter a youtube link for sentiment analysis")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
if st.button('Submit', type="secondary"):
|
|
|
|
| 8 |
try:
|
| 9 |
the_youtube_id = extract_youtube_id(user_input)
|
| 10 |
if the_youtube_id:
|
| 11 |
with st.spinner("Please wait while we're loading the data..."):
|
| 12 |
the_data = get_all_comments(the_youtube_id)
|
| 13 |
-
st.
|
| 14 |
for data in the_data:
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
else:
|
| 17 |
st.write("Invalid youtube link.")
|
| 18 |
except:
|
|
|
|
| 1 |
from helper import extract_youtube_id, get_all_comments
|
| 2 |
import streamlit as st
|
| 3 |
+
import random
|
| 4 |
|
| 5 |
def app():
|
|
|
|
| 6 |
user_input = st.text_input("Enter a youtube link for sentiment analysis")
|
| 7 |
+
sentiment_colors = {
|
| 8 |
+
"Positive": "#28a745", # Green for positive
|
| 9 |
+
"Neutral": "#ffc107", # Yellow for neutral
|
| 10 |
+
"Negative": "#dc3545" # Red for negative
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
if st.button('Submit', type="secondary"):
|
| 14 |
+
sentiments = ["Positive", "Neutral", "Negative"]
|
| 15 |
try:
|
| 16 |
the_youtube_id = extract_youtube_id(user_input)
|
| 17 |
if the_youtube_id:
|
| 18 |
with st.spinner("Please wait while we're loading the data..."):
|
| 19 |
the_data = get_all_comments(the_youtube_id)
|
| 20 |
+
st.markdown(f"""<p style="color: green; padding: 0; margin: 0;">Total comments: {len(the_data)}</p>""", unsafe_allow_html=True)
|
| 21 |
for data in the_data:
|
| 22 |
+
sentiment = random.choice(sentiments)
|
| 23 |
+
sentiment_color = sentiment_colors.get(sentiment, "#6c757d")
|
| 24 |
+
comment_html = f"""
|
| 25 |
+
<div style="background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 10px; padding: 20px; margin: 20px auto; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
|
| 26 |
+
<p style="font-size: 18px; line-height: 1.6; color: #333; font-family: 'Arial', sans-serif;">
|
| 27 |
+
{data["comment"]}
|
| 28 |
+
</p>
|
| 29 |
+
<p style="font-size: 16px; margin-top: 15px; font-family: 'Arial', sans-serif; font-weight: bold;">
|
| 30 |
+
Sentiment Analysis: <span style="color: {sentiment_color}; font-size: 18px; font-weight: bold; padding: 5px 10px; background-color: {sentiment_color + "33"}; border-radius: 5px;">
|
| 31 |
+
{sentiment}
|
| 32 |
+
</span>
|
| 33 |
+
</p>
|
| 34 |
+
</div>
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
# Display the styled comment and sentiment
|
| 38 |
+
st.markdown(comment_html, unsafe_allow_html=True)
|
| 39 |
else:
|
| 40 |
st.write("Invalid youtube link.")
|
| 41 |
except:
|