Python中多变量Kalman Filter预测股票收盘价报错排查
问题:卡尔曼滤波器多变量预测收盘价时维度不匹配错误
尝试用Open、Low、High、Volume、Close五个变量作为输入,通过卡尔曼滤波器预测股票收盘价(Close),但运行代码时出现错误:The shape of all parameters is not consistent. Please re-check their values.。需求明确:不需要基于每个变量生成五个预测值,而是基于全部五个变量得到一个收盘价预测值。
原代码
import numpy as np import yfinance as yf from pykalman import KalmanFilter spy_data = yf.download('SPY', start='2010-01-01', end='2023-03-17') price = spy_data['Close'].values.reshape(-1, 1) open_price = spy_data['Open'].values.reshape(-1, 1) low_price = spy_data['Low'].values.reshape(-1, 1) high_price = spy_data['High'].values.reshape(-1, 1) volume = spy_data['Volume'].values.reshape(-1, 1) initial_state = np.zeros(5) initial_covariance = np.diag([100, 100, 100, 100, 100]) transition_matrix = np.array([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]) observation_matrix = np.array([[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]) process_noise = np.diag([0.001, 0.001, 0.001, 0.001, 0.001]) observation_noise = np.diag([0.1]) kf = KalmanFilter( initial_state_mean=initial_state, initial_state_covariance=initial_covariance, transition_matrices=transition_matrix, observation_matrices=observation_matrix, observation_covariance=observation_noise, transition_covariance=process_noise) state_means, state_covariances = kf.filter(np.hstack([price, open_price, low_price, high_price, volume])) # Predict next day's closing price last_state_mean = state_means[-1] last_state_covariance = state_covariances[-1] next_state_mean, next_state_covariance = kf.filter_update( last_state_mean, last_state_covariance, observation= np.array([spy_data['Adj Close'][-1], spy_data['Open'][-1], spy_data['Low'][-1], spy_data['High'][-1], spy_data['Volume'][-1]]) ) predicted_price = next_state_mean[0] print(f"Today's SPY closing price: {price[-1][0]}") print(f"Predicted SPY closing price for tomorrow: {predicted_price}")
错误原因
核心问题是卡尔曼滤波器的参数维度不匹配:
- 你将状态设为5维(对应5个输入变量),但观测矩阵设计为仅提取第一个状态,同时观测噪声是1维,和输入的5维观测数据(每次输入Close、Open、Low、High、Volume五个值)不匹配。
- 你的需求是用5个特征预测单一收盘价,状态维度应该设为1维(对应收盘价的估计值),而非5维。
修正方案及代码
调整参数维度,让状态、观测矩阵、观测噪声和输入数据维度一致,同时符合“用多特征预测单一收盘价”的需求:
import numpy as np import yfinance as yf from pykalman import KalmanFilter spy_data = yf.download('SPY', start='2010-01-01', end='2023-03-17') # 整理5维观测数据:Close, Open, Low, High, Volume observations = spy_data[['Close', 'Open', 'Low', 'High', 'Volume']].values # 状态设为1维:对应我们要估计的收盘价 initial_state_mean = np.array([spy_data['Close'].iloc[0]]) # 用第一个收盘价初始化 initial_state_covariance = np.array([[100]]) # 1x1协方差矩阵 # 转移矩阵:假设下一个状态等于当前状态(随机游走模型) transition_matrix = np.array([[1]]) # 过程噪声:状态转移的噪声 transition_covariance = np.array([[0.001]]) # 观测矩阵:5x1矩阵,每个元素对应一个特征与状态的关联系数(初始可设为1,后续可迭代优化) observation_matrix = np.array([[1], [1], [1], [1], [1]]) # 观测噪声:5x5对角矩阵,对应5个观测变量的噪声 observation_covariance = np.diag([0.1, 0.1, 0.1, 0.1, 100000]) # Volume噪声设大一点,因为数值范围大 # 初始化卡尔曼滤波器 kf = KalmanFilter( initial_state_mean=initial_state_mean, initial_state_covariance=initial_state_covariance, transition_matrices=transition_matrix, observation_matrices=observation_matrix, observation_covariance=observation_covariance, transition_covariance=transition_covariance ) # 滤波得到每个时刻的状态估计 state_means, state_covariances = kf.filter(observations) # 预测次日收盘价:基于最后一个状态进行一步预测(无需新观测) next_state_mean, next_state_covariance = kf.predict( state_means[-1], state_covariances[-1] ) predicted_price = next_state_mean[0] print(f"今日SPY收盘价: {spy_data['Close'].iloc[-1]}") print(f"预测明日SPY收盘价: {predicted_price:.2f}")
关键修改说明
- 状态维度改为1维,对应要预测的收盘价,符合“单一预测值”的需求。
- 观测矩阵设为5x1,将1维状态映射到5维观测数据,匹配输入的特征数量。
- 观测噪声调整为5x5对角矩阵,对应每个输入特征的噪声水平(Volume数值大,噪声系数设得更高)。
- 使用
predict方法直接基于最后状态预测下一个时刻的收盘价,无需额外输入观测数据(若有新观测可改用filter_update)。
内容的提问来源于stack exchange,提问作者dataman
相关产品推荐
相关产品推荐

