我正在尝试创建一个HMM来使用Jahmm库here基于Java中演奏的旋律来预测和弦。我跟随他们在页面上提供的示例,尽管我做了一些更改。为了我的目的,我需要的是以下内容:
Hmm<ObservationInteger> learntHmm = buildInitHmm();
List<List<ObservationInteger>> sequences = generateSequences();
BaumWelchLearner learner = new BaumWelchLearner();
for (int i = 0; i < 10; i++) {
learntHmm = learner.iterate(learntHmm, sequences);
}
初始HMM基本上所有设置为(1/7),一个键中的7个和弦和7个音符。
我的generateSequences()
方法如下:
List<List<ObservationInteger>> sequences = new ArrayList<List<ObservationInteger>>();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("trainingData.txt")));
String currentLine;
Random generator = new Random();
while ((currentLine = bufferedReader.readLine()) != null) {
String data[] = currentLine.split(" ");
List<ObservationInteger> observations = new ArrayList<ObservationInteger>();
for (int i = 0; i < data.length; i++) {
int dataValue = ((Integer.parseInt(data[i])) % 7);
ObservationInteger observationInteger = new ObservationInteger(dataValue);
observations.add(observationInteger);
}
sequences.add(observations);
}
bufferedReader.close();
} catch (FileNotFoundException e) {
System.out.println("File not found.");
} catch (IOException e) {
e.printStackTrace();
}
return sequences;
这会将.txt文件中的值读入List<List<ObservationInteger>>
,然后用于学习HMM。但是,如果我运行此操作,我会在Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
行上找到learntHmm = learner.iterate(learntHmm, sequences);
。
相当公平,但是当我改变这个
时ObservationInteger observationInteger = new ObservationInteger(dataValue)
改为
ObservationInteger(Random.nextInt(7))
这完全没问题。我不明白为什么会出现这种情况:在这两种情况下,我都在为sequences
提供观察值,其值为0-6之间的整数。在这两种情况下,维度都完全相同,但只有当整数是随机生成而不是从我的文件中读入时,才能正常工作。有什么想法吗?
完整堆栈跟踪:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at be.ac.ulg.montefiore.run.jahmm.OpdfInteger.probability(OpdfInteger.java:85)
at be.ac.ulg.montefiore.run.jahmm.OpdfInteger.probability(OpdfInteger.java:1)
at be.ac.ulg.montefiore.run.jahmm.ForwardBackwardCalculator.computeAlphaStep(ForwardBackwardCalculator.java:124)
at be.ac.ulg.montefiore.run.jahmm.ForwardBackwardCalculator.computeAlpha(ForwardBackwardCalculator.java:102)
at be.ac.ulg.montefiore.run.jahmm.ForwardBackwardCalculator.<init>(ForwardBackwardCalculator.java:63)
at be.ac.ulg.montefiore.run.jahmm.learn.BaumWelchLearner.generateForwardBackwardCalculator(BaumWelchLearner.java:133)
at be.ac.ulg.montefiore.run.jahmm.learn.BaumWelchLearner.iterate(BaumWelchLearner.java:73)
at HiddenMarkovModel.main(HiddenMarkovModel.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
答案 0 :(得分:0)
正如有人指出的那样,读入序列的一些值没有被正确评估。为此设置工作HMM需要取0-6之间的值。我不完全确定为什么modulo没有考虑到这一点,但我编写了自己的小方法,保证从.txt文件中读取的所有值都在0到6之间并修复它。