從機器學習的角度實現 excel 中趨勢線:揭秘梯度下降過程

1. 引言:Excel 的“一鍵魔法”背后藏著什么智慧?

在 Excel 中,我們只需右鍵 → 添加趨勢線,一條完美的直線就出現了。它快得像魔法,但魔法背后,是數學的嚴謹。

今天,我們不關心 Excel 內部用了什么算法可能是解析法),而是要問:

如果機器一開始‘什么都不知道’,它該怎么一步步‘學會’畫出這條線?


2. 我們的任務:預測一個簡單的線性關系

假設我們有一組數據,它們大致遵循 y = 2x + 1 的規律,但有一些隨機噪聲(模擬真實世界的測量誤差)。

我們的目標:僅憑這10個數據點,讓機器“學會”這個規律,找到最佳的 a(斜率)和 b(截距)


3. 準備數據:10 個“玩具”樣本

我們用 Python 生成這10個數據點:

import numpy as np
import matplotlib.pyplot as plt# 設置隨機種子,保證結果可復現
np.random.seed(42)# 生成 10 個 x 值,從 1 到 10
x = np.arange(1, 11)  # [1, 2, 3, ..., 10]# 生成 y 值:y = 2x + 1 + 噪聲
true_a, true_b = 2, 1
noise = np.random.normal(0, 0.5, size=x.shape)  # 添加標準差為 0.5 的高斯噪聲
y = true_a * x + true_b + noise# 查看數據
print("x:", x)
print("y:", np.round(y, 2))  # 保留兩位小數

輸出

x: [ 1  2  3  4  5  6  7  8  9 10]
y: [ 3.25  4.93  7.32  9.76 10.88 12.88 15.79 17.38 18.77 21.27]

關鍵點:真實規律是 y = 2x + 1,但數據有噪聲,所以 y 值不完全精確。


4. 可視化:我們的目標是什么?

讓我們畫出這些數據點,并標出真實的線(y=2x+1):

plt.figure(figsize=(8, 6))
plt.scatter(x, y, color='blue', label='真實數據點', s=50)
# 畫出真實規律的線
x_line = np.linspace(0, 11, 100)
y_line = true_a * x_line + true_b
plt.plot(x_line, y_line, 'g--', label=f'真實規律 y={true_a}x+{true_b}', linewidth=2)plt.xlabel('x')
plt.ylabel('y')
plt.title('我們的“學習”任務:根據10個數據點,找到最佳擬合線')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()


我們的任務就是:僅從這些藍色散點,讓機器找到一條最接近綠色虛線的直線


5. 模型定義:y_pred = a * x + b

我們假設模型的形式是:

y_pred = a * x + b
  • a:斜率(slope)
  • b:截距(intercept)
  • 初始時,我們不知道?a?和?b?是多少,可以先猜一個值,比如?a=0, b=0

6. 損失函數:我們“錯”了多少?

我們需要一個“尺子”來衡量預測的好壞。用均方誤差 (MSE)

MSE = (1/n) * Σ(y - y_pred)2

代碼實現:

def compute_mse(y_true, y_pred):return np.mean((y_true - y_pred) ** 2)# 初始猜測:a=0, b=0
a, b = 0.0, 0.0
y_pred_initial = a * x + b
initial_loss = compute_mse(y, y_pred_initial)
print(f"初始損失 (a=0, b=0): {initial_loss:.3f}")
初始損失 (a=0, b=0): 182.431

解釋:損失很大,因為 y_pred 全是 0,和真實 y 差很遠。

7. 核心:梯度下降——如何“學習”?

現在,我們教模型如何“學習”:

  • 比喻:你在濃霧中的山坡上,想找到谷底(損失最小的地方)。你看不見路,但能感覺到腳下的坡度(梯度)。你每次都向坡度最陡的下坡方向走一步(更新參數),一步步接近谷底。

  • 數學計算(對 ab 求偏導):

    • ?MSE/?a = (2/n) * Σ((a*x + b - y) * x)
    • ?MSE/?b = (2/n) * Σ(a*x + b - y)
  • 更新規則

    • a = a - learning_rate * ?MSE/?a
    • b = b - learning_rate * ?MSE/?b

8. 動手實現:手動訓練模型
# 超參數
learning_rate = 0.01  # 學習率,步長
epochs = 10000           # 訓練輪數# 初始化參數
a, b = 0.0, 0.0# 記錄歷史,用于畫圖
loss_history = []
a_history = []
b_history = []for i in range(epochs):# 前向:計算預測值y_pred = a * x + b# 計算損失loss = compute_mse(y, y_pred)loss_history.append(loss)a_history.append(a)b_history.append(b)# 計算梯度n = len(x)da = (2 / n) * np.sum((y_pred - y) * x)  # 注意:y_pred - ydb = (2 / n) * np.sum(y_pred - y)# 更新參數a = a - learning_rate * dab = b - learning_rate * db# 打印進度if (i+1) % 1000 == 0:print(f"第 {i+1} 輪: a={a:.3f}, b={b:.3f}, 損失={loss:.3f}")print(f"\n訓練完成!")
print(f"我們的模型找到: a ≈ {a:.3f}, b ≈ {b:.3f}")
print(f"真實規律是: a = {true_a}, b = {true_b}")

輸出

第 100 輪: a=2.054, b=0.840, 損失=0.153
第 200 輪: a=2.021, b=1.070, 損失=0.124
第 300 輪: a=2.007, b=1.168, 損失=0.119
第 400 輪: a=2.001, b=1.211, 損失=0.118
第 500 輪: a=1.999, b=1.229, 損失=0.118
第 600 輪: a=1.997, b=1.237, 損失=0.118
第 700 輪: a=1.997, b=1.240, 損失=0.118
第 800 輪: a=1.997, b=1.242, 損失=0.118
第 900 輪: a=1.997, b=1.243, 損失=0.118
第 1000 輪: a=1.997, b=1.243, 損失=0.118訓練完成!
我們的模型找到: a ≈ 1.997, b ≈ 1.243
真實規律是: a = 2, b = 1

看! 模型通過1000次迭代,a 從 0 逐漸接近 2,b 接近 1,損失不斷下降。


9. 可視化學習過程
  • 損失下降曲線
plt.plot(loss_history)
plt.xlabel('訓練輪數 (Epoch)')
plt.ylabel('損失 (MSE)')
plt.title('損失隨訓練過程下降')
plt.grid(True, alpha=0.3)
plt.show()

  • 參數變化過程
plt.plot(a_history, label='a (斜率)')
plt.plot(b_history, label='b (截距)')
plt.axhline(y=true_a, color='g', linestyle='--', label='真實 a')
plt.axhline(y=true_b, color='r', linestyle='--', label='真實 b')
plt.xlabel('訓練輪數')
plt.ylabel('參數值')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

  • 最終擬合結果
plt.figure(figsize=(8, 6))
plt.scatter(x, y, color='blue', label='真實數據點', s=50)
plt.plot(x_line, y_line, 'g--', label=f'真實規律 y={true_a}x+{true_b}', linewidth=2)
plt.plot(x_line, a * x_line + b, 'r-', label=f'擬合線 y={a:.2f}x+{b:.2f}', linewidth=2)
plt.xlabel('x')
plt.ylabel('y')
plt.title('梯度下降擬合結果')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

  • excel擬合結果
10. 對比專業工具:Scikit-learn

讓我們看看專業的機器學習庫 scikit-learn 是怎么做的:

from sklearn.linear_model import LinearRegression# 注意:sklearn 需要 2D 輸入
X = x.reshape(-1, 1)model = LinearRegression()
model.fit(X, y)print(f"Scikit-learn 結果: 斜率 a = {model.coef_[0]:.3f}, 截距 b = {model.intercept_:.3f}")

輸出

Scikit-learn 結果: 斜率 a = 1.997, 截距 b = 1.243

完全一致! 我們手動實現的梯度下降,和 sklearn 的結果一樣。


附. 深入理解:梯度下降 vs 解析法——殊途同歸的兩種智慧

你可能會問:“我們手動實現的梯度下降,和 scikit-learnLinearRegression,是同一種方法嗎?”

答案是:不是。 它們在求解方式、數學基礎和適用場景上有本質區別。但最終結果一致,是因為它們都在尋找同一個“最優解”。

下面,我們來揭開這個“黑箱”。


一、核心原理:迭代逼近 vs 數學解析
方法核心思想求解方式
手動梯度下降逐步“試錯”,像盲人下山,一步步逼近最優解。迭代法:重復“計算梯度 → 更新參數”直到收斂。
scikit-learn LinearRegression直接用數學公式算出理論最優解,一步到位。解析法(閉式解):通過公式?w = (X?X)?1X?y?直接計算。
1. 手動梯度下降(迭代法)
  • 數學邏輯

    • 定義損失函數(MSE):L(a,b) = \frac{1}{n} \sum_{i=1}^{n} (y_i - (ax_i + b))^2

    • 計算梯度(偏導數):\frac{\partial L}{\partial a} = \frac{2}{n} \sum_{i=1}^{n} (ax_i + b - y_i) x_i\frac{\partial L}{\partial b} = \frac{2}{n} \sum_{i=1}^{n} (ax_i + b - y_i)

    • 更新參數:a = a - \eta \cdot \frac{\partial L}{\partial a}, \quad b = b - \eta \cdot \frac{\partial L}{\partial b}? ? ?(η?為學習率)

  • 特點

    • 近似解:需要足夠迭代才能接近最優。

    • 適用于大數據:可分批處理(如隨機梯度下降)。

    • 需調參:學習率、迭代次數等。

2. scikit-learn LinearRegression(解析法)
  • 數學邏輯

    • 將問題表示為矩陣形式:\mathbf{y} = \mathbf{X}\mathbf{w} + \boldsymbol{\epsilon}

    • 最優參數?ww?的閉式解為:\mathbf{w} = (\mathbf{X}^T \mathbf{X})^{-1} \mathbf{X}^T \mathbf{y}
      這個公式是通過對損失函數求導并令其為 0 推導出的理論最優解

  • 特點

    • 精確解:無需迭代,一步到位。

    • 計算復雜度高:矩陣求逆的復雜度為?O(n3)O(n3),特征數多時很慢。

    • 無超參數:直接計算,無需調學習率。


二、關鍵差異對比
維度梯度下降(迭代法)LinearRegression(解析法)
求解方式逐步迭代逼近直接公式計算
結果性質近似解(可無限接近)理論最優解
計算效率大數據更高效特征多時慢
超參數依賴需調學習率、迭代次數無超參數
適用場景大數據、高維(如深度學習)小數據、低維(如本例)
數值穩定性受學習率影響受多重共線性影響

三、為什么結果能一致?—— 殊途同歸

盡管方法不同,但我們的手動實現和 sklearn 結果幾乎一致,原因在于:

梯度下降的迭代過程,本質上是在數學上“收斂于”解析法的最優解。

就像用牛頓法求方程的根:雖然是迭代過程,但最終會無限接近理論上的精確解。

在本例中,由于數據量小、特征少,解析法高效且精確。而梯度下降通過300次迭代,也成功逼近了這個最優解。


四、通俗類比
  • 梯度下降:像盲人下山,通過感受坡度,一步步向下走,最終到達谷底,適用于復雜、大規模問題,是深度學習的基石。
  • 解析法:像使用 GPS,直接定位谷底坐標,一步到位,適用于簡單、小規模問題,高效精確。

兩種方法最終會到達同一個“山底”,只是路徑和效率不同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95628.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95628.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95628.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于上拉電阻

上拉電阻的作用:輔助浮空狀態輸出高電平 其實就是確定這根線的電平,不能讓他處于一種未知的狀態。 其次也可以起到限制電流的作用,防止損壞原件 那么上拉電阻如何取值? 首先來看一下驅動能力。 因為線上是一定有寄生電容的&am…

PiscCode構建Mediapipe 手勢識別“剪刀石頭布”小游戲

在計算機視覺與人機交互領域,手勢識別是一個非常有趣的應用場景。本文將帶你用 Mediapipe 和 Python 實現一個基于攝像頭的手勢識別“剪刀石頭布”小游戲,并展示實時手勢與游戲結果。 1. 項目概述 該小游戲能夠實現: 實時檢測手勢&#xff0…

【VoNR】VoNR 不等于 VoLTE on 5G

博主未授權任何人或組織機構轉載博主任何原創文章,感謝各位對原創的支持! 博主鏈接 本人就職于國際知名終端廠商,負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作,目前牽頭6G技術研究。 博客內容主要圍繞…

計算機網絡:網絡設備在OSI七層模型中的工作層次和傳輸協議

OSI七層模型(物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層)中,不同網絡設備因功能不同,工作在不同層次。以下是典型網絡設備的工作層次及核心功能:1. 物理層(第1層) 核心功能&a…

RSA-e和phi不互素

1.題目import gmpy2 import libnum p 1656713884642828937525841253265560295123546793973683682208576533764344166170780019002774068042673556637515136828403375582169041170690082676778939857272304925933251736030429644277439899845034340194709105071151095131704526…

基于單片機蒸汽壓力檢測/蒸汽余熱回收

傳送門 👉👉👉👉單片機作品題目速選一覽表🚀 👉👉👉👉單片機作品題目功能速覽🚀 🔥更多文章戳👉小新單片機-CSDN博客&#x1f68…

https 協議與 wss 協議有什么不同

HTTPS 是用于網頁數據傳輸的安全協議,而 WSS 是用于實時雙向通信(如聊天、直播)的安全協議,二者的設計目標、應用場景、底層邏輯均存在本質區別。以下從 7 個核心維度展開對比,并補充關鍵關聯知識,幫助徹底…

主流分布式數據庫集群選型指南

以下是關于主流分布式可擴展數據庫集群的詳細解析,涵蓋技術分類、代表產品及適用場景,幫助您高效選型:一、分布式數據庫核心分類 1. NewSQL 數據庫(強一致性 分布式事務)產品開發方核心特性適用場景TiDBPingCAPHTAP架…

#T1359. 圍成面積

題目描述編程計算由“*”號圍成的下列圖形的面積。面積計算方法是統計*號所圍成的閉合曲線中水平線和垂直線交點的數目。如下圖所示,在1010的二維數組中,有“*”圍住了15個點,因此面積為15。輸入1010的圖形。輸出輸出面積。樣例輸入數據 10 0…

Hive on Tez/Spark 執行引擎對比與優化

在大數據開發中,Hive 已經成為最常用的數據倉庫工具之一。隨著業務數據規模的不斷擴大,Hive 默認的 MapReduce 執行引擎 顯得笨重低效。為了提升查詢性能,Hive 支持了 Tez 和 Spark 作為底層執行引擎。本文將帶你對比 Hive on Tez 與 Hive on Spark 的區別,并分享調優經驗。…

深入理解 Next.js 的路由機制

深入理解 Next.js 的路由機制 作者:碼力無邊在上一篇文章中,我們成功創建并運行了第一個 Next.js 應用。當你打開項目文件夾時,你可能會注意到一個名為 pages 的目錄。這個目錄看似普通,但它卻是 Next.js 路由系統的核心。今天&am…

modbus_tcp和modbus_rtu對比移植AT-socket,modbus_tcp雜記

modbus_rtu通信時沒有連接過程&#xff0c;主機和從機各自初始化自身串口就行了&#xff0c;而rtu需要確定從機ID。注:在TCP連接中&#xff0c;不同的網卡有不同的IP&#xff0c;port對應具體的程序。/* 先讀取數據 */for (i 0; i < len; i){if (pdPASS ! xQueueReceive(re…

Docker Compose 詳解:從安裝到使用的完整指南

在現代容器化應用開發中&#xff0c;Docker Compose 是一個不可或缺的工具&#xff0c;它能夠幫助我們輕松定義和運行多容器的 Docker 應用程序。 一、什么是 Docker Compose&#xff1f; Docker Compose 是 Docker 官方提供的一個工具&#xff0c;用于定義和運行多容器 Dock…

springboot配置多數據源(mysql、hive)

MyBatis-Plus 不能也不建議同時去“控制” Hive。它從設計到實現都假定底層是 支持事務、支持標準 SQL 方言 的 關系型數據庫&#xff08;MySQL、PostgreSQL、Oracle、SQL Server 等&#xff09;&#xff0c;而 Hive 兩者都不完全符合。如果操作兩個數據源都是mysql或者和關系數…

2025年上海市星光計劃第十一屆職業院校技能大賽高職組“信息安全管理與評估”賽項交換部分前6題詳解(僅供參考)

1.北京總公司和南京分公司有兩條裸纖采用了骨干鏈路配置,做必要的配置,只允許必要的Vlan 通過,不允許其他 Vlan 信息通過包含 Vlan1,禁止使用 trunk鏈路。 骨干鏈路位置??:總公司 SW 與分公司 AC 之間的兩條物理鏈路(Ethernet 1/0/5-6 必要 VLAN??: ?總公司:Vlan…

學習nginx location ~ .*.(js|css)?$語法規則

引言 nginx作為一款高性能的Web服務和反向代理服務&#xff0c;在網站性能優化中扮演著重要的角色。其中&#xff0c;location指令的正確配置是優化工作的關鍵之一。 這篇記錄主要解析location ~ .*\.(js|css)?$這一特定的語法規則&#xff0c;幫助大家理解其在nginx配置中的…

Nmap網絡掃描工具詳細使用教程

目錄 Nmap 主要功能 網絡存活主機發現 (ARP Ping Scan) 綜合信息收集掃描 (Stealth SYN Service OS) 全端口掃描 (Full Port Scan) NSE 漏洞腳本掃描 SMB 信息枚舉 HTTP 服務深度枚舉 SSH 安全審計 隱蔽掃描與防火墻規避 Nmap 主要功能 Nmap 主要有以下幾個核心功能…

Spring Boot 3.x 的 @EnableAsync應用實例

語法結構使用 EnableAsync 其實就像為你的應用穿上一件時尚的外套&#xff0c;簡單又高效&#xff01;只需在你的配置類上添加這個注解&#xff0c;輕松開啟異步之旅。代碼如下&#xff1a;想象一下&#xff0c;你的應用一瞬間變得靈活無比&#xff0c;像一個跳舞的機器人&…

Nginx Tomcat Jar包開機啟動自動配置

一、Nginx配置1、創建systemd nginx 服務文件vi /usr/lib/systemd/system/nginx.service### 內容[Unit] DescriptionThe nginx HTTP and reverse proxy server Afternetwork.target[Service] Typeforking ExecStartPre/mnt/nginx/sbin/nginx -t ExecStart/mnt/nginx/sbin/nginx…

修訂版!Uniapp從Vue3編譯到安卓環境踩坑記錄

Uniapp從Vue3編譯到安卓環境踩坑記錄 在使用Uniapp開發Vue3項目并編譯到安卓環境時&#xff0c;我遇到了不少問題&#xff0c;現將主要踩坑點及解決方案整理如下&#xff0c;供大家參考。 1. 動態導入與靜態導入問題 問題描述&#xff1a; 在Vue3項目中使用的動態導入語法在Uni…