1.数据加载
import numpy as np
import pandas as pd
from hmmlearn.hmm import GaussianHMM # GaussianHMM:股票的交易数据每天都不一样,变化连续数值
data = pd.read_csv('./apple_stock.csv') # 苹果公司股票情况
print(data.shape)
data.head()
(1300, 7)
data.tail()
data.dtypes # dtypes:查看数据类型 object:string类型
Date object
Open float64
High float64
Low float64
Close float64
Adj Close float64
Volume float64
dtype: object
2.日期转换
data['Date'] = pd.to_datetime(data['Date'],format = '%Y/%m/%d',errors = 'ignore') # format:格式
data.info() # info:查看详细信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1300 entries, 0 to 1299
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Date 1300 non-null datetime64[ns]
1 Open 1300 non-null float64
2 High 1300 non-null float64
3 Low 1300 non-null float64
4 Close 1300 non-null float64
5 Adj Close 1300 non-null float64
6 Volume 1300 non-null float64
dtypes: datetime64[ns](1), float64(6)
memory usage: 71.2 KB
data.head()
3.数据提取
volume = data['Volume'].values[1:] # 去除交易额第一天的数据
close_v = data['Close'].values
diff = np.diff(close_v) # diff:临近两个数作差 前后两天股价数值的差值 涨、跌、平
X = np.column_stack([diff,volume]) # column_stack:列合并
X.shape
(1299, 2)
4.算法建模
- n_components:指定使用3个隐藏层状态表示股票涨、平、跌三种状态
- n_iter:定义最大迭代次数
- covariance_type:定义协方差矩阵类型为对角线类型,即每个特征高斯分布有自己方差参数,相互之间没有影响
model= GaussianHMM(n_components=3,n_iter=100000, covariance_type = 'diag')
model.fit(X)
GaussianHMM(n_components=3, n_iter=100000)
for i in range(model.n_components):# n_components:模型的隐含状态即涨跌平
print('第{0}个隐含状态'.format(i))
print('平均值是:',model.means_[i])
print('方差是:',np.diag(model.covars_[i]))
print('------------------------------')
第0个隐含状态
平均值是: [-1.14524842e-01 1.23845771e+08]
方差是: [3.84678157e+00 2.24454700e+15]
------------------------------
第1个隐含状态
平均值是: [1.68138743e-01 2.79598061e+07]
方差是: [1.00638562e+00 5.12991123e+13]
------------------------------
第2个隐含状态
平均值是: [5.04087051e-02 5.66296542e+07]
方差是: [2.81382699e+00 2.27530289e+14]
------------------------------
可见层输入采用两个输入特征(涨跌幅、成交量)所以每个结点有两个元素分别代表该状态的涨跌幅均值、成交量均值。由于系统的目标预测涨跌幅所以这里只关心第一个特征的均值,有如下结论:
- 状态0的均值是-1.14524842e-01约为-0.1145,认为该状态是跌
- 状态1的均值是1.68138743e-01约为0.1681,认为该状态是涨
- 状态2的均值是5.04087051e-02约为0.0504,认为该状态是平
由涨跌幅特征的方差可得到信息为:
- 状态跌方差为3.845,是三个状态中方差最大的也就是说该状态的预测不是特别可信
- 状态涨方差为1.006,是三个状态中方差最小的也就是说该状态的预测非常可信
- 状态平方差为2.814,可信居中
5.状态转移
print(model.transmat_.round(3))
[[0.915 0. 0.102]
[0. 0.898 0.085]
[0.083 0.043 0.874]]
- 第一行最大的数值是0.915因此跌倾向于保持自己的状态即第二天仍旧为跌。
- 第二行最大的数值是0.898得知涨后第二天倾向于变为涨。
- 第三行转变状态最大数值0.874平后第二天仍旧倾向于平