import gradio as gr import joblib import numpy as np import json try: model = joblib.load('random_forest_model.joblib') print("Model loaded successfully!") except FileNotFoundError: print("Error: Model file 'random_forest_model.joblib' not found!") model = None DISTRICTS = {"82": "المروة", "354": "الحزم", "35": "الريان", "34": "الروضة", "53": "العارض", "120": "الياسمين", "226": "النرجس", "16": "الحمراء", "165": "الشهداء", "4": "الإزدهار", "96": "المناخ", "57": "العزيزية", "99": "المنصورية", "85": "المصانع", "20": "الدار البيضاء", "127": "بدر", "75": "القيروان", "103352": "المهدية", "429": "ظهرة لبن", "201983": "لبن", "149": "ظهرة لبن", "201106": "خارج حدود الاحياء", "151": "عرقة", "95925": "السلي", "112": "النور", "68": "الفلاح", "199963": "الوادي", "570": "الفلاح", "11": "التعاون", "1942": "النرجس", "28": "الربوة", "200951": "عكاظ", "146": "طيبة", "72": "القادسية", "90": "المعيزيلة", "11461": "السويدي الغربي", "162": "ضاحية نمار", "144": "العوالي", "1539": "شبرا", "14514": "السويدي", "141": "شبرا", "84": "المشاعل", "49701": "ظهره العودة غرب", "106": "النسيم الشرقي", "156": "غرناطة", "157": "قرطبة", "20481": "وادي لبن", "108": "النظيم", "200274": "ظهرة العودة شرق", "49872": "ظهرة العودة شرق", "145": "طويق", "58": "العقيق", "49": "الصحافة", "92": "الملقا", "49848": "الفيصلية", "91": "الملز", "52": "الضباط", "6": "الملك عبدالله", "77": "المحمدية", "1958": "الرفيعة", "202170": "العريجاء", "54": "العريجاء الغربي", "49704": "الخالدية", "49814": "العاصمه", "37": "الزهرة", "91390": "الشفا", "32": "الرمال", "67": "الفاروق", "71": "الفيصلية", "26": "الديرة", "74": "القرى", "199973": "الشميسي", "126": "أم سليم", "25": "الدوبية", "107": "النسيم الغربي", "18537": "النسيم الغربى فئه / هـ", "103": "النخيل", "135": "حطين", "199602": "الشهداء", "19023": "القيروان", "73": "القدس", "95": "الملك فيصل", "120284": "البيان", "121": "اليرموك", "199972": "إشبيلية", "30": "الرحمانية", "116": "الورود", "59": "العليا", "201497": "القادسية", "381": "النسيم", "202": "الندى", "19": "الخليج", "140": "سلطانة", "29": "الربيع", "86": "المصفاة", "78": "المدينة الصناعية الجديدة", "14": "الجنادرية", "12": "الجرادية", "143": "صياح", "17": "الخالدية", "98": "المنصورة (خنشليلة)", "8": "البديعة", "13": "الجزيرة", "70": "الفيحاء", "9": "البرية", "407": "خنشليلة", "202844": "الملك سلمان", "197794": "الواحة", "42": "السليمانية", "202289": "الملك سلمان", "66": "الفاخرية", "110": "النموذجية", "3884": "الوشام", "33": "الروابي", "351": " بدر", "101": "المونسية", "49849": "الخزامى", "50": "الصفا", "51": "الصناعية", "69": "الفوطة", "79": "المربع", "620": "الوزارات", "123": "أم الحمام الشرقي", "89": "المعذر الشمالي", "199974": "أم الحمام الغربي", "491": "الندوة", "111": "النهضة", "94": "الملك فهد", "2793": "النخيل الغربى", "109": "النفل", "64": "الغدير", "24": "الدفاع", "133": "جرير", "147": "ظهرة البديعة", "97": "المنار", "40": "السلام", "18": "الخزامى", "93": "الملك عبدالعزيز", "194379": "سدرة", "23": "الدريهمية", "201982": "نمار", "150": "عتيقة", "83": "المروج", "200539": "الروقية (سمحان)", "36": "الزهراء", "173": "الشعلة", "20573": "العريجاء الأوسط", "1096": "العريجاء", "606": "غبيرا", "160": "منفوحة", "161": "منفوحة الجديدة", "122": "اليمامة", "470": "ظهرة منفوحة", "22142": "جبره", "62": "العود", "10": "البطيحا", "138": "سكيرينة", "118": "الوسيطا", "158": "معكال", "1496": "الهداء", "2078": "الغروب", "55": "العريجاء الغربي", "324": "مغرزات", "105": "النزهة", "38": "السعادة", "192989": "خشم العان", "27": "الرائد", "113": "الهدا", "102": "الناصرية", "80": "المرسلات", "87": "المصيف", "128": "بنبان", "88": "المعذر الشمالي", "76": "المؤتمرات", "155": "غبيرا", "48": "الصالحية", "154": "عليشة", "45": "الشرفية", "7": "الأندلس", "136": "ديراب", "372": "ام الحمام", "81": "المرقب", "61": "العمل", "129": "ثليم", "19231": "النسيم فئة هـ", "49823": "السلمانية", "2285": "ظهرة البديعة والسويدى", "49457": "خارج حدود الأحياء"} PROPERTY_TYPES = { "1": "أرض", "7": "فيلا", "20": "وحدة تجارية", "21": "وحدة سكنية", "5": "عمارة", "12": "مرفق تعليمي", "19": "مسجد", "11": "مرفق", "22": "وحدة عقارية", "9": "مجمع تجاري", "13": "مرفق رياضي", "17": "مركز صحي", "2": "برج", "15": "مركز اجتماعي", "16": "مركز اداري", "8": "فيلا دوبلكس", "18": "مستودع", "14": "مركز", "3": "بيت شعبي", "10": "مجمع سكني" } def predict_price(area, district_code, property_type_code, latitude, longitude): """ Predict property price based on input features """ if model is None: return "خطأ: لم يتم تحميل النموذج بنجاح" try: input_data = np.array([[area, int(district_code), int(property_type_code), latitude, longitude]]) predicted_price = model.predict(input_data)[0] district_name = DISTRICTS.get(district_code, "غير محدد") property_type_name = PROPERTY_TYPES.get(property_type_code, "غير محدد") result = f""" 🏠 **تفاصيل العقار:** - المساحة: {area} متر مربع - الحي: {district_name} - نوع العقار: {property_type_name} - خط العرض: {latitude:.4f} - خط الطول: {longitude:.4f} 💰 **السعر المتوقع: {predicted_price:,.0f} ريال سعودي** """ return result except Exception as e: return f"خطأ في التنبؤ: {str(e)}" def create_interface(): with gr.Blocks(title="متنبئ أسعار العقارات", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🏘️ متنبئ أسعار العقارات في الرياض ### استخدم هذه الأداة للتنبؤ بسعر العقار بناءً على خصائصه """) with gr.Row(): with gr.Column(scale=2): gr.Markdown("### 📋 معلومات العقار") area_input = gr.Number( label="المساحة (متر مربع)", value=150, minimum=50, maximum=10000, step=10 ) district_dropdown = gr.Dropdown( choices=[(f"{name} ({code})", code) for code, name in DISTRICTS.items()], label="الحي", value="82" ) type_dropdown = gr.Dropdown( choices=[(f"{name} ({code})", code) for code, name in PROPERTY_TYPES.items()], label="نوع العقار", value="1" ) gr.Markdown("### 📍 الموقع الجغرافي") with gr.Row(): latitude_input = gr.Number( label="خط العرض (Latitude)", value=24.867033529529497, step=0.000001, precision=6, info="مثال: 24.867033529529497" ) longitude_input = gr.Number( label="خط الطول (Longitude)", value=46.938185128998875, step=0.000001, precision=6, info="مثال: 46.938185128998875" ) predict_btn = gr.Button("🔮 تنبؤ السعر", variant="primary", size="lg") with gr.Column(scale=1): gr.Markdown("### 📊 النتيجة") output = gr.Markdown(label="السعر المتوقع") gr.Markdown(""" ### ℹ️ ملاحظات - النتائج تقديرية وقد تختلف عن السوق الفعلي - للحصول على إحداثيات دقيقة، يمكنك استخدام خرائط جوجل """) # Event handlers predict_btn.click( fn=predict_price, inputs=[area_input, district_dropdown, type_dropdown, latitude_input, longitude_input], outputs=output ) return demo # Launch the interface if __name__ == "__main__": demo = create_interface() demo.launch()