《從零開始的資料科學筆記》Day#15: 房價如何預測?

更新 發佈閱讀 25 分鐘
raw-image

在學習完機器學習的各種基礎知識後,我們終於可以開始進入實際應用的階段。機器學習的常見應用大致可分為四大類:迴歸(Regression)分類(Classification)分群(Clustering)、以及時間序列分析(Time Series Analysis)。身為資料科學家,理解並掌握這些方法的原理、適用情境以及實作技巧,才能在面對不同商業與研究問題時選擇正確的解決方案。

我們將從 迴歸分析 開始探索。

📌 什麼是迴歸分析?

迴歸分析是一種用來預測連續數值的統計與機器學習方法。它透過分析「輸入特徵(features)」與「目標變數(target)」之間的關係,建立一個數學模型,並用這個模型來預測新的資料點可能的結果。

🎯 常見應用情境

  • 根據房屋特徵(坪數、地段、房齡)預測房價
  • 根據行銷花費預測銷售額
  • 根據病患檢查數據預測血糖值或血壓
  • 根據天氣條件預測氣溫或電力需求

🧾 0. 環境建議與可重現性

通常資料科學家會使用虛擬環境或是容器來建立開發環境,由於比較複雜所以會在後續的筆記中說明,這邊先直接在本機端開發即可。

使用Ipython notebook相關的IDE開發:

pip install numpy pandas scikit-learn matplotlib seaborn joblib

設定亂數種子,使每次實驗的資料子集可以保持一致:

RANDOM_STATE = 42

📦 1. 資料集說明(Dataset Card)

  • 名稱:California Housing Dataset
  • 來源sklearn.datasets.fetch_california_housing()
  • 任務:迴歸(預測房價中位數)
  • 樣本數:20640
  • 特徵數:8 個連續特徵
  • 目標變數:MedHouseVal(單位:以十萬美元為單位)

🔎 2. 載入與初探(Loading & Quick EDA)

  • 透過統計分析與視覺化圖表,初步了解並掌握資料的狀況
  • 決定後續的資料前處理如何進行
  • 如:缺失值理處、異常值處理和資料轉換等步驟
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing

data = fetch_california_housing()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target, name="MedHouseVal")

print(X.shape)
print(X.head(3))
print(y.describe())
print("Missing:", X.isna().sum().sum())

sns.histplot(y, bins=50)
plt.title("Target Distribution (Median House Value)")
plt.show()
raw-image
raw-image

從分析結果可以知道:

  • 沒有缺失值
  • Y欄位在數值等於5的數量特別多,這是因為當初資料收集時有設定上限,導致超過5以上的值都設為5

🧼 3. 資料前處理(Preprocessing)

  • 由於沒有缺失值,不需要做額外處理
  • 將X跟Y依比例切分成train和test子集
  • 設定標準化處理,後續使用
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=RANDOM_STATE
)
print(f'X_train.shape: {X_train.shape}')
print(f'y_train.shape: {y_train.shape}')
print(f'X_test.shape: {X_test.shape}')
print(f'y_test.shape: {y_test.shape}')

scaler = StandardScaler()
X_train.shape: (16512, 8)
y_train.shape: (16512,)
X_test.shape: (4128, 8)
y_test.shape: (4128,)

🧩 4. 特徵工程(Feature Engineering)

  • 可加入衍伸特徵,例如:房間數/家庭數、臥室比例、人口密度。
  • 或是進行特徵篩選,選出重要性較高的特徵
  • 類別型的特徵也需要在這將其轉換為數值型
  • 亦可進一步引入Box-cox轉換來修正特徵的資料分布
X_train = X_train.copy()
X_test = X_test.copy()
X_train["rooms_per_household"] = X_train["AveRooms"] / X_train["HouseAge"]
X_test["rooms_per_household"] = X_test["AveRooms"] / X_test["HouseAge"]

🧪 5. 基準模型(Baseline)

進行模型訓練實驗時,需要先設定一個基準模型,將其當作每次實驗的比較基準,通常會使用較簡單的模型。

from sklearn.dummy import DummyRegressor
from sklearn.metrics import root_mean_squared_error

baseline = DummyRegressor(strategy="mean")
baseline.fit(X_train, y_train)
y_base = baseline.predict(X_test)
print("Baseline RMSE:", root_mean_squared_error(y_test, y_base))
Baseline RMSE: 1.1448563543099792

🧠 6. 模型選擇與 GridSearchCV

選擇不同的模型和參數的設置進行模型選擇實驗,自動讓他搜尋最佳模型與參數,然後印出各種相關資訊。

from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV, KFold
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np

# 假設 RANDOM_STATE 已經定義,如果沒有則設定一個
RANDOM_STATE = 42

pipe = Pipeline([
("scale", StandardScaler()),
("model", LinearRegression())
])

param_grid = [
{"model": [LinearRegression()]},
{"model": [Ridge()], "model__alpha": [0.1, 1.0, 10.0]},
{"model": [RandomForestRegressor(random_state=RANDOM_STATE)],
"model__n_estimators": [100, 300], "model__max_depth": [None, 10, 20]}
]

cv = KFold(5, shuffle=True, random_state=RANDOM_STATE)
grid = GridSearchCV(pipe, param_grid, scoring="neg_root_mean_squared_error", cv=cv, n_jobs=-1)
grid.fit(X_train, y_train)
print("Best CV RMSE:", -grid.best_score_)

# 新增以下部分:列出最佳模型與參數
print("\n" + "="*50)
print("最佳模型詳細資訊")
print("="*50)

# 獲取最佳模型名稱
best_model_name = grid.best_estimator_.named_steps['model'].__class__.__name__
print(f"最佳模型: {best_model_name}")

# 獲取最佳模型參數
best_params = grid.best_params_
print("\n最佳參數:")
for param, value in best_params.items():
if param != "model": # 跳過模型本身的參數
print(f" {param}: {value}")

# 如果想更詳細地了解模型的參數,可以顯示所有參數
print("\n最佳模型的所有參數:")
best_model = grid.best_estimator_.named_steps['model']
model_params = best_model.get_params()
for param, value in model_params.items():
print(f" {param}: {value}")

# 顯示交叉驗證的詳細結果
print("\n" + "="*50)
print("交叉驗證結果詳細資訊")
print("="*50)

# 將CV結果轉換為DataFrame以便查看
cv_results = pd.DataFrame(grid.cv_results_)

# 選擇需要顯示的列
columns_to_display = ['mean_test_score', 'std_test_score', 'rank_test_score', 'params']
cv_results_display = cv_results[columns_to_display]

# 將結果按rank_test_score排序
cv_results_sorted = cv_results_display.sort_values('rank_test_score')

# 轉換negative RMSE為positive RMSE以便理解
cv_results_sorted['mean_test_score'] = -cv_results_sorted['mean_test_score']
cv_results_sorted['std_test_score'] = cv_results_sorted['std_test_score']

# 重命名列以便理解
cv_results_sorted = cv_results_sorted.rename(columns={
'mean_test_score': 'RMSE (mean)',
'std_test_score': 'RMSE (std)',
'rank_test_score': 'Rank'
})

# 顯示前5名模型
print("Top 5 models based on cross-validation:")
pd.set_option('display.max_colwidth', None) # 確保params列顯示完全
print(cv_results_sorted.head(5))

# 顯示最佳模型的測試分數
print("\n" + "="*50)
print("最佳模型在測試集上的表現")
print("="*50)
test_score = -grid.score(X_test, y_test) # 因為是neg_root_mean_squared_error,所以取負值
print(f"Test RMSE: {test_score:.4f}")

# 獲取特徵重要性(如果模型支持)
if hasattr(best_model, 'feature_importances_'):
print("\n" + "="*50)
print("特徵重要性")
print("="*50)
# 假設X_train是DataFrame且有列名
if hasattr(X_train, 'columns'):
feature_names = X_train.columns
else:
feature_names = [f"Feature {i}" for i in range(X_train.shape[1])]

importance = best_model.feature_importances_
features_importance = pd.DataFrame({
'Feature': feature_names,
'Importance': importance
}).sort_values('Importance', ascending=False)

print(features_importance)
Best CV RMSE: 0.5133453106680681

==================================================
最佳模型詳細資訊
==================================================
最佳模型: RandomForestRegressor

最佳參數:
model__max_depth: None
model__n_estimators: 300

最佳模型的所有參數:
bootstrap: True
ccp_alpha: 0.0
criterion: squared_error
max_depth: None
max_features: 1.0
max_leaf_nodes: None
max_samples: None
min_impurity_decrease: 0.0
min_samples_leaf: 1
min_samples_split: 2
min_weight_fraction_leaf: 0.0
monotonic_cst: None
n_estimators: 300
n_jobs: None
oob_score: False
random_state: 42
verbose: 0
warm_start: False

==================================================
交叉驗證結果詳細資訊
==================================================
Top 5 models based on cross-validation:
RMSE (mean) RMSE (std) Rank \
5 0.513345 0.013247 1
9 0.513383 0.013322 2
4 0.515307 0.012697 3
8 0.515626 0.012716 4
7 0.542397 0.013469 5

params
5 {'model': RandomForestRegressor(random_state=42), 'model__max_depth': None, 'model__n_estimators': 300}
9 {'model': RandomForestRegressor(random_state=42), 'model__max_depth': 20, 'model__n_estimators': 300}
4 {'model': RandomForestRegressor(random_state=42), 'model__max_depth': None, 'model__n_estimators': 100}
8 {'model': RandomForestRegressor(random_state=42), 'model__max_depth': 20, 'model__n_estimators': 100}
7 {'model': RandomForestRegressor(random_state=42), 'model__max_depth': 10, 'model__n_estimators': 300}

==================================================
最佳模型在測試集上的表現
==================================================
Test RMSE: 0.5102

==================================================
特徵重要性
==================================================
Feature Importance
0 MedInc 0.524881
5 AveOccup 0.135404
7 Longitude 0.084010
6 Latitude 0.083968
8 rooms_per_household 0.044613
2 AveRooms 0.040032
1 HouseAge 0.029529
4 Population 0.029080
3 AveBedrms 0.028483

📏 7. 模型評估

  • 使用最佳模型來進行模型評估,通常會同時考慮多個評估指標,以多種角度來評估此模型。
  • AIC和BIC也是常用的模型選擇方式
from sklearn.metrics import mean_absolute_error, root_mean_squared_error, r2_score

best_model = grid.best_estimator_
y_pred = best_model.predict(X_test)

print("MAE:", mean_absolute_error(y_test, y_pred))
print("RMSE:", root_mean_squared_error(y_test, y_pred))
print("R²:", r2_score(y_test, y_pred))

plt.scatter(y_test, y_pred, alpha=0.3)
plt.xlabel("True Values")
plt.ylabel("Predictions")
plt.title("Predicted vs Actual House Values")
plt.show()
MAE: 0.3305970771075585
RMSE: 0.5102476192195154
R²: 0.8013195595861359
raw-image

🔍 8. 殘差分析(Residual Analysis)

殘差分析主要檢查兩件事情:

  • 殘差是否呈現常態分布
  • 殘差是否隨機分布在零線的週圍,無明顯模式

詳細內容會在之後的筆記中說明

residuals = y_test - y_pred
sns.histplot(residuals, bins=50)
plt.title("Residual Distribution")
plt.show()

plt.scatter(y_pred, residuals, alpha=0.3)
plt.axhline(0, color="red", linestyle="--")
plt.xlabel("Predictions")
plt.ylabel("Residuals")
plt.title("Residuals vs Predictions")
plt.show()
raw-image
raw-image

📐 9. 特徵重要性(Feature Importance)

特徵重要性是用來篩選特徵以及判斷模型是否訓練正確的一個步驟,常使用的方式除了相關係數、統計檢定和Shapley Value之外,也有些模型內建特徵篩選功能如:Random Forest、Lasso Regression和XGBoost等。

if hasattr(best_model.named_steps['model'], 'feature_importances_'):
importances = best_model.named_steps['model'].feature_importances_
pd.Series(importances, index=X_train.columns).sort_values(ascending=False).plot(kind='bar')
plt.title("Feature Importances")
plt.show()
raw-image

💾 10. 模型保存與載入

模型訓練完之後須要將其儲存起來,後續使用時再載入模型,對新資料進行預測。 要特別注意的是,模型在訓練時進行過的前處理和轉換,對新資料也要做一樣的事情,才可以讓模型預測,這部分就不特別操作了。

import joblib

joblib.dump(best_model, "california_best_model.joblib")
model = joblib.load("california_best_model.joblib")

y_pred = model.predict(X_test)









留言
avatar-img
留言分享你的想法!
avatar-img
Ethan的AI學習筆記
4會員
26內容數
我是一個不務正業的資料科學家,從零開始學習的路途上跌跌撞撞,跌過許多坑,也撞過許多牆... 當有人迷失方向時,希望這些筆記可以成為你的指南針。
Ethan的AI學習筆記的其他內容
2025/07/25
帶著大家簡單地看過整個機器學習流程之後,相信每個人對於機器學習在幹嘛還是很模糊,因此這章節來個實際範例,讓大家更了解在每一個流程中資料科學家究竟都在做什麼。 這裡我使用機器學習中很有名的”鳶尾花”資料集,這部分內容會比較多,希望大家可以跟著我的步驟慢慢地操作,細細地去體驗如何完成一個基本的機器學習
Thumbnail
2025/07/25
帶著大家簡單地看過整個機器學習流程之後,相信每個人對於機器學習在幹嘛還是很模糊,因此這章節來個實際範例,讓大家更了解在每一個流程中資料科學家究竟都在做什麼。 這裡我使用機器學習中很有名的”鳶尾花”資料集,這部分內容會比較多,希望大家可以跟著我的步驟慢慢地操作,細細地去體驗如何完成一個基本的機器學習
Thumbnail
2025/07/19
在這個章節會繼續介紹機器學習後半部的流程,主要也是概念式的說明,每一個小細節在後續的文章中會再單獨拿出來說明。請大家盡量記得文章中每個流程所提到的專有名詞,大概了解每一個步驟在做什麼對於後續的學習很有幫助!
Thumbnail
2025/07/19
在這個章節會繼續介紹機器學習後半部的流程,主要也是概念式的說明,每一個小細節在後續的文章中會再單獨拿出來說明。請大家盡量記得文章中每個流程所提到的專有名詞,大概了解每一個步驟在做什麼對於後續的學習很有幫助!
Thumbnail
2025/07/16
接著會詳細的介紹機器學習的每一個步驟在做什麼,這部分專有名詞會比較多,希望大家可以盡量熟悉。 🙋問題定義 在真正進入機器學習流程之前,需要先定義你想要解決的問題。 如何將你的問題、你的痛點,轉換成機器學習可以執行的任務是你們會遇到的第一個難題,原則上可以遵循以下方法來思考:
Thumbnail
2025/07/16
接著會詳細的介紹機器學習的每一個步驟在做什麼,這部分專有名詞會比較多,希望大家可以盡量熟悉。 🙋問題定義 在真正進入機器學習流程之前,需要先定義你想要解決的問題。 如何將你的問題、你的痛點,轉換成機器學習可以執行的任務是你們會遇到的第一個難題,原則上可以遵循以下方法來思考:
Thumbnail
看更多
你可能也想看
Thumbnail
蝦皮分潤計畫讓我在分享旅遊文章時,也能透過推薦好物累積被動收入,貼補旅行基金。這篇文章,除了介紹計畫的操作亮點與心得,也分享我最常應用的案例:「旅行必備小物 TOP5」,包含行李鎖、免洗內衣褲、分裝瓶、折疊衣架與真空壓縮袋,幫助出國打包更輕鬆。想同時記錄旅行、分享好物又創造額外收入的你,千萬別錯過!
Thumbnail
蝦皮分潤計畫讓我在分享旅遊文章時,也能透過推薦好物累積被動收入,貼補旅行基金。這篇文章,除了介紹計畫的操作亮點與心得,也分享我最常應用的案例:「旅行必備小物 TOP5」,包含行李鎖、免洗內衣褲、分裝瓶、折疊衣架與真空壓縮袋,幫助出國打包更輕鬆。想同時記錄旅行、分享好物又創造額外收入的你,千萬別錯過!
Thumbnail
想增加被動收入?加入蝦皮分潤計畫是輕鬆上手的好方法!本文提供完整教學,包含申請流程、賺取分潤技巧,以及實際使用心得分享,助你輕鬆獲得額外收入。
Thumbnail
想增加被動收入?加入蝦皮分潤計畫是輕鬆上手的好方法!本文提供完整教學,包含申請流程、賺取分潤技巧,以及實際使用心得分享,助你輕鬆獲得額外收入。
Thumbnail
在當今快速變化的數位時代,企業面臨著前所未有的數據處理需求。為了應對這些挑戰,企業紛紛建立自己的大型語言模型(LLM),利用大量數據進行訓練,讓模型能夠理解並生成自然語言,從而實現人機協作,優化業務流程並提升客戶體驗。
Thumbnail
在當今快速變化的數位時代,企業面臨著前所未有的數據處理需求。為了應對這些挑戰,企業紛紛建立自己的大型語言模型(LLM),利用大量數據進行訓練,讓模型能夠理解並生成自然語言,從而實現人機協作,優化業務流程並提升客戶體驗。
Thumbnail
本文介紹了人工智慧(AI)及機器學習(ML)的基本概念和關係,探討了數據在機器學習中的重要性,以及深度學習和生成式人工智慧的應用。
Thumbnail
本文介紹了人工智慧(AI)及機器學習(ML)的基本概念和關係,探討了數據在機器學習中的重要性,以及深度學習和生成式人工智慧的應用。
Thumbnail
在當今快速發展的技術時代,人工智能 Artificial Intelligence 和機器學習 Machine Learning 已成為推動業務創新和增長的重要力量。從改善客戶服務到優化運營流程,AI和ML的應用範圍日益廣泛,為企業創造出前所未有的機會。企業又可如何利用AI和ML提升業務呢?
Thumbnail
在當今快速發展的技術時代,人工智能 Artificial Intelligence 和機器學習 Machine Learning 已成為推動業務創新和增長的重要力量。從改善客戶服務到優化運營流程,AI和ML的應用範圍日益廣泛,為企業創造出前所未有的機會。企業又可如何利用AI和ML提升業務呢?
Thumbnail
本文要探討AI的任務與實戰場景。AI技術已深入生活各層面,從違約預測到都市交通管理。AI任務主要有三類:數值型資料處理、自然語言處理(NLP)和電腦影像辨識。時間序列資料和強化學習方法(如AlphaGo)也引起廣泛關注。AI演算法和方法因應不同學派和技術發展而多樣化,了解這些基礎有助選擇適合研究方向
Thumbnail
本文要探討AI的任務與實戰場景。AI技術已深入生活各層面,從違約預測到都市交通管理。AI任務主要有三類:數值型資料處理、自然語言處理(NLP)和電腦影像辨識。時間序列資料和強化學習方法(如AlphaGo)也引起廣泛關注。AI演算法和方法因應不同學派和技術發展而多樣化,了解這些基礎有助選擇適合研究方向
Thumbnail
本文談及資料科學的領域與分工。首先是建造一個AI的研發流程,資料收集到 AI 模型訓練的過程,AI經歷這一切流程被創造出來並產生價值;再來本文也提及在這個領域中的各種腳色、資料工程師、數據庫工程師、資料科學家和資料分析師的各種介紹。並且強調跨領域合作的重要性。
Thumbnail
本文談及資料科學的領域與分工。首先是建造一個AI的研發流程,資料收集到 AI 模型訓練的過程,AI經歷這一切流程被創造出來並產生價值;再來本文也提及在這個領域中的各種腳色、資料工程師、數據庫工程師、資料科學家和資料分析師的各種介紹。並且強調跨領域合作的重要性。
Thumbnail
最新的AI趨勢讓人眼花撩亂,不知要如何開始學習?本文介紹了作者對AI的使用和體驗,以及各類AI工具以及推薦的選擇。最後強調了AI是一個很好用的工具,可以幫助人們節省時間並提高效率。鼓勵人們保持好奇心,不停止學習,並提出了對健康生活和開心生活的祝福。
Thumbnail
最新的AI趨勢讓人眼花撩亂,不知要如何開始學習?本文介紹了作者對AI的使用和體驗,以及各類AI工具以及推薦的選擇。最後強調了AI是一個很好用的工具,可以幫助人們節省時間並提高效率。鼓勵人們保持好奇心,不停止學習,並提出了對健康生活和開心生活的祝福。
Thumbnail
在當今快速變化的市場環境中,準確預測客戶需求並迅速應對市場動態成為企業成功的關鍵。本文將探討客戶需求預測的重要性、市場動態的迅速變化以及企業如何透過先進技術如人工智慧(AI)和大數據分析來提升市場反應速度和精準度。
Thumbnail
在當今快速變化的市場環境中,準確預測客戶需求並迅速應對市場動態成為企業成功的關鍵。本文將探討客戶需求預測的重要性、市場動態的迅速變化以及企業如何透過先進技術如人工智慧(AI)和大數據分析來提升市場反應速度和精準度。
Thumbnail
誠品生活|科技應用 書櫃陳列著與AI相關軟硬體的科技應用實作材料包,包含物聯網、影像辨識、機器學習、生醫感測等實作套裝材料。 選擇趨勢|科技玩物 這麼多科技應用實作包,怎麼選呢? 科技日新月異 科技玩物在生活中反應的特徵詞: 顛覆、科幻、新奇、便利、酷炫、魔法、未來
Thumbnail
誠品生活|科技應用 書櫃陳列著與AI相關軟硬體的科技應用實作材料包,包含物聯網、影像辨識、機器學習、生醫感測等實作套裝材料。 選擇趨勢|科技玩物 這麼多科技應用實作包,怎麼選呢? 科技日新月異 科技玩物在生活中反應的特徵詞: 顛覆、科幻、新奇、便利、酷炫、魔法、未來
Thumbnail
本文將探討人工智能對生活上的影響和改變,同時,例如規劃時間,安排選擇等等,附上一些建議與推薦工具。 在今天,大語言模型開通全球,我們可以輕易的使用人工智能對話,和他們對話,交流,討論,但是,除了娛樂以外,在生活上,我們還有什麼用法呢?
Thumbnail
本文將探討人工智能對生活上的影響和改變,同時,例如規劃時間,安排選擇等等,附上一些建議與推薦工具。 在今天,大語言模型開通全球,我們可以輕易的使用人工智能對話,和他們對話,交流,討論,但是,除了娛樂以外,在生活上,我們還有什麼用法呢?
Thumbnail
2023年被世人稱做生成式AI世代的元年,各式各樣的AI工具不斷湧現,改變了人們的生活。本文將詳細介紹人工智慧和機器學習的相關知識,以及各種人工智慧和機器學習的實現方法。
Thumbnail
2023年被世人稱做生成式AI世代的元年,各式各樣的AI工具不斷湧現,改變了人們的生活。本文將詳細介紹人工智慧和機器學習的相關知識,以及各種人工智慧和機器學習的實現方法。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News