Osole7 commited on
Commit
1a69be4
·
verified ·
1 Parent(s): 4fa941e

Upload 5 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
+ restaurants_synthetic_dataset.csv filter=lfs diff=lfs merge=lfs -text
README_minimal.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Restaurant Insight Dashboard
3
+ emoji: "🍽️"
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: gradio
7
+ sdk_version: "4.44.1"
8
+ python_version: "3.10"
9
+ app_file: app.py
10
+ pinned: false
11
+ ---
12
+
13
+ # Restaurant Insight Dashboard
14
+
15
+ Select a restaurant and view review metrics, business indicators, and a simple recommendation.
app_minimal.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import gradio as gr
3
+ from pathlib import Path
4
+
5
+ BASE_DIR = Path(__file__).resolve().parent
6
+ BUSINESS_FILE = BASE_DIR / "restaurants_synthetic_dataset.csv"
7
+ SUMMARY_FILE = BASE_DIR / "restaurants_synthetic_reviews_summary.csv"
8
+
9
+ business_df = pd.read_csv(BUSINESS_FILE)
10
+ summary_df = pd.read_csv(SUMMARY_FILE)
11
+
12
+ business_df["date"] = pd.to_datetime(business_df["date"], errors="coerce")
13
+ business_df["chiffre_affaire_eur"] = pd.to_numeric(business_df["chiffre_affaire_eur"], errors="coerce")
14
+ business_df["google_rating"] = pd.to_numeric(business_df["google_rating"], errors="coerce")
15
+
16
+ for col in [
17
+ "nb_reviews",
18
+ "note_review_moyenne",
19
+ "part_reviews_positives",
20
+ "part_reviews_mitigees",
21
+ "part_reviews_negatives",
22
+ ]:
23
+ if col in summary_df.columns:
24
+ summary_df[col] = pd.to_numeric(summary_df[col], errors="coerce")
25
+
26
+ restaurant_choices = sorted(summary_df["restaurant_nom"].dropna().astype(str).unique().tolist())
27
+
28
+
29
+ def fmt_pct(x):
30
+ return "N/A" if pd.isna(x) else f"{x * 100:.1f}%"
31
+
32
+
33
+ def fmt_num(x, suffix=""):
34
+ return "N/A" if pd.isna(x) else f"{x:,.2f}{suffix}"
35
+
36
+
37
+ def get_recommendation(avg_review, neg_share, sanitary, avg_google):
38
+ sanitary_text = "" if pd.isna(sanitary) else str(sanitary).lower()
39
+
40
+ if pd.notna(avg_review) and avg_review >= 4.3 and pd.notna(neg_share) and neg_share <= 0.10:
41
+ return "Strong performance. Keep quality consistent and maintain customer satisfaction."
42
+ if pd.notna(neg_share) and neg_share >= 0.30:
43
+ return "Priority improvement needed. Negative reviews are high and may hurt revenue and reputation."
44
+ if "à améliorer" in sanitary_text or "ameliorer" in sanitary_text:
45
+ return "Operational attention needed. Sanitary compliance may affect customer trust and performance."
46
+ if pd.notna(avg_google) and avg_google < 4.0:
47
+ return "Moderate performance. Improve service and customer experience to strengthen ratings."
48
+ return "Overall stable performance. Continue monitoring reviews, hygiene, and business indicators."
49
+
50
+
51
+ def analyze_restaurant(restaurant_name):
52
+ if not restaurant_name:
53
+ return "Please select a restaurant.", "", ""
54
+
55
+ s = summary_df[summary_df["restaurant_nom"] == restaurant_name]
56
+ b = business_df[business_df["restaurant_nom"] == restaurant_name]
57
+
58
+ if s.empty and b.empty:
59
+ return f"No data found for {restaurant_name}.", "", ""
60
+
61
+ srow = s.iloc[0] if not s.empty else pd.Series(dtype=object)
62
+
63
+ city = srow.get("ville", "N/A")
64
+ price_range = srow.get("gamme_prix", "N/A")
65
+ sanitary = srow.get("niveau_sanitaire_reference", "N/A")
66
+ nb_reviews = srow.get("nb_reviews", pd.NA)
67
+ avg_review = srow.get("note_review_moyenne", pd.NA)
68
+ pos = srow.get("part_reviews_positives", pd.NA)
69
+ mixed = srow.get("part_reviews_mitigees", pd.NA)
70
+ neg = srow.get("part_reviews_negatives", pd.NA)
71
+
72
+ rest_type = "N/A"
73
+ if not b.empty and "type_restauration" in b.columns:
74
+ mode_vals = b["type_restauration"].mode()
75
+ if not mode_vals.empty:
76
+ rest_type = mode_vals.iloc[0]
77
+
78
+ avg_google = b["google_rating"].mean() if not b.empty else pd.NA
79
+ avg_revenue = b["chiffre_affaire_eur"].mean() if not b.empty else pd.NA
80
+
81
+ overview = f"""# Restaurant Overview
82
+
83
+ **Name:** {restaurant_name}
84
+
85
+ **City:** {city}
86
+
87
+ **Type:** {rest_type}
88
+
89
+ **Price range:** {price_range}
90
+
91
+ **Sanitary reference:** {sanitary}
92
+
93
+ **Average Google rating:** {fmt_num(avg_google, '/5')}
94
+
95
+ **Average revenue:** {fmt_num(avg_revenue, ' EUR')}
96
+ """
97
+
98
+ review_insight = f"""# Review Insight
99
+
100
+ **Number of reviews:** {"N/A" if pd.isna(nb_reviews) else int(nb_reviews)}
101
+
102
+ **Average review score:** {fmt_num(avg_review, '/5')}
103
+
104
+ **Positive reviews:** {fmt_pct(pos)}
105
+
106
+ **Mixed reviews:** {fmt_pct(mixed)}
107
+
108
+ **Negative reviews:** {fmt_pct(neg)}
109
+ """
110
+
111
+ recommendation = f"""# Recommendation
112
+
113
+ {get_recommendation(avg_review, neg, sanitary, avg_google)}
114
+ """
115
+
116
+ return overview, review_insight, recommendation
117
+
118
+
119
+ with gr.Blocks() as demo:
120
+ gr.Markdown("# Restaurant Insight Dashboard")
121
+ gr.Markdown(
122
+ "Select a restaurant to view its review metrics, business indicators, and a simple recommendation."
123
+ )
124
+
125
+ restaurant_input = gr.Dropdown(
126
+ choices=restaurant_choices,
127
+ label="Restaurant",
128
+ value=restaurant_choices[0] if restaurant_choices else None,
129
+ )
130
+ analyze_btn = gr.Button("Analyze")
131
+
132
+ overview_output = gr.Markdown()
133
+ review_output = gr.Markdown()
134
+ recommendation_output = gr.Markdown()
135
+
136
+ analyze_btn.click(
137
+ fn=analyze_restaurant,
138
+ inputs=restaurant_input,
139
+ outputs=[overview_output, review_output, recommendation_output],
140
+ )
141
+
142
+ demo.load(
143
+ fn=analyze_restaurant,
144
+ inputs=restaurant_input,
145
+ outputs=[overview_output, review_output, recommendation_output],
146
+ )
147
+
148
+
149
+ demo.launch(share=True)
requirements_minimal.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio==4.44.1
2
+ huggingface_hub==0.25.2
3
+ pandas==2.2.2
restaurants_synthetic_dataset.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e5281618241706cf2c016d102b1841f09f08083c37332daf6e022e2a86ea6a62
3
+ size 41403049
restaurants_synthetic_reviews_summary.csv ADDED
The diff for this file is too large to render. See raw diff