- This topic has 0 replies, 1 voice, and was last updated 9 years ago by
hessinemaaoui.
-
AuthorPosts
-
January 20, 2012 at 7:13 am #1904
hessinemaaoui
KeymasterHi,
I am training a HMM with SuanShu but once it got errors in some cases. I tried a few different settings but the errors still occurred. Let me summarize how the error occurs.
Set HMM with 3 states with 5 discrete values in the emission probability at each state. Then I randomized a matrix A of size 3 x 3 and matrix B of size 3 x 5. Now I also get 100 observations, where the first 99 values are between 1 and 4, and the 100th value is 5. Then it runs out an infinite value matrices A and B. I suspect the issue is due to that the training algorithm finds that the value 5 cannot be found from the previous occurrences and cannot determine the probability of the model at value 5 in observation. For more details, you can refer to the following .java.
Is it an algorithmic issue or something would be fixed? Thanks.
Main Program:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061<br />package com.numericalmethod.suanshu.examples;<br />import com.numericalmethod.suanshu.matrix.doubles.Matrix;<br />import com.numericalmethod.suanshu.stats.hmm.rabiner.HmmTrainByEM;<br />import com.numericalmethod.suanshu.stats.hmm.rabiner.HiddenMarkovModel;<br />import com.numericalmethod.suanshu.matrix.doubles.matrixtype.dense.DenseMatrix;<br />import com.numericalmethod.suanshu.vector.doubles.dense.DenseVector;<br />import org.junit.Test;<br />import java.io.*;<br />import java.util.*;<br /><br />/**<br />*<br />* @author Chan<br />*/<br /><br /><br />public class Test_HMM_20120120 {<br />public static void main( String args[]) { <br />org.junit.runner.JUnitCore.main("com.numericalmethod.suanshu.examples.Test_HMM_20120120");<br />}<br />@Test<br />public void test_0010(){<br />// Initialization<br />double ThresholdValue = 0.500; //Input 1<br />int[] ActiveCol = {1, 2, 3}; //Input 2<br />int number_row_a = 3, number_col_a = number_row_a; //Input 3<br />int NumberofTotalCol = 5; //Input 4<br />int number_row_b = number_row_a, number_col_b = ActiveCol.length*2-1;<br />int WinSize = 100; <br />int nTraining = 10;<br />DenseVector PI_0 = new DenseVector(MarkovModel_pre_20120119.GenerateRandomMatrix(1, number_row_a).t()); <br />DenseMatrix A_0 = new DenseMatrix(MarkovModel_pre_20120119.GenerateRandomMatrix(number_row_a, number_col_a));<br />DenseMatrix B_0 = new DenseMatrix(MarkovModel_pre_20120119.GenerateRandomMatrix(number_row_b, number_col_b)); <br />HiddenMarkovModel model_0 = new HiddenMarkovModel(PI_0, A_0, B_0);<br /><br />DenseVector Obs = new DenseVector(MarkovModel_pre_20120119.GenerateRandomMatrix(1, WinSize).t());<br />System.out.print(Obs.toString());<br />int[] TempArray = new int[WinSize+1];<br />for (int i = 0; i<WinSize; i++){ <br />if (Obs.get(i+1)<0.25/WinSize)<br />TempArray<i> = 1;<br />else if (Obs.get(i+1)>=0.25/WinSize && Obs.get(i+1)<0.5/WinSize)<br />TempArray</i><i> = 2;<br />else if (Obs.get(i+1)>=0.5/WinSize && Obs.get(i+1)<0.75/WinSize)<br />TempArray</i><i> = 3;<br />else<br />TempArray</i><i> = 4;<br />System.out.println(TempArray</i><i>);<br />}<br /><br />TempArray[WinSize] = 4;<br />for (int k=0; k<nTraining; k++) //train nTraining times<br />model_0 = new HmmTrainByEM().train(model_0, TempArray);<br /><br />System.out.println(model_0.A().toString()); <br />System.out.println(model_0.B().toString());<br />}<br />}<br /><br /></i>It depends to another .java with method GenerateRandomMatrix from class MarkovModel_pre_20120119. Just copy it in another .java and use it in the main program. Method GenerateRandomMatrix is to generate random matrices.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177<br /><br />package com.numericalmethod.suanshu.examples;<br /><br />import com.numericalmethod.suanshu.matrix.doubles.Matrix;<br />import com.numericalmethod.suanshu.matrix.doubles.matrixtype.dense.DenseMatrix;<br />import java.util.*;<br />import java.io.*;<br /><br />/**<br />*<br />* @author Chan<br />*/<br /><br /><br />public class MarkovModel_pre_20120119 {<br />public static void main(String args[]) {<br />// Test out the functions<br />//Matrix A = new DenseMatrix(GetObservationState(readData("C:\text.txt", 2, 100), 0.005)); <br />//System.out.println(A.toString()); <br />}<br /><br /><br />public static DenseMatrix readData(String FilePath, int ColSize, int WinSize, int[] ActiveCol)<br />{<br /><br />// Col1 = Date; Col2 = Closed price; Col3 = Return;<br />DenseMatrix temp_Data = new DenseMatrix(new double[1000][ActiveCol.length +1]);<br />// Col1 = Date; Col2 = Closed price; Col3 = Normalized return;<br />DenseMatrix output_Data = new DenseMatrix(new double [1000][ActiveCol.length +1]);<br /><br /><br />try{<br />// Open the file that is the first<br />// command line parameter<br />FileInputStream fstream = new FileInputStream(FilePath);<br /><br />// Get the object of DataInputStream<br />DataInputStream in = new DataInputStream(fstream);<br />BufferedReader br = new BufferedReader(new InputStreamReader(in));<br />String strLine;<br />//Read File Line By Line<br />int i =1;<br />strLine = br.readLine();<br />while ((strLine = br.readLine()) != null && i <= 1000) { <br />// Input the first col and second col to date and close price<br />int colCount = 1;<br />for (int col = 1; col <= ColSize; col++)<br />{ <br />for (int ActiveColn = 1; ActiveColn<=ActiveCol.length; ActiveColn++)<br />if (col == ActiveCol[ActiveColn-1]){ <br />temp_Data.set(i, colCount++, Double.parseDouble(strLine.split(",")[col-1])) ; <br />break;<br />}<br />}<br />i++;<br />}<br />//Close the input stream<br />in.close();<br />}catch (Exception e){//Catch exception if any<br />System.err.println("Error: " + e.getMessage());<br />}<br /><br />// Calculate the return, the first one return cannot be calculated<br />for (int i = 1000; i>=2; i--){<br />if (temp_Data.get(i, 1)>0)<br />for (int col=ActiveCol.length +1; col >=3 ;col--)<br />temp_Data.set(i, col, (temp_Data.get(i, col-1)-temp_Data.get(i-1, col-1))/temp_Data.get(i-1, col-1));<br />}<br /><br />// Assign date and price<br />for (int i = 1000; i>WinSize; i-- ){ <br />output_Data.set(i-WinSize, 1, temp_Data.get(i, 1));<br />output_Data.set(i-WinSize, 2, temp_Data.get(i, 2));<br />}<br /><br />// Assign all the observations<br />for (int col = 3; col<=ActiveCol.length +1; col++)<br />{<br />for (int i = 1000; i>WinSize; i-- ){<br />double mean = 0, variance = 0;<br />for (int j = 0; i<WinSize; j++)<br />mean+=temp_Data.get(i-j, 3); <br />mean = mean/WinSize;<br /><br />for (int j = 0; j<WinSize; j++)<br />variance+=(temp_Data.get(i-j, 3)-mean)*(temp_Data.get(i-j, 3)-mean); <br />variance = variance/WinSize;<br />output_Data.set(i-WinSize, col, (temp_Data.get(i,col)-mean)/Math.sqrt(variance));<br />}<br />}<br />return output_Data;<br />}<br /><br />public static DenseMatrix GetObservationState(DenseMatrix Obser, double Threshold)<br />{<br />// Find out the size of a non-zero submatrix of Obser<br />int NonZeroRowSize = 0;<br />for (int i = 1; i <= Obser.nRows(); i++)<br />if (Obser.get(i,1)>0) NonZeroRowSize++;<br /><br />DenseMatrix output_GetObser = new DenseMatrix (new double[NonZeroRowSize][Obser.nCols()]);<br />for (int i = 1; i<=NonZeroRowSize; i++)<br />{<br />// Assign Date<br />output_GetObser.set(i, 1, Obser.get(i, 1));<br />// Assign Price<br />output_GetObser.set(i, 2, Obser.get(i, 2));<br />// Assign state<br />for (int col = 3; col <= Obser.nCols(); col++)<br />{<br />if (Obser.get(i, col)<(-1)*Threshold)<br />output_GetObser.set(i, col, 1);<br />else if (Obser.get(i, col)> Threshold)<br />output_GetObser.set(i, col, 3);<br />else<br />output_GetObser.set(i, col, 2);<br />}<br /><br />}<br /><br />return GenerateObservationValue(output_GetObser);<br />}<br /><br /><br />// It generate the state by the weighted average of observation state (default factors 1)<br />// If the observation<i> = {1, 2, 3, 3, 2}, then translate it to {-1, 0, 1, 1, 0}<br />// Add all those observation value. Max value = Size; Min Value = -Size<br />public static DenseMatrix GenerateObservationValue(DenseMatrix output_GetObser)<br />{<br />DenseMatrix OutMx = new DenseMatrix(new double [output_GetObser.nRows()][3]);<br />for (int row = 1; row<=output_GetObser.nRows(); row ++)<br />{<br />int SumObservation = 0;<br />for (int col = 3; col <= output_GetObser.nCols(); col++)<br />SumObservation += output_GetObser.get(row, col);<br />// Consider there are two observations, min_value = 2 and max_value = 6<br />// We need to transfer it to observation values from 1 to 5<br />OutMx.set(row, 1, output_GetObser.get(row, 1));<br />OutMx.set(row, 2, output_GetObser.get(row, 2));<br />OutMx.set(row, 3, SumObservation-(output_GetObser.nCols()-3));<br />} <br />return OutMx;<br />}<br /><br />// Return a random matrix<br />public static DenseMatrix GenerateRandomMatrix(int rowsize, int colsize){<br />Random generator = new Random();<br /><br />double r1 = generator.nextDouble();<br />double r2 = generator.nextDouble();<br />double sum = r1 + r2;<br />r1 = r1/sum;<br />r2 = r2/sum; <br />double sum_a; <br /><br />DenseMatrix ResultMatrix = new DenseMatrix(new double[rowsize][colsize]);<br />double[] r_a = new double[colsize+1];<br /><br /><br />for ( int j = 1; j<=rowsize;j++){<br />sum_a =0;<br />for (int i=1;i<=colsize;i++){<br />r_a</i><i> = generator.nextDouble();<br />sum_a = r_a</i><i> + sum_a;<br />}<br />for (int i=1;i<=colsize;i++){<br />r_a</i><i> = r_a</i><i>/sum_a;<br />}<br />for ( int k = 1;k<= colsize;k++){<br />ResultMatrix.set(j, k, r_a[k]);<br />}<br />}<br />return ResultMatrix;<br />}<br />}<br /></i> -
AuthorPosts
- You must be logged in to reply to this topic.