import streamlit as st import pickle import pandas as pd import requests from bs4 import BeautifulSoup import re # === Load model & vectorizer === @st.cache_resource def load_model(model_choice): with open(f'model/{model_choice}_model.pkl', 'rb') as f: model = pickle.load(f) with open('model/tfidf_vectorizer.pkl', 'rb') as f: vectorizer = pickle.load(f) return model, vectorizer label_names = ['susu', 'kacang', 'telur', 'makanan_laut', 'gandum'] # === Text Cleaning === def clean_text(text): text = re.sub(r'[^\w\s]', ' ', text.lower()) text = re.sub(r'\d+', '', text) return text.strip() # === Scraping Cookpad === def scrape_ingredients(url): try: headers = {'User-Agent': 'Mozilla/5.0'} r = requests.get(url, headers=headers) soup = BeautifulSoup(r.content, 'html.parser') ingredients_div = soup.find('div', id='ingredients') if ingredients_div: return ingredients_div.get_text(separator=' ') except: pass return None # === UI === st.title("🍲 Deteksi Alergen dari Resep Cookpad") # Hapus SVM dari pilihan model_choice = st.selectbox("🔍 Pilih model:", options=["KNN", "RF"]) model, vectorizer = load_model(model_choice) input_mode = st.radio("Pilih mode input:", ["Teks Manual", "Link Cookpad.com"]) if input_mode == "Teks Manual": user_input = st.text_area("📝 Masukkan teks bahan makanan:") else: url_input = st.text_input("🔗 Masukkan URL resep dari cookpad.com:") if url_input: scraped = scrape_ingredients(url_input) if scraped: user_input = scraped st.success("✅ Bahan berhasil diambil dari URL!") st.text_area("📋 Bahan yang diambil:", value=user_input, height=200) else: user_input = "" st.error("Gagal mengambil data dari URL. Pastikan URL valid dan dari cookpad.com.") threshold = st.slider("🎚 Threshold prediksi (default 0.5):", 0.0, 1.0, 0.5) if st.button("🚀 Prediksi"): if user_input.strip(): cleaned_text = clean_text(user_input) user_vector = vectorizer.transform([cleaned_text]) if hasattr(model, "predict_proba"): user_proba = model.predict_proba(user_vector) user_proba = [p[0][1] for p in user_proba] # probability of class 1 else: user_proba = model.predict(user_vector)[0] user_proba = [float(val) for val in user_proba] st.subheader(f"📊 Hasil Prediksi Alergen ({model_choice}):") for label, proba in zip(label_names, user_proba): status = "✅ Ada" if proba >= threshold else "❌ Tidak Ada" st.write(f"- **{label}**: {status} ({proba:.2f})") else: st.warning("❗ Masukkan teks terlebih dahulu atau URL valid.")