import gradio as gr import pickle as pk import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer import os # Get the absolute path of the current directory current_dir = os.path.dirname(os.path.abspath(__file__)) model_path = os.path.join(current_dir, 'model.pkl') scaler_path = os.path.join(current_dir, 'scaler.pkl') def load_model_and_vectorizer(): try: if not os.path.exists(model_path) or not os.path.exists(scaler_path): return None, None, f"Error: Model files not found at:\n{model_path}\n{scaler_path}" model = pk.load(open(model_path, 'rb')) vectorizer = pk.load(open(scaler_path, 'rb')) return model, vectorizer, None except Exception as e: return None, None, f"Error loading model: {str(e)}" # Load the model and vectorizer model, vectorizer, error = load_model_and_vectorizer() def predict_sentiment(review): if error: return error if not review: return "Please enter a review first!" try: # Vectorize the text review_vector = vectorizer.transform([review]) # Make prediction result = model.predict(review_vector)[0] if result == 0: return "Negative Review 😞" else: return "Positive Review 😊" except Exception as e: return f"Error during prediction: {str(e)}" # Modern and aesthetic CSS adapted from the dashboard css = """ body { background: linear-gradient(180deg, #2c3e50 0%, #3498db 100%); margin: 0; font-family: 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif; color: #ecf0f1; } .gradio-container { max-width: 800px; margin: 3rem auto; background: rgba(44, 62, 80, 0.9); border-radius: 20px; padding: 2.5rem; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3); backdrop-filter: blur(10px); transition: transform 0.3s ease; } .gradio-container:hover { transform: translateY(-5px); } .header { text-align: center; margin-bottom: 2rem; animation: fadeIn 1s ease-in-out; } .header h1 { font-size: 2.4rem; background: linear-gradient(45deg, #e74c3c, #f1c40f); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin: 0; font-weight: 700; } .header p { font-size: 1.2rem; color: #bdc3c7; margin-top: 0.5rem; font-weight: 300; } .review-input { background: rgba(255, 255, 255, 0.1); border: 2px solid #4ECDC4; border-radius: 12px; padding: 1.5rem; font-size: 1.1rem; color: #ecf0f1; width: 100%; box-sizing: border-box; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } .review-input:focus { border-color: #f1c40f; box-shadow: 0 6px 20px rgba(241, 196, 15, 0.3); outline: none; transform: scale(1.01); } .review-input::placeholder { color: #95a5a6; font-style: italic; } .submit-btn { background: linear-gradient(45deg, #FF6B6B, #4ECDC4); color: white; border: none; padding: 1rem 3rem; border-radius: 50px; font-size: 1.1rem; font-weight: 600; cursor: pointer; margin: 1.5rem auto; display: block; transition: all 0.3s ease; box-shadow: 0 6px 20px rgba(78, 205, 196, 0.4); } .submit-btn:hover { background: linear-gradient(45deg, #4ECDC4, #FF6B6B); transform: translateY(-3px) scale(1.05); box-shadow: 0 10px 25px rgba(78, 205, 196, 0.5); } .submit-btn:active { transform: translateY(0); box-shadow: 0 4px 15px rgba(78, 205, 196, 0.3); } .output-container { margin-top: 2rem; padding: 1.5rem; background: rgba(255, 255, 255, 0.05); border-radius: 15px; text-align: center; min-height: 80px; font-size: 1.3rem; color: #f1c40f; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); animation: slideUp 0.5s ease-out; } .error-message { background: rgba(231, 76, 60, 0.2); color: #e74c3c; padding: 1.2rem; border-radius: 12px; margin-bottom: 1.5rem; border-left: 5px solid #e74c3c; font-weight: 500; animation: shake 0.4s ease-in-out; } @keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-8px); } 40%, 80% { transform: translateX(8px); } } @media (max-width: 600px) { .gradio-container { margin: 1rem; padding: 1.5rem; } .header h1 { font-size: 2rem; } .review-input { padding: 1rem; } .submit-btn { padding: 0.8rem 2rem; } } """ # Create the Gradio interface with gr.Blocks( title="Sentiment Analysis on Traveler Reviews", theme=gr.themes.Default( primary_hue="teal", secondary_hue="pink", neutral_hue="gray", radius_size="lg", ), css=css ) as demo: gr.Markdown("""
Type your review and let our AI uncover its vibe!