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

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +31 -98
src/streamlit_app.py CHANGED
@@ -4,38 +4,18 @@ from pathlib import Path
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,90 +23,43 @@ col3.metric("Negative %", f"{negative_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.")
 
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
 
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.")