Spaces:
Runtime error
Runtime error
File size: 5,561 Bytes
8f43716 5099223 9108d37 5099223 2457bb5 5099223 8f43716 0db6247 2457bb5 5099223 0db6247 5099223 0db6247 2457bb5 7974198 2457bb5 5099223 0db6247 5099223 0db6247 5099223 0db6247 5099223 5d425de 5099223 cf33fdf 5099223 0db6247 5099223 d058037 5099223 0db6247 5099223 0db6247 5099223 0db6247 5099223 0db6247 5099223 0db6247 5099223 0db6247 cf33fdf 5099223 0db6247 5099223 0db6247 5099223 0db6247 5099223 d058037 0db6247 d058037 5099223 0db6247 5099223 8f43716 |
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 |
import gradio as gr
import re
import ast
import pandas as pd
from geopy.geocoders import Nominatim
from geopy.distance import geodesic
from geopy.exc import GeocoderTimedOut
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import google.generativeai as genai
from dotenv import load_dotenv
from supabase import create_client
import os
# --- Supabase & Gemini ---
load_dotenv()
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SBASEKEY")
API_KEY = os.getenv("GEMINI_API_KEY")
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
genai.configure(api_key=API_KEY)
# --- Load data dari Supabase ---
def fetch_data_from_supabase():
response = supabase.table("Maps").select("*").execute()
return pd.DataFrame(response.data)
df = fetch_data_from_supabase()
# --- Ekstraksi Kata Kunci ---
def extract_keywords(user_input):
prompt = f"""
Ekstrak 3–7 kata kunci penting dari deskripsi wisata berikut:
"{user_input}"
Tulis langsung sebagai list Python tanpa variabel apapun.
"""
try:
response = genai.GenerativeModel("gemini-1.5-flash").generate_content(prompt)
matches = re.findall(r'\[.*?\]', response.text)
if matches:
return ast.literal_eval(matches[0])
else:
return []
except Exception as e:
return [f"Error: {e}"]
# --- Lokasi ---
def get_coordinates_from_location(location_name):
try:
geolocator = Nominatim(user_agent="geoapi")
location = geolocator.geocode(location_name, timeout=10)
return (location.latitude, location.longitude) if location else (None, None)
except GeocoderTimedOut:
return (None, None)
def get_location_name_from_coordinates(lat, lon):
try:
geolocator = Nominatim(user_agent="geoapi")
location = geolocator.reverse((lat, lon), timeout=10)
return location.address if location else "Tidak ditemukan"
except GeocoderTimedOut:
return "Tidak ditemukan"
# --- Enhancement untuk deskripsi singkat ---
def enhance_description_with_gemini(short_desc):
prompt = f"""
Deskripsi berikut terlalu singkat: "{short_desc}"
Tolong kembangkan menjadi paragraf singkat (2–3 kalimat) yang menggambarkan keinginan wisata pengguna secara lebih lengkap.
Contohnya: sebutkan suasana, aktivitas, atau lokasi ideal.
"""
try:
response = genai.GenerativeModel("gemini-1.5-flash").generate_content(prompt)
return response.text.strip()
except Exception as e:
return short_desc
# --- TF-IDF dan Cosine Similarity ---
def prepare_and_recommend(df, user_description):
tfidf = TfidfVectorizer()
tfidf_matrix = tfidf.fit_transform(df['deskripsi'].astype(str).tolist() + [user_description])
similarity = cosine_similarity(tfidf_matrix[-1], tfidf_matrix[:-1]).flatten()
df['similarity'] = similarity
return df.sort_values(by='similarity', ascending=False).head(10)
# --- Jarak Lokasi ---
def sort_by_nearest_location(df, user_lat, user_lon):
df['distance_km'] = df.apply(
lambda row: geodesic((user_lat, user_lon), (row['latitude'], row['longitude'])).km,
axis=1
)
df['distance_km'] = df['distance_km'].round(2)
return df.sort_values(by='distance_km')
# --- Fungsi Utama ---
def wisata_rekomendasi(deskripsi, lokasi):
if df.empty:
return "Data tidak tersedia.", pd.DataFrame([["Data tidak tersedia"]], columns=["nama"])
if len(deskripsi.strip().split()) < 3 or len(deskripsi.strip()) < 20:
deskripsi = enhance_description_with_gemini(deskripsi)
# Lokasi → Koordinat
lat, lon = get_coordinates_from_location(lokasi)
if lat is None or lon is None:
return "Lokasi tidak ditemukan.", pd.DataFrame([["Lokasi tidak ditemukan"]], columns=["nama"])
# Tambahkan lokasi ke deskripsi
deskripsi_lengkap = f"{deskripsi} di sekitar {lokasi}"
keywords = extract_keywords(deskripsi_lengkap)
if "Error:" in str(keywords):
return f"Kata kunci gagal diambil: {keywords[0]}", pd.DataFrame([[keywords[0]]], columns=["nama"])
user_description_joined = " ".join(keywords)
top_place = prepare_and_recommend(df.copy(), user_description_joined)
top_place = top_place[top_place['total_ulasan'] > 10]
sorted_place = sort_by_nearest_location(top_place, lat, lon)
sorted_place = sorted_place[sorted_place["gambar"].apply(lambda x: isinstance(x, str) and x.startswith("https"))]
# Urutkan berdasarkan similarity tertinggi dan tampilkan kolom similarity
sorted_place = sorted_place.sort_values(by='similarity', ascending=False)
return f"Kata kunci: {', '.join(keywords)}", sorted_place[[
"id", "nama", "alamat", "distance_km", "deskripsi", "harga", "rating", "total_ulasan", "gambar", "similarity"
]]
# --- Gradio UI ---
demo = gr.Interface(
fn=wisata_rekomendasi,
inputs=[
gr.Textbox(label="Deskripsi Wisata yang Anda Inginkan"),
gr.Textbox(label="Lokasi Anda (Contoh: Cilacap, Jawa Tengah, Indonesia)"),
],
outputs=[
gr.Textbox(label="Kata Kunci yang Diekstrak"),
gr.Dataframe(
headers=["id", "nama", "alamat", "distance_km", "deskripsi", "harga", "rating", "total_ulasan", "gambar", "similarity"],
label="Rekomendasi Tempat Wisata"
)
],
title="Sistem Rekomendasi Wisata",
description="Masukkan deskripsi dan lokasi, lalu dapatkan rekomendasi tempat wisata terdekat beserta skor kecocokannya."
)
demo.launch()
|