第 5 篇:初試牛刀 - 簡單的預測方法

第 5 篇:初試牛刀 - 簡單的預測方法

經過前面四篇的學習,我們已經具備了處理時間序列數據的基本功:加載、可視化、分解以及處理平穩性。現在,激動人心的時刻到來了——我們要開始嘗試預測 (Forecasting) 未來!

預測是時間序列分析最核心的應用之一。雖然存在很多復雜的預測模型,但萬丈高樓平地起,一些看似簡單的預測方法不僅容易理解和實現,有時效果還出奇地好,并且它們是理解更高級模型的重要基礎。

本篇,我們將學習幾種“入門級”的時間序列預測方法:

  1. 預測的基本概念: 區分訓練與預測,劃分數據集。
  2. 樸素預測 (Naive Forecast): 最簡單的方法。
  3. 簡單平均法 (Simple Average): 用歷史平均值預測。
  4. 移動平均法 (Moving Average): 用近期歷史平均值預測。
  5. (可選) 季節性樸素預測 (Seasonal Naive Forecast): 考慮季節性的樸素方法。

我們將用 Python 實現這些方法,并看看它們的預測效果如何。

預測的基本概念

在進行預測之前,我們需要明確兩個基本概念:

  • 擬合 (In-sample Fit) vs. 預測 (Out-of-sample Forecast):

    • 擬合: 使用模型去“解釋”或“匹配”我們已經擁有的歷史數據。
    • 預測: 使用模型去推斷我們尚未觀測到未來數據點。這才是我們通常意義上的“預測”。
  • 訓練集 (Training Set) vs. 測試集 (Test Set):

    • 為了評估模型的真實預測能力,我們不能用全部歷史數據來構建模型,然后又用這些數據來評估。這就像考試前知道了所有答案。

    • 標準的做法是:將歷史數據劃分為兩部分:

      • 訓練集: 用于構建(或“訓練”)我們的預測模型。模型只能看到這部分數據。
      • 測試集: 用于評估模型的預測效果。模型在訓練階段看不到這部分數據。我們將模型的預測結果與測試集的真實值進行比較。
    • 對于時間序列,通常是按時間順序劃分,較早的數據作為訓練集,較晚的數據作為測試集。例如,用前 80% 的數據訓練,后 20% 的數據測試。

最簡單的預測模型

現在,讓我們來認識幾位簡單但重要的“預測選手”。我們將繼續使用之前的月度 CO2 數據(或你可以替換成自己的數據)。

import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
import seaborn as sns# --- 數據準備 ---
# 1. 加載數據
data = sm.datasets.co2.load_pandas().data
data['co2'].interpolate(inplace=True)
monthly_data = data.resample('M').mean()# 2. 劃分訓練集和測試集 (例如,最后 2 年作為測試集)
train_data = monthly_data[:-24] # 除去最后 24 個月
test_data = monthly_data[-24:]  # 最后 24 個月print(f"訓練集范圍: {train_data.index.min()} to {train_data.index.max()}")
print(f"測試集范圍: {test_data.index.min()} to {test_data.index.max()}")# --- 可視化劃分結果 (可選) ---
plt.figure(figsize=(12, 6))
plt.plot(train_data.index, train_data['co2'], label='Train Data')
plt.plot(test_data.index, test_data['co2'], label='Test Data (Actual)')
plt.title('CO2 Data: Train/Test Split')
plt.xlabel('Date')
plt.ylabel('CO2 Concentration')
plt.legend()
plt.show()

在這里插入圖片描述
在這里插入圖片描述

1. 樸素預測 (Naive Forecast)

  • 邏輯: 假設未來跟現在(最近的已知值)一樣。預測下一期的值就等于訓練集中最后一期的實際值。
    • ?(t+1) = Y(t_last_train)
  • 優點: 極其簡單,無需參數,是一個重要的基準 (Baseline) 模型(任何更復雜的模型都應該比它做得更好才有意義)。
  • 缺點: 無法捕捉趨勢和季節性,對波動敏感。
  • 實現:
# 獲取訓練集最后一個值
last_train_value = train_data['co2'].iloc[-1]# 創建測試集長度的預測值,所有值都等于 last_train_value
naive_forecast = pd.Series([last_train_value] * len(test_data), index=test_data.index)print("\n樸素預測 (Naive Forecast):")
print(naive_forecast.head())

在這里插入圖片描述

2. 簡單平均法 (Simple Average)

  • 邏輯: 假設未來會和歷史的平均水平一樣。預測未來所有期的值都等于訓練集中所有數據的平均值
    • ?(t+k) = mean(Y_train) for all k > 0
  • 優點: 簡單,考慮了所有歷史信息。
  • 缺點: 忽略了時間序列的演變(趨勢、季節性),對早期數據和近期數據給予同等權重。如果序列有明顯趨勢,效果通常很差。
  • 實現:
# 計算訓練集平均值
train_mean = train_data['co2'].mean()# 創建測試集長度的預測值,所有值都等于 train_mean
simple_avg_forecast = pd.Series([train_mean] * len(test_data), index=test_data.index)print("\n簡單平均法預測 (Simple Average Forecast):")
print(simple_avg_forecast.head())

在這里插入圖片描述

3. 移動平均法 (Moving Average)

  • 邏輯: 只考慮最近的一段歷史。預測下一期的值等于訓練集中最近 N 個數據點的平均值。N 是需要我們指定的窗口大小 (Window Size)
    • ?(t+1) = mean(Y(t), Y(t-1), ..., Y(t-N+1))
  • 優點: 比簡單平均法更關注近期變化,能一定程度平滑短期波動。
  • 缺點: 無法很好地處理趨勢和季節性。預測值對窗口大小 N 很敏感。它本質上是對近期水平的估計,不是趨勢預測。嚴格來說,移動平均更多用于平滑數據或作為更復雜模型的組件,直接用于多步預測效果有限(通常只預測一步,或者假設未來多步都等于這個平均值)。
  • 實現 (預測未來所有期都等于最后窗口的平均值):
# 設置移動平均窗口大小 (例如,最近 12 個月)
window_size = 12# 計算訓練集最后 N 個點的平均值
moving_avg = train_data['co2'].iloc[-window_size:].mean()# 創建測試集長度的預測值
moving_avg_forecast = pd.Series([moving_avg] * len(test_data), index=test_data.index)print(f"\n移動平均法預測 (Moving Average Forecast, N={window_size}):")
print(moving_avg_forecast.head())

在這里插入圖片描述

4. (可選) 季節性樸素預測 (Seasonal Naive Forecast)

  • 邏輯: 假設下個季節/周期的同一時間點會和上個季節/周期一樣。例如,預測明年 1 月的值等于今年 1 月的值。
    • ?(t+k) = Y(t+k-s),其中 s 是季節周期長度 (e.g., 12 for monthly data with annual seasonality)。
  • 優點: 考慮了季節性,對于有強季節性模式的數據可能效果不錯。也是一個重要的基準。
  • 缺點: 忽略了趨勢和其他變化。
  • 實現 (需要訪問訓練集中更早的數據):
# 季節周期
seasonality = 12seasonal_naive_forecast_list = []
for i in range(len(test_data)):if i >= seasonality:# 使用測試集前一個季節周期的預測值seasonal_value = test_data['co2'].iloc[i - seasonality]else:# 不足一個周期,用訓練集最后一個完整周期前的值seasonal_value = train_data['co2'].iloc[-seasonality + i]seasonal_naive_forecast_list.append(seasonal_value)seasonal_naive_forecast = pd.Series(seasonal_naive_forecast_list, index=test_data.index)print("\n季節性樸素預測 (Seasonal Naive Forecast):")
print(seasonal_naive_forecast.head())

在這里插入圖片描述

可視化預測結果

光看數字不夠直觀,讓我們把預測結果和測試集的真實值畫在一起比較一下。

plt.figure(figsize=(14, 8))# 繪制訓練數據
plt.plot(train_data.index, train_data['co2'], label='Train Data')# 繪制測試數據 (真實值)
plt.plot(test_data.index, test_data['co2'], label='Test Data (Actual)', color='black', linewidth=2)# 繪制各種預測結果
plt.plot(test_data.index, naive_forecast, label='Naive Forecast', linestyle='--')
plt.plot(test_data.index, simple_avg_forecast, label='Simple Average Forecast', linestyle='--')
plt.plot(test_data.index, moving_avg_forecast, label=f'Moving Average (N={window_size}) Forecast', linestyle='--')
plt.plot(test_data.index, seasonal_naive_forecast, label='Seasonal Naive Forecast', linestyle='--')# 添加標題和標簽
plt.title('Comparison of Simple Forecast Methods')
plt.xlabel('Date')
plt.ylabel('CO2 Concentration')
plt.legend()
plt.tight_layout()
plt.show()

在這里插入圖片描述

解讀圖形:

  • 觀察每種預測方法(虛線)與測試集真實值(黑色實線)的接近程度。
  • 對于 CO2 數據(有明顯趨勢和季節性):
    • 樸素預測簡單平均 顯然跟不上趨勢,預測線是平的。
    • 移動平均 (N=12) 也基本是平的,因為它只是最后12個月的平均,沒有預測趨勢。
    • 季節性樸素預測 捕捉到了季節波動,但沒有捕捉到整體上升的趨勢。
  • 這表明,對于具有明顯趨勢和/或季節性的數據,這些簡單方法可能不足以做出準確預測。它們更多是作為后續更復雜模型的比較基準

小結

今天我們邁出了預測的第一步:

  • 理解了預測的目標是推斷未來值,以及訓練集/測試集劃分的重要性。
  • 學習并實現了四種簡單的預測方法:
    • 樸素預測 (Naive): ?(t+1) = Y(t)
    • 簡單平均法 (Simple Average): ?(t+k) = mean(Y_train)
    • 移動平均法 (Moving Average): ?(t+1) = mean(Y(t), ..., Y(t-N+1))
    • 季節性樸素預測 (Seasonal Naive): ?(t+k) = Y(t+k-s)
  • 通過可視化比較了這些方法在測試集上的表現,并認識到它們作為基準模型的價值。

下一篇預告

我們已經做出了幾種預測,但是怎么量化地評價哪個預測“更好”呢?光靠看圖是不夠嚴謹的。下一篇,我們將學習常用的預測評估指標 (Evaluation Metrics),如 MAE, MSE, RMSE 等,它們將幫助我們用數字來衡量預測的準確性。

準備好給你的預測打分了嗎?敬請期待!


(嘗試用你自己的時間序列數據跑一遍這些簡單預測方法,看看哪個效果相對最好?窗口大小 N 對移動平均預測影響大嗎?歡迎分享!)

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

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

相關文章

從代碼學習深度學習 - 學習率調度器 PyTorch 版

文章目錄 前言一、理論背景二、代碼解析2.1. 基本問題和環境設置2.2. 訓練函數2.3. 無學習率調度器實驗2.4. SquareRootScheduler 實驗2.5. FactorScheduler 實驗2.6. MultiFactorScheduler 實驗2.7. CosineScheduler 實驗2.8. 帶預熱的 CosineScheduler 實驗三、結果對比與分析…

k8s 基礎入門篇之開啟 firewalld

前面在部署k8s時,都是直接關閉的防火墻。由于生產環境需要開啟防火墻,只能放行一些特定的端口, 簡單記錄一下過程。 1. firewall 與 iptables 的關系 1.1 防火墻(Firewall) 定義: 防火墻是網絡安全系統&…

RSS 2025|蘇黎世提出「LLM-MPC混合架構」增強自動駕駛,推理速度提升10.5倍!

論文題目:Enhancing Autonomous Driving Systems with On-Board Deployed Large Language Models 論文作者:Nicolas Baumann,Cheng Hu,Paviththiren Sivasothilingam,Haotong Qin,Lei Xie,Miche…

list的學習

list的介紹 list文檔的介紹 list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。list的底層是雙向鏈表結構,雙向鏈表中每個元素存儲在互不相關的獨立節點中,在節點中通過指針指向其前一個元素和后一…

生物信息學技能樹(Bioinformatics)與學習路徑

李升偉 整理 生物信息學是一門跨學科領域,涉及生物學、計算機科學以及統計學等多個方面。以下是關于生物信息學的學習路徑及相關技能的詳細介紹。 一、基礎理論知識 1. 生物學基礎知識 需要掌握分子生物學、遺傳學、細胞生物學等相關概念。 對基因組結構、蛋白質…

AOSP Android14 Launcher3——遠程窗口動畫關鍵類SurfaceControl詳解

在 Launcher3 執行涉及其他應用窗口(即“遠程窗口”)的動畫時,例如“點擊桌面圖標啟動應用”或“從應用上滑回到桌面”的過渡動畫,SurfaceControl 扮演著至關重要的角色。它是實現這些跨進程、高性能、精確定制動畫的核心技術。 …

超詳細實現單鏈表的基礎增刪改查——基于C語言實現

文章目錄 1、鏈表的概念與分類1.1 鏈表的概念1.2 鏈表的分類 2、單鏈表的結構和定義2.1 單鏈表的結構2.2 單鏈表的定義 3、單鏈表的實現3.1 創建新節點3.2 頭插和尾插的實現3.3 頭刪和尾刪的實現3.4 鏈表的查找3.5 指定位置之前和之后插入數據3.6 刪除指定位置的數據和刪除指定…

17.整體代碼講解

從入門AI到手寫Transformer-17.整體代碼講解 17.整體代碼講解代碼 整理自視頻 老袁不說話 。 17.整體代碼講解 代碼 import collectionsimport math import torch from torch import nn import os import time import numpy as np from matplotlib import pyplot as plt fro…

前端性能優化:所有權轉移

前端性能優化:所有權轉移 在學習rust過程中,學到了所有權概念,于是便聯想到了前端,前端是否有相關內容,于是進行了一些實驗,并整理了這些內容。 所有權轉移(Transfer of Ownership)…

Missashe考研日記-day23

Missashe考研日記-day23 0 寫在前面 博主前幾天有事回家去了,斷更幾天了不好意思,就當回家休息一下調整一下狀態了,今天接著開始更新。雖然每天的博客寫的內容不算多,但其實還是挺費時間的,比如這篇就花了我40多分鐘…

Docker 中將文件映射到 Linux 宿主機

在 Docker 中,有多種方式可以將文件映射到 Linux 宿主機,以下是常見的幾種方法: 使用-v參數? 基本語法:docker run -v [宿主機文件路徑]:[容器內文件路徑] 容器名稱? 示例:docker run -it -v /home/user/myfile.txt:…

HarmonyOS-ArkUI-動畫分類簡介

本文的目的是,了解一下HarmonyOS動畫體系中的分類。有個大致的了解即可。 動效與動畫簡介 動畫,是客戶端提升界面交互用戶體驗的一個重要的方式。可以使應用程序更加生動靈越,提高用戶體驗。 HarmonyOS對于界面的交互方面,圍繞回歸本源的設計理念,打造自然,流暢品質一提…

C++如何處理多線程環境下的異常?如何確保資源在異常情況下也能正確釋放

多線程編程的基本概念與挑戰 多線程編程的核心思想是將程序的執行劃分為多個并行運行的線程,每個線程可以獨立處理任務,從而充分利用多核處理器的性能優勢。在C中,開發者可以通過std::thread創建線程,并使用同步原語如std::mutex、…

區間選點詳解

步驟 operator< 的作用在 C 中&#xff0c; operator< 是一個運算符重載函數&#xff0c;它定義了如何比較兩個對象的大小。在 std::sort 函數中&#xff0c;它會用到這個比較函數來決定排序的順序。 在 sort 中&#xff0c;默認會使用 < 運算符來比較兩個對象…

前端配置代理解決發送cookie問題

場景&#xff1a; 在開發任務管理系統時&#xff0c;我遇到了一個典型的身份認證問題&#xff1a;??用戶登錄成功后&#xff0c;調獲取當前用戶信息接口卻提示"用戶未登錄"??。系統核心流程如下&#xff1a; ??用戶登錄??&#xff1a;調用 /login 接口&…

8.1 線性變換的思想

一、線性變換的概念 當一個矩陣 A A A 乘一個向量 v \boldsymbol v v 時&#xff0c;它將 v \boldsymbol v v “變換” 成另一個向量 A v A\boldsymbol v Av. 輸入 v \boldsymbol v v&#xff0c;輸出 T ( v ) A v T(\boldsymbol v)A\boldsymbol v T(v)Av. 變換 T T T…

【java實現+4種變體完整例子】排序算法中【冒泡排序】的詳細解析,包含基礎實現、常見變體的完整代碼示例,以及各變體的對比表格

以下是冒泡排序的詳細解析&#xff0c;包含基礎實現、常見變體的完整代碼示例&#xff0c;以及各變體的對比表格&#xff1a; 一、冒泡排序基礎實現 原理 通過重復遍歷數組&#xff0c;比較相鄰元素并交換逆序對&#xff0c;逐步將最大值“冒泡”到數組末尾。 代碼示例 pu…

系統架構設計(二):基于架構的軟件設計方法ABSD

“基于架構的軟件設計方法”&#xff08;Architecture-Based Software Design, ABSD&#xff09;是一種通過從軟件架構層面出發指導詳細設計的系統化方法。它旨在橋接架構設計與詳細設計之間的鴻溝&#xff0c;確保系統的高層結構能夠有效指導后續開發。 ABSD 的核心思想 ABS…

Office文件內容提取 | 獲取Word文件內容 |Javascript提取PDF文字內容 |PPT文檔文字內容提取

關于Office系列文件文字內容的提取 本文主要通過接口的方式獲取Office文件和PDF、OFD文件的文字內容。適用于需要獲取Word、OFD、PDF、PPT等文件內容的提取實現。例如在線文字統計以及論文文字內容的提取。 一、提取Word及WPS文檔的文字內容。 支持以下文件格式&#xff1a; …

Cesium學習筆記——dem/tif地形的分塊與加載

前言 在Cesium的學習中&#xff0c;學會讀文檔十分重要&#xff01;&#xff01;&#xff01;在這里附上Cesium中英文文檔1.117。 在Cesium項目中&#xff0c;在平坦坦地球中加入三維地形不僅可以增強真實感與可視化效果&#xff0c;還可以??提升用戶體驗與交互性&#xff0c…