使用 Colaboratory 和 Kaggle 資料庫學習線性回歸:梯度下降法與 Scikit-learn 實作

更新於 發佈於 閱讀時間約 14 分鐘
學習理論後,重要的是如何用程式碼實現,這一篇文章我會用 Python 練習手刻梯度下降法,上傳自己的檔案練習。中間有發現數據集跑出來的結果跟我想的不一樣,我也分享如何解決(感謝AI)最後再用 Scikit-learn 加上 Matplotlib 視覺畫圖表,期望之後可以在工作使用到。

使用 Colaboratory 練習,使用 AI 工具輔助,並使用 kaggle 開源資料庫練習

Colaboratory

加上程式碼就可以簡單的練習,不需要架設其他的環境。

raw-image


1. 手刻梯度下降法 (Batch Gradient Descent)

假設我們要做 簡單線性回歸。y = ax+b ,數據我先隨機設定。

實際上應用可以用自己的 Excel 或是 CSV,

import numpy as np

# 生成範例資料 (x:輸入特徵, y:實際值)
X = np.array([1, 2, 7.2, 4.3, 6]) # 單一特徵
y = np.array([3, 7, 8, 9, 11]) # 我隨機設定數字做示範

# 初始化參數
theta_0 = 0 # 截距項 (bias)
theta_1 = 0 # 斜率 (weight)
alpha = 0.01 # 學習率
epochs = 1000 # 迭代次數
m = len(X) # 樣本數 X

# 執行梯度下降
for epoch in range(epochs):
# 計算預測值
y_pred = theta_0 + theta_1 * X

# 計算損失函數 (MSE) #**是次方,所以**2是二次方
loss = np.mean((y_pred - y) ** 2)

# 計算梯度 (偏導數)
d_theta_0 = (2/m) * np.sum(y_pred - y) # 對 theta_0 求偏導
d_theta_1 = (2/m) * np.sum((y_pred - y) * X) # 對 theta_1 求偏導

# 更新參數
theta_0 -= alpha * d_theta_0
theta_1 -= alpha * d_theta_1

# 每 100 次輸出一次 loss
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss:.5f}, theta_0: {theta_0:.5f}, theta_1: {theta_1:.5f}")

print(f"最終結果: theta_0 = {theta_0:.5f}, theta_1 = {theta_1:.5f}")

2. 這段程式碼做了什麼?

  1. 初始化參數
    • theta_0 和 theta_1 設為 0,代表模型起點隨機。
    • alpha = 0.01,控制每次參數更新的幅度。
    • epochs = 1000,設定執行 1000 次梯度下降。
  2. 梯度下降步驟
    • 計算預測值--> 計算 MSE 損失函數-->計算梯度 (偏導數)-->更新參數

輸出結果

  • 每 100 次迭代輸出一次 Loss,讓我們觀察模型收斂過程。

最後輸出最終的 theta_0theta_1,得到最佳的線性回歸參數。

raw-image

用 Colaboratory 跑出的結果

Epoch 0, Loss: 44.00000, theta_0: 0.22000, theta_1: 0.66000
Epoch 100, Loss: 0.00313, theta_0: 0.01634, theta_1: 1.98496
Epoch 200, Loss: 0.00000, theta_0: 0.00919, theta_1: 1.99563
...
Epoch 900, Loss: 0.00000, theta_0: 0.00003, theta_1: 1.99999
最終結果: theta_0 = 0.00003, theta_1 = 1.99999

生活上的應用:上傳自己的檔案

  1. 貼上以下程式碼先上傳資料
from google.colab import files
import pandas as pd

# 上傳 CSV 檔案
uploaded = files.upload()

# 讀取 CSV exel 要改成pd.read_excel
df = pd.read_csv(next(iter(uploaded))) # 取得上傳的檔案名稱
print(df.head()) # 顯示前幾筆資料


raw-image


挖 失敗! 出現 NAN

raw-image


NaN"Not a Number" 的縮寫,代表「無效數值」,通常出現在以下情況:

  • 數值運算錯誤

例如 0 、 inf 這種無法計算的數值。

你的 NaN 問題可能來自 Loss 變成 inf 之後發生數值錯誤。

  • 資料有缺失

如果 X 或 y 有 NaN,運算時會導致 NaN 傳播。

但你的 df.dropna() 已經移除 NaN,所以這應該不是主要原因。

  • 數值過大導致溢出 (Overflow)

你的 theta_1 在 Epoch 100 之後變得超大 (10^308 這種等級),導致 Loss 變成 inf,進一步影響計算。

這通常是 學習率 (alpha) 過大,讓梯度下降失控,導致 theta_0 和 theta_1 在幾次迭代後爆炸。

問 ChatGPT 原因:

你的問題應該是 學習率過大,導致 Loss 變成 inf,進而產生 NaN。透過:

  1. 降低學習率 (alpha = 0.0001)
  2. 標準化 Xy
  3. 限制 theta_0theta_1 的範圍

我先說我的嘗試,因為0.0001,Theta_0 結果出現 0 ,有可能是均值接近0,所以可以先嘗試

👉 解決方法

試著先檢查 Xy 的均值:

如果 y_predy 的均值相等,那麼梯度接近 0,theta_0 幾乎不變。

print("X mean:", np.mean(X))
print("y mean:", np.mean(y))

如果 Xy 的均值接近 0,可以嘗試:

  • X 進行標準化,但 不要對 y 標準化
    X = (X - np.mean(X)) / np.std(X)

測試後發現 X meany mean 都非常接近 0 (在 e-17e-16 級別),這表示 X 和 y 已經標準化了

raw-image


因為標準化後的 X 是均值為 0 的對稱分佈,梯度下降在更新 theta_0 時可能變得極小,導致 theta_0 始終維持在 0


為什麼 theta_0 斜率= 0?

如果 X 已標準化 (mean ≈ 0),則:

  • 目標函數的最佳擬合線應該通過 (0, mean(y)),但因為 mean(y) ≈ 0,所以 theta_0 = 0
  • 在梯度更新時,theta_0 的梯度 (d_theta_0) 會接近 0,因此 theta_0 幾乎沒有變化。

這是數學上的結果,不是程式錯誤。


raw-image

在我把 y 標準化的程式碼註解掉就可以看到變化

# 標準化數據
X_mean, X_std = np.mean(X), np.std(X)
y_mean, y_std = np.mean(y), np.std(y)
X = (X - X_mean) / X_std
# 因為我的數據標準化會使截距貼近零,所以暫時不標準化 y = (y - y_mean) / y_std
print("X mean:", np.mean(X))
print("y mean:", np.mean(y))

在公司很常會希望用圖表報告,用 Matplotib 就可以繪製

可視化梯度下降 Matplotlib

用 Matplotlib 繪製梯度下降過程:

我先把這段程式碼貼到我前面的數據庫中

import matplotlib.pyplot as plt

# 繪製數據點 #一般的二維數據就可以跑
plt.scatter(X, y, color='blue', label='Actual data')

# 繪製最終擬合線
y_pred_final = theta_0 + theta_1 * X
plt.plot(X, y_pred_final, color='red', label='Fitted line')

plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.title('Linear Regression using Gradient Descent')
plt.show()
剛好我選的數據集成正比

剛好我選的數據集成正比

試著亂改資料點xD

試著亂改資料點xD

改進:使用 Scikit-Learn

如果不想手刻梯度下降,可以使用 scikit-learn 的其中一個功能 LinearRegression 直接做回歸:

糖尿病資料庫

我用別的數據庫測試 https://scikit-learn.org/stable/datasets/toy_dataset.html

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

# 1. 載入糖尿病數據集
diabetes = datasets.load_diabetes()

# 2. 取出其中一個特徵 (只用 BMI 來預測疾病指數)
X = diabetes.data[:, np.newaxis, 2] # 選擇第3個特徵
y = diabetes.target # 目標變數

# 3. 分割數據集為訓練集和測試集 (80% 訓練, 20% 測試)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 4. 建立並訓練線性回歸模型
model = LinearRegression()
model.fit(X_train, y_train)

# 5. 預測測試數據
y_pred = model.predict(X_test)

# 6. 視覺化結果
plt.scatter(X_test, y_test, color="black", label="Actual Data") # 真實值
plt.plot(X_test, y_pred, color="red", linewidth=2, label="Predicted Line") # 預測直線
plt.xlabel("BMI")
plt.ylabel("Disease Progression")
plt.legend()
plt.show()

# 7. 輸出模型參數
print(f"Intercept (theta_0): {model.intercept_}")
print(f"Slope (theta_1): {model.coef_[0]}")
raw-image

補充說明語法:

X = diabetes.data[:, np.newaxis, 2] # 選擇第3個特徵

[:] 是 Python 中的「切片語法(slicing)」,在這行程式碼裡的作用是選擇所有的列(rows),而 2 則是選擇第 3 個特徵(索引從 0 開始算)。因為我們只做二維的回歸,所以只能其中一個特徵(BMI) 做疾病指數的預測。

  • diabetes.data
    • 這是 scikit-learn 的糖尿病數據集,裡面有年齡、BMI、血壓,格式是 numpy.ndarray,維度為 (442, 10),代表 442 筆資料,每筆資料有 10 個特徵
  • [:, np.newaxis, 2]
    • : → 選取 所有的列(rows),也就是 442 筆資料 全部選取。
    • np.newaxis → 這個會增加一個維度,讓 X 變成 (442, 1) 的 2D 矩陣,而不是原本的 (442,) 1D 陣列。
    • 2 → 取出 索引 2 的特徵(第 3 個特徵)
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
線性回歸是一種預測模型,目標是找到一條最貼近數據點的直線。本文詳細介紹線性回歸的流程,包含收集資料、建立模型、計算誤差、優化模型和測試模型等步驟。重點闡述梯度下降法與損失函數的應用,並解釋學習率的影響、參數更新方式,以及如何透過梯度下降法逐步逼近損失函數的最低點。
本篇筆記介紹非監督式學習的三大類別:分群、關聯分析和降維,並深入說明其概念、演算法和應用場景。包含K-Means分群演算法、Apriori關聯分析演算法、PCA降維技術,以及強化學習的基礎概念。
深入探討監督式學習中的分類預測,涵蓋邏輯回歸、混淆矩陣、模型評估指標 (Accuracy, Precision, Recall, F1 Score)、ROC 曲線、AUC,以及 KNN、SVM 和 Naive Bayes 等分類演算法。還介紹決策樹、Bagging、Boosting 等集成學習方法。
這篇文章提供機器學習和人工智慧的基礎概念,包含監督式學習、非監督式學習、強化學習,以及模型訓練、優化和評估等重要環節。文中也涵蓋了特徵工程、特徵縮放、維度詛咒等關鍵概念,並簡要介紹了正規化、K折交叉驗證等進階技術。
本文回顧向量內積、方向導數與梯度的概念,並以生活化的比喻和數學公式說明它們在微積分和機器學習中的應用,尤其是在梯度下降法中尋找函數最低點的過程。
本文提供微分的基礎概念介紹,包含微分的定義、極限的應用、Power Rule 和 Chain Rule 的說明,以及偏微分的概念。文中包含圖表公式,並以淺顯易懂的方式說明微積分在 AI 模型訓練中的重要性。
線性回歸是一種預測模型,目標是找到一條最貼近數據點的直線。本文詳細介紹線性回歸的流程,包含收集資料、建立模型、計算誤差、優化模型和測試模型等步驟。重點闡述梯度下降法與損失函數的應用,並解釋學習率的影響、參數更新方式,以及如何透過梯度下降法逐步逼近損失函數的最低點。
本篇筆記介紹非監督式學習的三大類別:分群、關聯分析和降維,並深入說明其概念、演算法和應用場景。包含K-Means分群演算法、Apriori關聯分析演算法、PCA降維技術,以及強化學習的基礎概念。
深入探討監督式學習中的分類預測,涵蓋邏輯回歸、混淆矩陣、模型評估指標 (Accuracy, Precision, Recall, F1 Score)、ROC 曲線、AUC,以及 KNN、SVM 和 Naive Bayes 等分類演算法。還介紹決策樹、Bagging、Boosting 等集成學習方法。
這篇文章提供機器學習和人工智慧的基礎概念,包含監督式學習、非監督式學習、強化學習,以及模型訓練、優化和評估等重要環節。文中也涵蓋了特徵工程、特徵縮放、維度詛咒等關鍵概念,並簡要介紹了正規化、K折交叉驗證等進階技術。
本文回顧向量內積、方向導數與梯度的概念,並以生活化的比喻和數學公式說明它們在微積分和機器學習中的應用,尤其是在梯度下降法中尋找函數最低點的過程。
本文提供微分的基礎概念介紹,包含微分的定義、極限的應用、Power Rule 和 Chain Rule 的說明,以及偏微分的概念。文中包含圖表公式,並以淺顯易懂的方式說明微積分在 AI 模型訓練中的重要性。
你可能也想看
Google News 追蹤
在此篇中,我們來拿實務的例子作實戰練習,我們會討論如何在Google Colab的環境下,撈取所有台美股的股票代碼,並獲取相關細節,最後將獲取的資訊存取於SQLite資料庫中。
Thumbnail
在資料分析過程中,透過衡量變數之間的線性或非線性關係,能有效探索數據集,篩選出重要特徵,並進行預測建模。本文介紹瞭如何理解數據、使用相關矩陣找出變數關聯性,以及利用互資訊評估變數之間的依賴程度,幫助資料科學家在建模過程中選擇適當的變數,提升模型效果。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
前言 在閱讀《強化式學習:打造最強 AlphaZero 通用演算法》時,對一些看似基本,但是重要且會影響到之後實作的項目概念有點疑惑,覺得應該查清楚,所以搞懂後記錄下來,寫下這篇文章(應該說是筆記?)。 正文 下面這段程式碼: model = Sequential() model.add
瞭解如何透過Regression實作Classification,使用one-hot vector表示不同的類別,並透過乘上不同的Weight和加上不同的bias來得到三個數值形成向量。同時通過softmax的方式得到最終的y'值,並探討使用Cross-entropy來計算類別的loss。
Thumbnail
最近有新的訂閱者加入, 想趁這個機會再分享一次學習心法與建議給第一次練習的讀者、同學們。 如果你本身已經很熟練演算法,那隨機挑題目練習ok,可以測試觀念是否正確,並且驗證寫code的效率與正確程度。 如果是剛畢業或還在學,以前沒有打過程式競賽。 想開始有系統地增強演算法&資料結構的能力
Thumbnail
這篇文章介紹如何使用Python整理資料成百分比資料以及繪製百分比堆疊直條圖。
Thumbnail
這篇文章以簡單易懂的文字和圖片介紹線性混和效應模型,包含其中的元素和意義。除此之外也透過 R 的實作具體呈現操作時的情況。
在此篇中,我們來拿實務的例子作實戰練習,我們會討論如何在Google Colab的環境下,撈取所有台美股的股票代碼,並獲取相關細節,最後將獲取的資訊存取於SQLite資料庫中。
Thumbnail
在資料分析過程中,透過衡量變數之間的線性或非線性關係,能有效探索數據集,篩選出重要特徵,並進行預測建模。本文介紹瞭如何理解數據、使用相關矩陣找出變數關聯性,以及利用互資訊評估變數之間的依賴程度,幫助資料科學家在建模過程中選擇適當的變數,提升模型效果。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
前言 在閱讀《強化式學習:打造最強 AlphaZero 通用演算法》時,對一些看似基本,但是重要且會影響到之後實作的項目概念有點疑惑,覺得應該查清楚,所以搞懂後記錄下來,寫下這篇文章(應該說是筆記?)。 正文 下面這段程式碼: model = Sequential() model.add
瞭解如何透過Regression實作Classification,使用one-hot vector表示不同的類別,並透過乘上不同的Weight和加上不同的bias來得到三個數值形成向量。同時通過softmax的方式得到最終的y'值,並探討使用Cross-entropy來計算類別的loss。
Thumbnail
最近有新的訂閱者加入, 想趁這個機會再分享一次學習心法與建議給第一次練習的讀者、同學們。 如果你本身已經很熟練演算法,那隨機挑題目練習ok,可以測試觀念是否正確,並且驗證寫code的效率與正確程度。 如果是剛畢業或還在學,以前沒有打過程式競賽。 想開始有系統地增強演算法&資料結構的能力
Thumbnail
這篇文章介紹如何使用Python整理資料成百分比資料以及繪製百分比堆疊直條圖。
Thumbnail
這篇文章以簡單易懂的文字和圖片介紹線性混和效應模型,包含其中的元素和意義。除此之外也透過 R 的實作具體呈現操作時的情況。