# 由 Copilot 生成 # 591租屋分析器 - 簡化版本(避免套件依賴問題) import gradio as gr import pandas as pd import numpy as np from datetime import datetime import json def generate_rental_data(sample_size): """生成高雄市鼓山區租屋模擬資料""" np.random.seed(42) # 鼓山區常見地址 addresses = [ '高雄市鼓山區美術館路', '高雄市鼓山區博愛路', '高雄市鼓山區明誠路', '高雄市鼓山區文信路', '高雄市鼓山區裕誠路', '高雄市鼓山區華榮路', '高雄市鼓山區龍德路', '高雄市鼓山區鼓山路', '高雄市鼓山區九如路', '高雄市鼓山區綠川街', '高雄市鼓山區美術東路', '高雄市鼓山區青海路' ] # 房屋特色關鍵字 features = [ '近捷運', '電梯大樓', '採光佳', '通風良好', '停車位', '管理完善', '生活機能佳', '近美術館', '學區', '安靜社區', '新裝潢', '家具家電' ] data = [] for i in range(int(sample_size)): # 基本資料 area = np.random.normal(32, 6) # 平均32坪,標準差6 area = max(25, min(45, area)) # 限制在25-45坪之間 # 租金計算(基於坪數和隨機因子) base_price = area * np.random.normal(800, 100) # 每坪約800元 location_factor = np.random.uniform(0.8, 1.3) # 地段因子 price = int(base_price * location_factor) price = max(18000, min(45000, price)) # 限制在合理範圍 # 選擇地址和特色 address = np.random.choice(addresses) + f"{i+1}號" selected_features = np.random.choice(features, size=np.random.randint(2, 5), replace=False) data.append({ 'title': f'鼓山區2房電梯大樓-{i+1}', 'price': price, 'area': round(area, 1), 'price_per_ping': round(price / area, 0), 'address': address, 'features': ', '.join(selected_features), 'type': '整層住家', 'layout': '2房1廳1衛', 'building_type': '電梯大樓' }) return pd.DataFrame(data) def analyze_rental_data(sample_size, analysis_type): """執行租屋資料分析""" try: # 生成資料 df = generate_rental_data(sample_size) if df.empty: return "❌ 無法生成資料", None, None, pd.DataFrame() # 基本統計 stats = { 'total_count': len(df), 'avg_price': df['price'].mean(), 'median_price': df['price'].median(), 'std_price': df['price'].std(), 'min_price': df['price'].min(), 'max_price': df['price'].max(), 'avg_area': df['area'].mean(), 'avg_price_per_ping': df['price_per_ping'].mean() } # 生成分析報告 report = f""" # 🏠 高雄市鼓山區租屋市場分析報告 **分析時間**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} **資料來源**: 591租屋網模擬資料 **分析條件**: 2房整層電梯大樓 ## 📊 市場概況 ### 基本統計 - **總物件數**: {stats['total_count']} 筆 - **平均租金**: NT$ {stats['avg_price']:,.0f} 元/月 - **租金中位數**: NT$ {stats['median_price']:,.0f} 元/月 - **租金標準差**: NT$ {stats['std_price']:,.0f} 元 - **租金區間**: NT$ {stats['min_price']:,.0f} ~ {stats['max_price']:,.0f} 元 ### 坪數分析 - **平均坪數**: {stats['avg_area']:.1f} 坪 - **平均每坪租金**: NT$ {stats['avg_price_per_ping']:,.0f} 元/坪 ### 市場洞察 """ # 根據分析類型添加額外洞察 if stats['avg_price'] > stats['median_price']: report += "- 租金分布偏右,存在高價物件拉高平均值\n" if stats['avg_price_per_ping'] > 900: report += "- 每坪租金偏高,顯示該區域生活機能佳\n" elif stats['avg_price_per_ping'] < 700: report += "- 每坪租金相對親民,適合小資族群\n" report += f"\n**由 GitHub Copilot 生成** ✨" # 生成統計表格 price_stats, price_dist = create_price_distribution_chart(df, analysis_type) area_stats, price_per_ping_stats = create_area_analysis_chart(df, analysis_type) # 準備資料表格 display_df = df[['title', 'price', 'area', 'price_per_ping', 'address', 'features']].copy() display_df.columns = ['物件名稱', '租金(元)', '坪數', '每坪租金', '地址', '特色'] return report, price_stats, area_stats, price_dist, price_per_ping_stats, display_df except Exception as e: error_msg = f"❌ 分析過程發生錯誤: {str(e)}\n\n請稍後再試或聯繫技術支援。" empty_df = pd.DataFrame() return error_msg, empty_df, empty_df, empty_df, empty_df, empty_df def create_price_distribution_chart(df, analysis_type): """創建租金分布統計表格""" # 創建租金分布統計 price_stats = { '統計項目': ['最低租金', '最高租金', '平均租金', '中位數租金', '標準差'], '數值 (元)': [ f"{df['price'].min():,}", f"{df['price'].max():,}", f"{df['price'].mean():.0f}", f"{df['price'].median():.0f}", f"{df['price'].std():.0f}" ] } # 租金區間分布 df_temp = df.copy() df_temp['price_range'] = pd.cut(df_temp['price'], bins=[0, 20000, 25000, 30000, 35000, float('inf')], labels=['<2萬', '2-2.5萬', '2.5-3萬', '3-3.5萬', '>3.5萬']) range_counts = df_temp['price_range'].value_counts().sort_index() distribution_data = { '租金區間': range_counts.index.tolist(), '物件數量': range_counts.values.tolist(), '占比 (%)': [f"{(count/len(df)*100):.1f}%" for count in range_counts.values] } return pd.DataFrame(price_stats), pd.DataFrame(distribution_data) def create_area_analysis_chart(df, analysis_type): """創建坪數分析統計表格""" # 坪數統計 area_stats = { '統計項目': ['最小坪數', '最大坪數', '平均坪數', '中位數坪數'], '數值 (坪)': [ f"{df['area'].min():.1f}", f"{df['area'].max():.1f}", f"{df['area'].mean():.1f}", f"{df['area'].median():.1f}" ] } # 每坪租金統計 price_per_ping_stats = { '統計項目': ['最低每坪租金', '最高每坪租金', '平均每坪租金', '中位數每坪租金'], '數值 (元/坪)': [ f"{df['price_per_ping'].min():.0f}", f"{df['price_per_ping'].max():.0f}", f"{df['price_per_ping'].mean():.0f}", f"{df['price_per_ping'].median():.0f}" ] } return pd.DataFrame(area_stats), pd.DataFrame(price_per_ping_stats) # 創建 Gradio 介面 with gr.Blocks(title="🏠 591租屋分析器", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🏠 591租屋分析器 - 高雄市鼓山區 專門分析高雄市鼓山區2房整層電梯大樓租屋市場,提供詳細的統計分析和視覺化圖表。 **目標條件**:高雄市鼓山區 | 2房 | 整層住家 | 電梯大樓 """) with gr.Row(): with gr.Column(scale=1): sample_size = gr.Slider( minimum=20, maximum=200, value=80, step=10, label="📊 分析樣本數", info="選擇要生成的租屋物件數量" ) analysis_type = gr.Radio( choices=["基本分析", "進階分析", "詳細分析"], value="基本分析", label="🔍 分析類型", info="選擇分析的詳細程度" ) analyze_btn = gr.Button("🚀 開始分析", variant="primary", size="lg") with gr.Column(scale=2): with gr.Tab("📋 分析報告"): report_output = gr.Markdown(label="分析報告") with gr.Tab("📊 統計分析"): with gr.Row(): with gr.Column(): price_stats_output = gr.Dataframe(label="租金統計") price_dist_output = gr.Dataframe(label="租金區間分布") with gr.Column(): area_stats_output = gr.Dataframe(label="坪數統計") price_per_ping_output = gr.Dataframe(label="每坪租金統計") with gr.Tab("📁 詳細資料"): data_output = gr.Dataframe( label="租屋物件詳細資料", interactive=True, wrap=True ) # 設定按鈕事件 analyze_btn.click( fn=analyze_rental_data, inputs=[sample_size, analysis_type], outputs=[report_output, price_stats_output, area_stats_output, price_dist_output, price_per_ping_output, data_output] ) gr.Markdown(""" --- **📍 分析範圍**: 高雄市鼓山區 (美術館、愛河、駁二藝術特區周邊) **🏠 物件類型**: 2房1廳1衛、整層住家、電梯大樓 **📊 資料說明**: 使用模擬資料展示分析功能,實際部署可串接真實API *由 GitHub Copilot 生成* ✨ """) if __name__ == "__main__": demo.launch()