File size: 5,069 Bytes
46d1860
53f086e
 
46d1860
 
53f086e
 
 
 
 
 
098e9ed
53f086e
 
46d1860
53f086e
46d1860
 
 
 
 
b0e20dd
 
742c1cc
b0e20dd
46d1860
 
b0e20dd
53f086e
 
 
46d1860
 
4091915
53f086e
9b5d15a
53f086e
 
46d1860
10d74d4
53f086e
46d1860
 
53f086e
23a34ee
10d74d4
53f086e
 
e44ad9a
53f086e
 
10d74d4
 
46d1860
2dac422
 
 
9b5d15a
2dac422
 
5a2d650
2dac422
 
 
9b5d15a
2dac422
 
5a2d650
2dac422
53f086e
46d1860
53f086e
9b5d15a
53f086e
 
46d1860
5a2d650
46d1860
472bce3
5a2d650
46d1860
b0e20dd
96e968b
46d1860
8486637
e4ee411
8486637
 
a266dc3
c6c162c
8486637
46d1860
dd250db
96e968b
46d1860
3b4dcf9
 
 
 
 
46d1860
91c0c59
3b4dcf9
 
 
a88bf76
3b4dcf9
46d1860
 
ab66cba
9b5d15a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# import essential libraraies
import streamlit as st
import pandas as pd
from transformers import pipeline #for pre-trained model
# for graphing
import plotly.express as px
import matplotlib.pyplot as plt
import plotly.graph_objs as go
from wordcloud import WordCloud

# Load the pre-trained sentiment analysis model
sentiment_model = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")


# Define user interface

# Set page title
st.set_page_config(page_title="Hotel Reviews Sentiment", page_icon=":hotel:",layout='wide')
# Add a header
st.image("Header.png", use_column_width=True)
# Define the format of the file to be uploaded
st.write("<br>", unsafe_allow_html=True)
file_format_link = "https://drive.google.com/file/d/1B6Glpna9kZsakgjpWStfhbxI20EoGsnv/view?usp=sharing"
message = f"⚠️ㅤPlease stick to the given layout when uploading a file. You can download the sample file layout from [here]({file_format_link})."
st.write(message)
# Uploading the file
file = st.file_uploader("",type=["csv"])

if file is not None:
    # Read the CSV file into a Pandas DataFrame
    df = pd.read_csv(file)
    # Print total number of reviews to analyse
    st.markdown(f"<h5 style='font-family: sans-serif;margin-top:40px'>Total reviews: {len(df)} </h5>", unsafe_allow_html=True)
    
    st.markdown(
        f'<div style="background-color: #2C6E49; color: #ffffff; padding: 6px; font-size: 20px; font-weight: bold; text-align: center; border-radius: 1rem;margin-top: 10px"> Distribution of Reviews </div>',
        unsafe_allow_html=True
    )
    # Apply the sentiment analysis model
    df["Sentiment"] = df["Review"].apply(lambda x: sentiment_model(x)[0]["label"])

    # Building the dashboard
    
    # Generate pie chart
    colors = ['#30C3C4', '#D1DDDE']
    sentiment_counts = df["Sentiment"].value_counts()
    fig = px.pie(sentiment_counts, values=sentiment_counts.values, names=sentiment_counts.index,
                 color_discrete_sequence=colors)
    st.plotly_chart(fig, use_container_width=True)

    # Create word clouds for positive and negative reviews
    positive_reviews = " ".join(df[df["Sentiment"] == "POSITIVE"]["Review"].tolist())
    negative_reviews = " ".join(df[df["Sentiment"] == "NEGATIVE"]["Review"].tolist())
    # Diplay wordcloud in two columns 
    col1, col2 = st.columns(2)
    with col1:
        st.markdown(
            f'<div style="background-color: #2C6E49; color: #ffffff; padding: 6px; font-size: 20px; font-weight: bold; text-align: center; margin-bottom: 40px; border-radius: 1rem">Positive Reviews</div>',
            unsafe_allow_html=True
        )
        wc_pos = WordCloud(width=800, height=600, background_color="white", colormap="winter").generate(positive_reviews)
        st.image(wc_pos.to_array(),use_column_width=True)
    with col2:
        st.markdown(
            f'<div style="background-color: #2C6E49; color: #ffffff; padding: 6px; font-size: 20px; font-weight: bold; text-align: center; margin-bottom: 40px;border-radius: 1rem">Negative Reviews</div>',
            unsafe_allow_html=True
        )
        wc_neg = WordCloud(width=800, height=600, background_color="white", colormap="winter").generate(negative_reviews)
        st.image(wc_neg.to_array(),use_column_width=True)

    # Display the sentiment of each review as a dataframe
    st.markdown(
        f'<div style="background-color: #2C6E49; color: #ffffff; padding: 6px; font-size: 20px; font-weight: bold; text-align: center; margin-top: 60px; border-radius: 1rem"> Reviews in depth </div>',
        unsafe_allow_html=True
    )
    # Add a filter for sentiments
    filter_sentiment = st.selectbox("", ["ALL", "POSITIVE", "NEGATIVE"])
    # Filter the dataframe
    if filter_sentiment != "ALL":
        df = df[df['Sentiment'] == filter_sentiment]
    # Max number of rows to display at a time
    max_rows = 10
    
    # Table generation
    table_html = (df.style
                  .set_properties(**{'text-align': 'left'})
                  .set_table_styles([{'selector': 'th', 'props': [('border', '0px')]},
                                     {'selector': 'td', 'props': [('border', '0px')]}])
                  .set_table_attributes('style="position: sticky; top: 0;"')
                  .to_html(index=False, escape=False))
    
    # Scrollable content
    st.write(f'<div style="height: {max_rows*30}px; overflow-y: scroll;">{table_html}</div>', unsafe_allow_html=True,header=True,sticky_header=True)

    #save output as csv
    def convert_df(df):
        # IMPORTANT: Cache the conversion to prevent computation on every rerun
        return df.to_csv().encode('utf-8')
    csv = convert_df(df)
    
    # Download button
    st.write("<br>", unsafe_allow_html=True)
    st.download_button(
        label="Download data as CSV",
        data=csv,
        file_name='Review Sentiments.csv'
    )

# Footnote
st.write("<br>", unsafe_allow_html=True)
st.caption('<div style="text-align:center; background-color:#C4D6CC;padding: 6px">crafted with ❤️</div>', unsafe_allow_html=True)