4D 機器學習-上午

程式碼 一、

import numpy as np            # 匯入 NumPy,用來做矩陣運算
import matplotlib.pyplot as plt      # 匯入 Matplotlib,用來畫圖
from scipy.linalg import expm    # 從 SciPy 匯入 expm,用來計算矩陣指數 e^(Qt)

程式碼 二、

def make_Q(h1, h2, h3, h4, rate_unit="year", target_unit="month"):
    """Build Q-matrix for CTMC"""       # 建立連續時間馬可夫鏈 (CTMC) 的 Q 矩陣
    factor = 1/12.0 if rate_unit == "year" and target_unit == "month" else 1.0  # 如果輸入是「每年率」,要轉換成「每月率」(除以 12),否則維持不變
    h1, h2, h3, h4 = np.array([h1, h2, h3, h4], dtype=float) * factor       # 把輸入 hazard 轉換成浮點數並套用單位換算

    Q = np.zeros((4,4), dtype=float)              # 建立 4x4 的零矩陣
    Q[0,0] = -h1; Q[0,1] =  h1                # 狀態0 (Normal) → 狀態1 (Pre) 的轉移率 h1
    Q[1,0] =  h4; Q[1,1] = -(h2 + h4); Q[1,2] = h2   # 狀態1 可能回到0 (率 h4),或往2 (率 h2),對角線是負的總和
    Q[2,2] = -h3; Q[2,3] =  h3                # 狀態2 (Stage 1) → 狀態3 (Stage 2),率 h3
    return Q                            # 回傳生成的 Q 矩陣

程式碼 三、

def transition_matrix(Q, t):
    """Transition probability matrix P(t) = expm(Q*t)"""   # 計算 P(t)=e^(Qt),即時間 t 的轉移機率矩陣
    return expm(Q * t)

程式碼 四、

def simulate_from_state0(Q, t_grid):
    """Simulate probabilities starting from state 0"""         # 從狀態0 (Normal) 開始模擬隨時間的機率分布
    p0 = np.array([1,0,0,0], dtype=float)                 # 初始機率分布:一開始全部在 Normal 狀態
    return np.vstack([p0 @ transition_matrix(Q, t) for t in t_grid]) # 對每個時間點 t,計算 p0*P(t),堆疊成矩陣

程式碼 五、

# ===== 畫圖 =====
def plot_curves(t_grid, probs):
    labels = ['Normal', 'Pre-hypertension', 'Stage 1 Hypertension', 'Stage 2 Hypertension']  # 狀態標籤
    plt.figure(figsize=(7,4.5))                 # 設定圖表大小
    for i in range(4):
        plt.plot(t_grid, probs[:, i], label=labels[i])  # 畫出每個狀態隨時間的機率曲線
    plt.xlabel('Months')                     # x 軸標籤:月份
    plt.ylabel('Probability')                  # y 軸標籤:機率
    plt.title('Dynamic probabilities starting from Normal BP')  # 圖標題
    plt.legend()                         # 顯示圖例
    plt.grid(True)                        # 顯示格線
    plt.show()                          # 顯示圖表

程式碼 六、

# hazards per year
h1, h2, h3, h4 = 0.5271, 0.3077, 0.2378, 0.4706         # 四個 hazard 值 (每年)

Q = make_Q(h1, h2, h3, h4, rate_unit="year", target_unit="month")  # 建立 Q 矩陣,並將年率轉換成月率
t_grid = np.linspace(0, 120, 241)   # 建立時間網格,從 0 到 120 個月,取 241 個點 (每 0.5 個月一個點)
probs = simulate_from_state0(Q, t_grid)  # 計算從 Normal 狀態開始的機率隨時間變化

# Plot
plot_curves(t_grid, probs)          # 畫出四個狀態的機率曲線

# Show transition matrices
print("P(12 months):\n", np.round(transition_matrix(Q, 12), 2))
print("P(120 months):\n", np.round(transition_matrix(Q, 120), 2))
結果顯示