TÓM TẮT
Giới thiệu
Mô hình harmonic (harmonic model) là một công cụ mạnh mẽ trong phân tích chuỗi thời gian, đặc biệt hữu ích trong việc dự báo, nhận diện mẫu và loại bỏ nhiễu. Khi làm việc với dữ liệu tài chính, khí tượng, y tế hay bất kỳ lĩnh vực nào có xu hướng tuần hoàn, việc hiểu và vẽ mô hình harmonic sẽ giúp bạn khai thác thông tin tiềm ẩn một cách hiệu quả. Bài viết này sẽ cung cấp hướng dẫn chi tiết, từng bước một, từ các khái niệm cơ bản đến các kỹ thuật nâng cao, đồng thời minh họa bằng các ví dụ thực tế và mã nguồn Python để bạn có thể áp dụng ngay.
1. Kiến Thức Cơ Bản Về Harmonic
1.1. Định Nghĩa Harmonic
Trong toán học, harmonic (điệu hài) là một hàm sin hoặc cos có dạng:
y(t) = A \cdot \sin(2\pi f t + \phi)
- A: biên độ (amplitude) – mức độ dao động.
- f: tần số (frequency) – số chu kỳ trên một đơn vị thời gian.
- (\phi): pha (phase) – vị trí bắt đầu của sóng.
Khi kết hợp nhiều harmonic lại, chúng ta có thể mô tả các chuỗi thời gian phức tạp hơn:
y(t) = \sum_{k=1}^{N} A_k \cdot \sin(2\pi f_k t + \phi_k)
1.2. Ứng Dụng Thực Tiễn
- Tài chính: Phân tích xu hướng và chu kỳ trong giá cổ phiếu, ngoại tệ.
- Khoa học khí hậu: Nhận diện các chu kỳ El Niño, La Niña.
- Y học: Phân tích nhịp tim, EEG.
- Kỹ thuật: Phân tích rung động, tín hiệu âm thanh.
2. Chuẩn Bị Dữ Liệu
2.1. Thu Thập Dữ Liệu

Có thể bạn quan tâm: Cách Vẽ Mô Hình Business: Hướng Dẫn Chi Tiết Từ A Đến Z
- Nguồn dữ liệu: CSV, API tài chính (Yahoo Finance, Alpha Vantage), cơ sở dữ liệu thời gian thực.
- Định dạng: Thông thường là một cột thời gian (timestamp) và một cột giá trị (price, temperature, …).
2.2. Tiền Xử Lý
- Xóa bỏ NaN:
python df = df.dropna() - Định dạng thời gian:
python df'date' = pd.to_datetime(df'date') df.set_index('date', inplace=True) - Chuẩn hoá (Normalization) (nếu cần):
python from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() df'value_norm' = scaler.fit_transform(df'value')
2.3. Phân Tích Đặc Trưng
- FFT (Fast Fourier Transform) để xác định các tần số chính.
- Periodogram cho việc hiển thị năng lượng theo tần số.
import numpy as np
from scipy.fft import fft, fftfreq N = len(df)
T = 1.0 # giả sử dữ liệu có khoảng cách thời gian cố định 1 đơn vị
yf = fft(df'value_norm')
xf = fftfreq(N, T):N//2 plt.plot(xf, 2.0/N np.abs(yf0:N//2))
plt.title('Spectrum')
plt.xlabel('Frequency')
plt.ylabel('Amplitude')
plt.show()
3. Xây Dựng Mô Hình Harmonic
3.1. Lựa Chọn Số Harmonic (N)
- Dựa vào đỉnh trong biểu đồ spectrum.
- Số harmonic quá ít → mô hình không đủ mô tả; quá nhiều → overfitting.
3.2. Công Thức Tổng Hợp
\hat{y}(t) = \sum_{k=1}^{N} \big a_k \cos(2\pi f_k t) + b_k \sin(2\pi f_k t) \big
Trong đó (a_k = A_k \cos(\phi_k)) và (b_k = A_k \sin(\phi_k)). Việc chuyển sang dạng cos‑sin giúp việc ước lượng thông qua Linear Regression.
3.3. Tạo Ma trận Thiết Kế (Design Matrix)

Có thể bạn quan tâm: Cách Vẽ Mô Cơ Vân: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
def create_design_matrix(t, freqs): """ t: array of time points freqs: list/array of frequencies (f1, f2, ..., fN) Returns X: matrix with columns cos(2πf1t), sin(2πf1t), ..., cos(2πfN t), sin(2πfN t) """ X = for f in freqs: X.append(np.cos(2np.pift)) X.append(np.sin(2np.pift)) return np.column_stack(X)
3.4. Ước Lượng Tham Số Bằng Linear Regression
from sklearn.linear_model import LinearRegression t = np.arange(len(df))
freqs = 0.01, 0.03, 0.07 # ví dụ: 3 tần số được chọn sau FFT
X = create_design_matrix(t, freqs)
y = df'value_norm'.values model = LinearRegression()
model.fit(X, y)
coeffs = model.coef_
intercept = model.intercept_
3.5. Trích Rút Biên Độ, Tần Số, Pha
A = np.sqrt(coeffs0::22 + coeffs1::22) # amplitude
phi = np.arctan2(coeffs1::2, coeffs0::2) # phase
4. Vẽ Mô Hình Harmonic
4.1. Dự Đoán Giá Trị
y_pred = model.predict(X)
df'harmonic_fit' = y_pred
4.2. Đồ Thị So Sánh
import matplotlib.pyplot as plt plt.figure(figsize=(14,6))
plt.plot(df.index, df'value_norm', label='Original', alpha=0.6)
plt.plot(df.index, df'harmonic_fit', label='Harmonic Model', linewidth=2)
plt.title('So sánh Dữ liệu gốc và Mô hình Harmonic')
plt.xlabel('Thời gian')
plt.ylabel('Giá trị (chuẩn hoá)')
plt.legend()
plt.show()
4.3. Đồ Thị Thành Phần Harmonic Riêng Lẻ
for i, f in enumerate(freqs): Xi = create_design_matrix(t, f) yi = model.predict(Xi) plt.plot(df.index, yi, label=f'Harmonic {i+1} (f={f:.3f})') plt.title('Các thành phần harmonic')
plt.legend()
plt.show()
5. Đánh Giá Mô Hình

Có thể bạn quan tâm: Cách Vẽ Mô Cơ Tim: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
5.1. Các Thước Đo Lỗi
- RMSE (Root Mean Squared Error)
- MAE (Mean Absolute Error)
- R² (Coefficient of Determination)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score rmse = np.sqrt(mean_squared_error(y, y_pred))
mae = mean_absolute_error(y, y_pred)
r2 = r2_score(y, y_pred) print(f'RMSE: {rmse:.4f}, MAE: {mae:.4f}, R²: {r2:.4f}')
5.2. Kiểm Tra Overfitting
- Cross‑validation: chia dữ liệu thành train / test.
- AIC / BIC: tiêu chuẩn thông tin Akaike/Bayesian để chọn số harmonic tối ưu.
import statsmodels.api as sm X2 = sm.add_constant(X) # thêm intercept
model_sm = sm.OLS(y, X2).fit()
print(model_sm.summary())
6. Các Biến Thể Nâng Cao
6.1. Harmonic với Độ Dốc Thời Gian (Time‑Varying Amplitude)
Thay vì cố định A, cho phép A(t) thay đổi dần theo thời gian:
A_k(t) = A_{k0} + \alpha_k t
Bạn có thể mở rộng ma trận thiết kế bằng cách thêm các cột t cos(2πf t) và t sin(2πf t).
6.2. Harmonic và Trend (Xu Hướng)

Có thể bạn quan tâm: Cách Vẽ Mô Biểu Bì: Hướng Dẫn Chi Tiết Từ A Đến Z
Kết hợp polynomial trend:
y(t) = \beta_0 + \beta_1 t + \dots + \beta_m t^m + \sum_{k=1}^{N} \big a_k \cos(2\pi f_k t) + b_k \sin(2\pi f_k t) \big
Thêm các cột t, t^2, … vào design matrix.
6.3. Harmonic với Damping (Giảm biên độ)
y(t) = \sum_{k=1}^{N} A_k e^{-\lambda_k t} \sin(2\pi f_k t + \phi_k)
Đây là mô hình phi‑tuyến tính, thường ước lượng bằng Non‑Linear Least Squares (scipy.optimize.curve_fit).
from scipy.optimize import curve_fit def damped_harmonic(t, params): # params = A1, lambda1, f1, phi1, A2, lambda2, f2, phi2, ... y = np.zeros_like(t, dtype=float) n = len(params)//4 for i in range(n): A = params4i lam = params4i+1 f = params4i+2 phi = params4i+3 y += A np.exp(-lamt) np.sin(2np.pift + phi) return y p0 = 1, 0.01, 0.02, 0, 0.5, 0.02, 0.05, 0 # giá trị khởi tạo
params_opt, _ = curve_fit(damped_harmonic, t, y, p0=p0)
6.4. Harmonic Trong Mô Hình ARIMA‑Harmonic
Khi chuỗi thời gian còn có phần ngẫu nhiên mạnh, bạn có thể:
- Loại bỏ harmonic → nhận phần dư (residual).
- Áp dụng ARIMA lên phần dư để mô hình hoá noise.
from statsmodels.tsa.arima.model import ARIMA residual = y - y_pred
model_arima = ARIMA(residual, order=(2,0,1)).fit()
print(model_arima.summary())
7. Thực Hành: Dự Báo Giá Cổ Phiếu Với Harmonic
7.1. Thu Thập Dữ Liệu
import yfinance as yf ticker = 'AAPL'
data = yf.download(ticker, start='2026-01-01', end='2026-12-31')
close = data'Close'.dropna()
close_norm = scaler.fit_transform(close.values.reshape(-1,1)).flatten()
df_stock = pd.DataFrame({'close_norm': close_norm}, index=close.index)
7.2. Phân Tích Spectrum và Chọn Tần Số
N = len(df_stock)
yf = fft(df_stock'close_norm')
xf = fftfreq(N, 1):N//2 # Lấy 5 tần số có biên độ lớn nhất
indices = np.argsort(np.abs(yf:N//2))-5:
freqs_selected = xfindices
print('Tần số được chọn:', freqs_selected)
7.3. Xây Dựng và Đánh Giá Mô Hình

t = np.arange(N)
X = create_design_matrix(t, freqs_selected)
model = LinearRegression()
model.fit(X, df_stock'close_norm')
pred = model.predict(X) rmse = np.sqrt(mean_squared_error(df_stock'close_norm', pred))
print('RMSE:', rmse)
7.4. Dự Báo 30 Ngày Tiếp Theo
t_future = np.arange(N, N+30)
X_future = create_design_matrix(t_future, freqs_selected)
future_pred = model.predict(X_future) # Đảo chuẩn hoá để trở lại giá gốc
future_price = scaler.inverse_transform(future_pred.reshape(-1,1)).flatten()
future_dates = pd.date_range(start=df_stock.index-1 + pd.Timedelta(days=1), periods=30, freq='B')
future_df = pd.DataFrame({'price_pred': future_price}, index=future_dates) plt.figure(figsize=(12,5))
plt.plot(df_stock.index-200:, scaler.inverse_transform(df_stock'close_norm'-200:.values.reshape(-1,1)), label='Giá thực')
plt.plot(future_df.index, future_df'price_pred', label='Dự báo Harmonic', marker='o')
plt.title('Dự báo giá AAPL 30 ngày tới bằng mô hình Harmonic')
plt.xlabel('Ngày')
plt.ylabel('Giá (USD)')
plt.legend()
plt.show()
Kết quả cho thấy mô hình harmonic có khả năng bắt được các chu kỳ dài hạn (ví dụ: chu kỳ kinh tế, mùa vụ) nhưng cần kết hợp với các mô hình khác để dự báo ngắn hạn chính xác hơn.
8. Lưu Ý Khi Áp Dụng Mô Hình Harmonic
- Dữ liệu cần đủ dài: Để phân tích tần số thấp, cần ít nhất vài vòng lặp của chu kỳ.
- Chu kỳ không ổn định: Nếu tần số thay đổi theo thời gian, mô hình tĩnh sẽ kém hiệu quả → nên dùng Wavelet Transform hoặc Empirical Mode Decomposition (EMD).
- Nhiễu mạnh: Harmonic không thể loại bỏ nhiễu ngẫu nhiên; hãy kết hợp với ARIMA, GARCH, hoặc machine learning.
- Overfitting: Luôn kiểm tra bằng dữ liệu validation và dùng tiêu chuẩn AIC/BIC để quyết định số harmonic.
- Giới hạn tính toán: Khi số harmonic lớn, ma trận thiết kế có thể trở nên vô cùng lớn → dùng Ridge Regression hoặc Lasso để regularize.
9. Kết Luận
Việc vẽ và sử dụng mô hình harmonic không chỉ là một kỹ thuật thống kê đơn giản mà còn là một cách tiếp cận sâu sắc để khám phá những cấu trúc tuần hoàn tiềm ẩn trong dữ liệu thời gian. Từ việc phân tích spectrum, xây dựng ma trận thiết kế, ước lượng tham số cho tới đánh giá mô hình, mỗi bước đều có những công cụ và phương pháp hỗ trợ mạnh mẽ trong Python. Khi được kết hợp khéo léo với các mô hình dự báo khác (ARIMA, GARCH, Machine Learning), harmonic sẽ nâng cao độ chính xác và khả năng giải thích của các dự báo.
Hy vọng bài viết chi tiết trên đã cung cấp cho bạn một lộ trình toàn diện để học, thực hành và triển khai mô hình harmonic trong các dự án thực tế. Hãy bắt đầu thử nghiệm với dữ liệu của mình, điều chỉnh tần số, số harmonic và các biến thể nâng cao để tìm ra mô hình phù hợp nhất. Chúc bạn thành công!
