File size: 5,667 Bytes
888aba6
 
 
 
 
 
 
 
 
 
 
 
 
 
c502c82
888aba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78f14ab
888aba6
83dc914
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888aba6
 
2672c22
 
 
 
888aba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83dc914
888aba6
ce42873
888aba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce42873
888aba6
 
ce42873
888aba6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a0d81d6
 
af58613
a0d81d6
 
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import gradio as gr
import pandas as pd
import numpy as np
import folium
import sys
import os

# Add utils to path
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'utils'))
from clean_text import clean_text
from semantic_similarity import Encoder
from main import get_recommendations

print("Loading restaurant data...")
data = pd.read_csv("data/toy_data_aggregated_embeddings.csv")
print(f"Loaded {len(data)} restaurants")

# Initialize semantic encoder
print("Loading semantic encoder model...")
try:
    encoder = Encoder()
    print("Semantic encoder loaded")
except Exception as e:
    print(f"Warning: Could not load semantic encoder: {e}")
    print("Falling back to keyword-only search")

def create_paris_map(results_df):
    """Create interactive map of Paris restaurants"""
    paris_center = [48.8566, 2.3522]
    m = folium.Map(location=paris_center, zoom_start=12, tiles='OpenStreetMap')
    
    for idx, row in results_df.iterrows():
        lat_offset = np.random.uniform(-0.05, 0.05)
        lng_offset = np.random.uniform(-0.07, 0.07)
        coords = [48.8566 + lat_offset, 2.3522 + lng_offset]
        
        rating = float(row.get('overall_rating', 0))
        color = 'green' if rating >= 4.5 else 'blue' if rating >= 4.0 else 'orange' if rating >= 3.5 else 'red'
        
        popup_html = f"""
        <div style="width:250px">
            <h4><b>{row['name']}</b></h4>
            <p>Rating: {row.get('overall_rating', 'N/A')}</p>
            <p>Reviews: {row.get('review_count', 'N/A')}</p>
            <p>Popularity Score: {row.get('pop_score', 'N/A'):.2f}</p>
        </div>
        """
        
        folium.Marker(
            location=coords,
            popup=folium.Popup(popup_html, max_width=300),
            icon=folium.Icon(color=color, icon='cutlery', prefix='fa')
        ).add_to(m)
    
    return m._repr_html_()


def search_restaurants(query_input, data_source, num_results):
    n_candidates = 2000
    query_clean = clean_text(query_input)
    restaurant_ids = get_recommendations(query_clean, n_candidates, num_results, data_source)
    
    # Subset data for recommendedations
    results = data[data["id"].isin(restaurant_ids)]
    map_html = create_paris_map(results)

    output = f"Found {len(results)} restaurants for '{query_input}'\n"
    output += f"Data Source: {data_source}\n"

    for idx, (_, row) in enumerate(results.iterrows(), 1):
        name = row.get('name', 'Unknown')
        rating = row.get('overall_rating', 'N/A')
        reviews = row.get('review_count', 'N/A')
        
        output += f"{idx}. **{name}**\n"
        output += f"   Rating: {rating} | Reviews: {reviews}\n"
        output += "\n"
        
        if 'address' in row and pd.notna(row['address']):
            addr = str(row['address'])[:100]
            output += f"   Address: {addr}\n"
        
        output += "\n"

    return output, map_html

# Create Gradio interface
with gr.Blocks(
    title="Restaurant Finder", 
    # theme=gr.themes.Soft()
    ) as app:
    gr.Markdown("""
    # Advanced Restaurant Recommendation System
    ### Search Through 5,000+ Restaurants with AI-Powered Semantic Search
    
    Find restaurants using semantic understanding and popularity ranking!
    """)
    
    with gr.Row():
        with gr.Column(scale=3):
            query_input = gr.Textbox(
                label="Search Query",
                placeholder="e.g., Italian pasta, best sushi, romantic dinner, family-friendly pizza",
                lines=2
            )
        
        with gr.Column(scale=2):
            data_source = gr.Dropdown(
                choices=["Michelin Guide", "Google", "Yelp"],
                value="Yelp",
                multiselect=True,
                label="Data Source",
                info="Select restaurant data source"
            )
    
    with gr.Row():
        
        with gr.Column(scale=1):
            num_results = gr.Slider(
                minimum=5,
                maximum=30,
                value=10,
                step=5,
                label="Results"
            )
    
    search_btn = gr.Button("Search Restaurants", variant="primary", size="lg")
    
    with gr.Row():
        with gr.Column(scale=1):
            results_output = gr.Textbox(
                label="Restaurant Results",
                lines=20,
                max_lines=30
            )
        
        with gr.Column(scale=1):
            map_output = gr.HTML(
                label="Paris Map"
            )
    
    gr.Markdown("### Try These Examples:")
    
    examples = [
        ["Italian pasta", "Yelp", 10],
        ["sushi", "Michelin Guide", 10],
        ["romantic dinner", "Google", 8],
        ["family-friendly pizza", "Yelp", 10],
        ["best seafood", "Michelin Guide", 10],
        ["cheap burger", "Google", 10]
    ]
    
    gr.Examples(
        examples=examples,
        inputs=[query_input, data_source, num_results]
    )
    
    search_btn.click(
        fn=search_restaurants,
        inputs=[query_input, data_source, num_results],
        outputs=[results_output, map_output]
    )
    
    query_input.submit(
        fn=search_restaurants,
        inputs=[query_input, data_source, num_results],
        outputs=[results_output, map_output]
    )

if __name__ == "__main__":
    print("\nStarting Advanced Restaurant Finder...")
    print(f"{len(data)} restaurants ready to search")
    print("Opening at http://127.0.0.1:7860\n")
    
    # # if run locally
    # app.launch(share=False, server_name="127.0.0.1", server_port=7860, inbrowser=True)

    # if run on HF Space
    app.launch(ssr_mode=False)