我在使用来自Android可穿戴设备的加速度计和陀螺仪传感器数据训练JaHMM实现的HMM模型。
用加速度计数据训练的HMM输出的学习状态良好,误差率也尚可接受。
两个HMM的初始化如下所示:
Hmm<ObservationVector> hmm = new Hmm<>(2, new OpdfMultiGaussianFactory(3)); hmm.setPi(0, 0.5); hmm.setPi(1, 0.5); hmm.setOpdf(0, new OpdfMultiGaussian( new double[]{0,0,0}, new double[][] {{0.1,0,0}, {0,0.1,0}, {0,0,0.1} })); hmm.setOpdf(1, new OpdfMultiGaussian( new double[]{0,0,0}, new double[][] {{0.1,0,0}, {0,0.1,0}, {0,0,0.1} })); hmm.setAij(0, 0, 0.5); hmm.setAij(0, 1, 0.5); hmm.setAij(1, 0, 0.5); hmm.setAij(1, 1, 0.5);
用加速度计数据训练的HMM输出如下:
HMM with 2 state(s)
State 0 Pi: 0.5000000000000188 Aij: 0.5 0.5 Opdf: Multi-variate Gaussian distribution — Mean: [ 0.036 -0.051 0.075 ]
State 1 Pi: 0.5000000000000188 Aij: 0.5 0.5 Opdf: Multi-variate Gaussian distribution — Mean: [ 0.036 -0.051 0.075 ]
然而,用陀螺仪数据训练的HMM似乎无法学习HMM的状态,无论我尝试了多少次训练迭代(500次迭代)。例如,学习状态的概率就是NaN
用陀螺仪数据训练的HMM输出如下:
HMM with 2 state(s)
State 0 Pi: NaN Aij: ? ? Opdf: Multi-variate Gaussian distribution — Mean: [ ? ? ? ]
State 1 Pi: NaN Aij: ? ? Opdf: Multi-variate Gaussian distribution — Mean: [ ? ? ? ]
这种行为的原因可能是什么?我是否需要在数据可用于HMM之前进行预处理或归一化步骤?HMM的状态数量是否不足?我尝试过使用五个状态,但结果仍然相同。
加速度计训练文件的片段可以在这里看到:https://gist.github.com/Gudui/91d2c6b2452f1ea6a5c925b1eed9b40c
陀螺仪训练文件的片段可以在这里看到:https://gist.github.com/Gudui/987cc1c1a7c0311a03988b818e7cbbcb
对于这两个训练文件,每一行代表一个训练序列。
该库在这里可用: https://github.com/tanjiti/jahmm
提前感谢!
回答:
进一步说明我的评论,我建议:
- 使用高斯分布的随机初始化,即不要将均值向量初始化为
[0,0,0]
,也不要将协方差矩阵初始化为0.1倍的单位矩阵,像你现在做的那样,而是使用一些随机值或基于你的数据的经验均值和协方差。 - 对数据进行白化处理,确保其在每个坐标上的均值为零,方差为单位(甚至可以使用PCA使坐标不相关)。