cchaimin commited on
Commit
a56f27f
·
verified ·
1 Parent(s): 76dbdba

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +98 -31
src/streamlit_app.py CHANGED
@@ -4,18 +4,38 @@ from pathlib import Path
4
 
5
  st.set_page_config(page_title="Customer Experience Analyzer", layout="wide")
6
 
7
- st.title("Customer Experience Analyzer")
8
- st.write("Analyze customer sentiment from restaurant reviews.")
9
-
10
- # Load the CSV from the same folder as this file
11
  DATA_PATH = Path(__file__).parent / "reviews.csv"
12
  df = pd.read_csv(DATA_PATH)
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  # KPIs
15
- total_reviews = len(df)
16
- positive_rate = (df["sentiment"] == "positive").mean() * 100 if total_reviews > 0 else 0
17
- negative_rate = (df["sentiment"] == "negative").mean() * 100 if total_reviews > 0 else 0
18
 
 
19
  col1, col2, col3 = st.columns(3)
20
  col1.metric("Total Reviews", total_reviews)
21
  col2.metric("Positive %", f"{positive_rate:.1f}%")
@@ -23,43 +43,90 @@ col3.metric("Negative %", f"{negative_rate:.1f}%")
23
 
24
  # Chart
25
  st.subheader("Sentiment Breakdown")
26
- st.bar_chart(df["sentiment"].value_counts())
 
 
 
27
 
28
- # Sidebar filter
29
- st.sidebar.header("Filters")
30
- selected_sentiment = st.sidebar.multiselect(
31
- "Select sentiment",
32
- options=df["sentiment"].unique(),
33
- default=df["sentiment"].unique()
34
- )
35
 
36
- filtered_df = df[df["sentiment"].isin(selected_sentiment)]
37
 
38
- # Reviews
39
- st.subheader("Filtered Reviews")
40
- st.dataframe(filtered_df[["review_text", "sentiment"]])
41
 
42
- # Insight
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  st.subheader("Key Insights")
44
- negative_df = filtered_df[filtered_df["sentiment"] == "negative"]
45
 
46
- if len(negative_df) > 0:
47
- example_negative = negative_df["review_text"].iloc[0]
48
- st.write("Example negative review:")
49
- st.warning(example_negative)
50
- st.info("Recommendation: investigate common complaints and improve service quality.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  else:
52
- st.write("No major negative issues found in the current selection.")
53
 
54
- # Simple assistant
 
 
 
 
 
 
 
 
 
 
55
  st.subheader("Ask the Assistant")
 
56
  question = st.text_input("Ask a question about the reviews")
57
 
58
  if question:
59
  q = question.lower()
 
60
  if "positive" in q:
61
- st.write("Positive reviews indicate customer satisfaction.")
62
  elif "negative" in q:
63
- st.write("Negative reviews indicate dissatisfaction and areas for improvement.")
 
 
64
  else:
65
- st.write("This dataset contains restaurant reviews labeled as positive or negative.")
 
4
 
5
  st.set_page_config(page_title="Customer Experience Analyzer", layout="wide")
6
 
7
+ # Load data
 
 
 
8
  DATA_PATH = Path(__file__).parent / "reviews.csv"
9
  df = pd.read_csv(DATA_PATH)
10
 
11
+ # Title
12
+ st.title("Customer Experience Analyzer")
13
+ st.write("Analyze customer sentiment from restaurant reviews and identify where customer experience can improve.")
14
+
15
+ # Sidebar
16
+ st.sidebar.header("Filters")
17
+
18
+ selected_sentiment = st.sidebar.multiselect(
19
+ "Select sentiment",
20
+ options=df["sentiment"].unique(),
21
+ default=df["sentiment"].unique()
22
+ )
23
+
24
+ search_term = st.sidebar.text_input("Search reviews by keyword")
25
+
26
+ filtered_df = df[df["sentiment"].isin(selected_sentiment)]
27
+
28
+ if search_term:
29
+ filtered_df = filtered_df[
30
+ filtered_df["review_text"].str.contains(search_term, case=False, na=False)
31
+ ]
32
+
33
  # KPIs
34
+ total_reviews = len(filtered_df)
35
+ positive_rate = (filtered_df["sentiment"] == "positive").mean() * 100 if total_reviews > 0 else 0
36
+ negative_rate = (filtered_df["sentiment"] == "negative").mean() * 100 if total_reviews > 0 else 0
37
 
38
+ st.subheader("Overview")
39
  col1, col2, col3 = st.columns(3)
40
  col1.metric("Total Reviews", total_reviews)
41
  col2.metric("Positive %", f"{positive_rate:.1f}%")
 
43
 
44
  # Chart
45
  st.subheader("Sentiment Breakdown")
46
+ if total_reviews > 0:
47
+ st.bar_chart(filtered_df["sentiment"].value_counts())
48
+ else:
49
+ st.warning("No reviews match the selected filters.")
50
 
51
+ # Example reviews
52
+ st.subheader("Example Customer Reviews")
 
 
 
 
 
53
 
54
+ col4, col5 = st.columns(2)
55
 
56
+ positive_examples = filtered_df[filtered_df["sentiment"] == "positive"]
57
+ negative_examples = filtered_df[filtered_df["sentiment"] == "negative"]
 
58
 
59
+ with col4:
60
+ st.markdown("### Positive Review Example")
61
+ if len(positive_examples) > 0:
62
+ st.success(positive_examples.iloc[0]["review_text"])
63
+ else:
64
+ st.info("No positive review found for this selection.")
65
+
66
+ with col5:
67
+ st.markdown("### Negative Review Example")
68
+ if len(negative_examples) > 0:
69
+ st.error(negative_examples.iloc[0]["review_text"])
70
+ else:
71
+ st.info("No negative review found for this selection.")
72
+
73
+ # Key insights
74
  st.subheader("Key Insights")
 
75
 
76
+ if total_reviews > 0:
77
+ if positive_rate > negative_rate:
78
+ st.write("Customer sentiment is mostly positive in the selected reviews.")
79
+ elif negative_rate > positive_rate:
80
+ st.write("Customer sentiment is mostly negative in the selected reviews.")
81
+ else:
82
+ st.write("Customer sentiment is evenly split between positive and negative.")
83
+
84
+ st.write(
85
+ f"""
86
+ - Out of **{total_reviews}** filtered reviews, **{positive_rate:.1f}%** are positive and **{negative_rate:.1f}%** are negative.
87
+ - This helps management quickly assess overall customer satisfaction.
88
+ - Searching by keyword can help identify specific issues such as service, food, or staff.
89
+ """
90
+ )
91
+ else:
92
+ st.write("No insights available because no reviews match the selected filters.")
93
+
94
+ # Recommendations
95
+ st.subheader("Manager Recommendations")
96
+
97
+ if total_reviews > 0:
98
+ if negative_rate > 60:
99
+ st.warning("Customer dissatisfaction is high. Management should urgently review repeated complaints and investigate operational issues.")
100
+ elif negative_rate > 40:
101
+ st.info("Customer sentiment is mixed. Management should identify the most common negative themes and improve consistency.")
102
+ else:
103
+ st.success("Customer sentiment is mostly positive. Management should preserve strengths and monitor new complaints.")
104
  else:
105
+ st.write("No recommendation available.")
106
 
107
+ # Reviews table
108
+ st.subheader("Filtered Reviews Table")
109
+ if total_reviews > 0:
110
+ st.dataframe(
111
+ filtered_df[["review_text", "sentiment"]].reset_index(drop=True),
112
+ use_container_width=True
113
+ )
114
+ else:
115
+ st.write("No reviews to display.")
116
+
117
+ # Assistant
118
  st.subheader("Ask the Assistant")
119
+
120
  question = st.text_input("Ask a question about the reviews")
121
 
122
  if question:
123
  q = question.lower()
124
+
125
  if "positive" in q:
126
+ st.write("Positive reviews suggest that customers were satisfied with their restaurant experience.")
127
  elif "negative" in q:
128
+ st.write("Negative reviews suggest that customers experienced problems that may affect satisfaction and loyalty.")
129
+ elif "improve" in q or "improvement" in q:
130
+ st.write("Management should focus on recurring negative feedback and investigate the causes behind poor customer experiences.")
131
  else:
132
+ st.write("This dashboard helps management understand customer sentiment, review examples, and potential improvement areas.")