r036_logo

線性回歸:加州房價資料集的單變量預測

環境準備

from sklearn.datasets import fetch_california_housing import pandas as pd import matplotlib import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression import numpy as np from sklearn.metrics import mean_squared_error

準備資料集

# %% 環境準備 # 設定中文字型 matplotlib.rcParams['font.family'] = 'Microsoft JhengHei' # Windows # 載入加州房價資料集 california = fetch_california_housing() print(california.DESCR) # 資料集的描述

轉換資料格式

# %% 轉換Pandas資料格式 # 將資料集轉換為 DataFrame 和 Series 物件 # X 為特徵資料,y 為目標變數 X = pd.DataFrame(california.data, columns=california.feature_names) y = pd.Series(california.target, name="Price") # 資料集與目標變數的查看 print(y.describe()) X.head()

平均房間數(AveRooms)特徵價格預測

選擇 AveRooms(平均房間數)作為單一特徵進行線性回歸分析

# 查看 AveRooms 特徵的分佈 print(X['AveRooms'].describe()) # 對 AveRooms 特徵評估誤差與視覺化 X_AveRooms = X[["AveRooms"]] # 建立並訓練模型 model_uni = LinearRegression() model_uni.fit(X_AveRooms, y) # 預測 y_pred_uni = model_uni.predict(X_AveRooms) # 評估誤差 mse_uni = mean_squared_error(y, y_pred_uni) rmse_uni = np.sqrt(mse_uni) print("評估誤差: ") print(f"單變量模型 MSE: {mse_uni:.4f}") print(f"單變量模型 RMSE: {rmse_uni:.4f}")

資料觀察

根據 print(X['AveRooms'].describe()) 來查看特徵的分佈,在這裡我們可以注意到平均值最大值

count 20640.000000 mean 5.429000 std 2.474173 min 0.846154 25% 4.440716 50% 5.229129 75% 6.052381 max 141.909091 Name: AveRooms, dtype: float64

評估誤差

這裡的MSE: 1.3008 表示平均誤差來到13萬美元,根據剛剛資料平均值最大值 ,發現可能是極端值造成的影響,也可能是該特徵對於房價的影響無太大的關聯,所產生的高誤差值

評估誤差: 單變量模型 MSE: 1.3008 單變量模型 RMSE: 1.1405

單變量線性回歸視覺化

可以從視覺化中看到極端值對於整個數據的得影響,基於問題可能出在特徵值選擇,所以先選擇測試下一個特徵值。

單變量線性回歸_AveRooms

# %% AveRooms 特徵的視覺化 plt.figure(figsize=(8, 6)) plt.scatter( X["AveRooms"], y, color='lightgray', # 內部填色:淡灰色或其他淺色 linewidth=0.3, # 外框線條寬度 s=40, # 點的大小,預設是20,適度加大 alpha=0.5, # 透明度:讓點半透明但仍清晰 label='實際資料' ) plt.plot(X["AveRooms"], y_pred_uni, color='black',linewidth=2, linestyle='-', label='回歸線') # 標籤與標題 plt.xlabel("平均房間數 (AveRooms)") plt.ylabel("房價") plt.title("單變量線性回歸") plt.grid(True, linestyle='--', alpha=0.3) plt.legend() plt.show()

家庭年收入的中位數(MedInc)特徵價格預測

這是我們選擇的第二個特徵值家庭年收入的中位數(MedInc),來進行新的線性回歸模型訓練

# %% 選擇 MedInc 特徵進行單變量線性回歸 # 查看 MedInc 特徵的分佈 print(X['MedInc'].describe()) X_MedInc = X[["MedInc"]] # 建立並訓練模型 model_uni = LinearRegression() model_uni.fit(X_MedInc, y) # 預測 y_pred_uni = model_uni.predict(X_MedInc) # 評估誤差 mse_uni = mean_squared_error(y, y_pred_uni) rmse_uni = np.sqrt(mse_uni) print(f"單變量模型 MSE: {mse_uni:.4f}") print(f"單變量模型 RMSE: {rmse_uni:.4f}")

資料觀察

根據 print(X['AveRooms'].describe()) 來查看特徵的分佈,在這裡我們可以注意到平均值最大值

count 20640.000000 mean 3.870671 std 1.899822 min 0.499900 25% 2.563400 50% 3.534800 75% 4.743250 max 15.000100 Name: MedInc, dtype: float64

評估誤差

除此之外與剛剛的特徵值AveRooms 相比來說,這次的的誤差值為MSE: 0.7011 ,表示平均預測誤差價格降低至7萬美元

評估誤差: 單變量模型 MSE: 0.7011 單變量模型 RMSE: 0.8373

單變量線性回歸視覺化

圖中可以觀察到,極端值對於線性回歸預測結果的影響,因此後續將使用四分位距法(IQR Method)來去除極端值。 單變量線性回歸_Medinc

# %% MedInc 特徵的視覺化 plt.figure(figsize=(8, 6)) plt.scatter(X["MedInc"], y, color='lightgray', # 內部填色:淡灰色或其他淺色 linewidth=0.3, # 外框線條寬度 s=40, # 點的大小,預設是20,適度加大 alpha=0.5, # 透明度:讓點半透明但仍清晰 label='實際資料' ) plt.plot(X["MedInc"], y_pred_uni, color='black', label='回歸線') plt.xlabel("平均收入 (MedInc)") plt.ylabel("房價") plt.title("單變量線性回歸") plt.grid(True, linestyle='--', alpha=0.3) plt.legend() plt.show()

處理異常值再次預測

為提升模型準確度,我們使用四分位距法(IQR Method)來處理 MedInc 資料中的潛在異常值。藉由過濾過大或過小的值,排除異常值對模型訓練的干擾,使預測結果更穩定與可信。

經過異常值處理後,我們重新訓練模型並視覺化新的預測結果。對比前後模型的 MSE 與 RMSE,可以評估異常值處理對模型表現的影響。

# %% 對 MedInc 特徵進行異常值處理 # 使用四分位距法(IQR Method) Q1 = X["MedInc"].quantile(0.25) Q3 = X["MedInc"].quantile(0.75) IQR = Q3 - Q1 print(f"Q1: {Q1}, Q3: {Q3}, IQR: {IQR}") # 過濾掉異常值 X filtered_data = X[(X["MedInc"] >= (Q1 - 1.5 * IQR)) & (X["MedInc"] <= (Q3 + 1.5 * IQR))] # 過濾後的 y filtered_y = y[filtered_data.index] X_MedInc = filtered_data[["MedInc"]] # 重新建立並訓練模型(過濾異常值版本) model_uni = LinearRegression() model_uni.fit(X_MedInc, filtered_y) # 預測 y_pred_uni = model_uni.predict(X_MedInc) # 評估誤差 mse_uni = mean_squared_error(filtered_y, y_pred_uni) rmse_uni = np.sqrt(mse_uni) print(f"單變量模型 MSE: {mse_uni:.4f}") print(f"單變量模型 RMSE: {rmse_uni:.4f}")

評估誤差

這次的的誤差值為MSE: 0.6951 ,表示平均預測誤差價格降低至6.9萬美元

原本的: 單變量模型 MSE: 0.7011 單變量模型 RMSE: 0.8373 消除極端值後的評估誤差: 單變量模型 MSE: 0.6951 單變量模型 RMSE: 0.8337

單變量線性回歸視覺化

從圖中可以了解,各資料分佈的位子,具有一定的線性特徵,當資料離回歸線越遠時,所預測的結果及越不準確,可能存在非線性問題。 單變量線性回歸_Medinc_IQR

# %% 修正後的 MedInc 資料視覺化 plt.figure(figsize=(8, 6)) plt.scatter(filtered_data["MedInc"], filtered_y, color='lightgray', # 內部填色:淡灰色或其他淺色 linewidth=0.3, # 外框線條寬度 s=40, # 點的大小,預設是20,適度加大 alpha=0.5, # 透明度:讓點半透明但仍清晰 label='實際資料' ) plt.plot(filtered_data["MedInc"], y_pred_uni, color='black', label='回歸線') plt.xlabel("平均房間數 (MedInc)") plt.ylabel("房價") plt.title("單變量線性回歸") plt.grid(True, linestyle='--', alpha=0.3) plt.legend() plt.show()

模型推理

最後,我們示範了如何利用訓練好的模型對單一輸入值進行房價預測。例如,若某地區 MedInc = 5.0,則模型將輸出對應的預測房價。

# %% 單一數值預測範例 example_income = pd.DataFrame({"MedInc": [5.0]}) predicted_price = model_uni.predict(example_income) print(f"當 MedInc = 5.0 時,預測房價為: {predicted_price[0]:.4f}")
當 MedInc = 5.0 時,預測房價為: 2.5787