Changeset 101
- Timestamp:
- 07/04/11 15:21:50 (13 years ago)
- Location:
- trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/DeterministicFiniteAutomaton.java
r93 r101 7 7 import de.ugoe.cs.eventbench.data.Event; 8 8 9 /** 10 * <p> 11 * Implements a Deterministic Finite Automata (DFA) capable of random session 12 * generation. It is a special case of a first-order Markov model, where the 13 * transition probability is equally high for all following states. 14 * </p> 15 * 16 * @author Steffen Herbold 17 * @version 1.0 18 */ 9 19 public class DeterministicFiniteAutomaton extends FirstOrderMarkovModel { 10 20 11 21 /** 22 * <p> 12 23 * Id for object serialization. 24 * </p> 13 25 */ 14 26 private static final long serialVersionUID = 1L; 15 27 28 /** 29 * <p> 30 * Constructor. Creates a new DeterministicFiniteAutomaton. 31 * </p> 32 * 33 * @param r 34 * random number generator used by probabilistic methods of the 35 * class 36 */ 16 37 public DeterministicFiniteAutomaton(Random r) { 17 38 super(r); 18 39 } 19 40 41 /** 42 * <p> 43 * Calculates the proability of the next state. Each of the following states 44 * in the automaton is equally probable. 45 * </p> 46 * 47 * @see de.ugoe.cs.eventbench.models.IStochasticProcess#getProbability(java.util.List, 48 * de.ugoe.cs.eventbench.data.Event) 49 */ 20 50 @Override 21 public double getProbability(List<? extends Event<?>> context, Event<?> symbol) { 51 public double getProbability(List<? extends Event<?>> context, 52 Event<?> symbol) { 22 53 double result = 0.0d; 23 54 24 55 List<Event<?>> contextCopy; 25 if( context.size()>=trieOrder ) { 26 contextCopy = new LinkedList<Event<?>>(context.subList(context.size()-trieOrder+1, context.size())); 56 if (context.size() >= trieOrder) { 57 contextCopy = new LinkedList<Event<?>>(context.subList( 58 context.size() - trieOrder + 1, context.size())); 27 59 } else { 28 60 contextCopy = new LinkedList<Event<?>>(context); 29 61 } 30 62 31 32 63 List<Event<?>> followers = trie.getFollowingSymbols(contextCopy); 33 34 if ( followers.size()!=0 && followers.contains(symbol)) {64 65 if (followers.size() != 0 && followers.contains(symbol)) { 35 66 result = 1.0d / followers.size(); 36 67 } 37 68 38 69 return result; 39 70 } -
trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/FirstOrderMarkovModel.java
r86 r101 14 14 import Jama.Matrix; 15 15 16 public class FirstOrderMarkovModel extends HighOrderMarkovModel implements IDotCompatible { 17 18 /** 16 /** 17 * <p> 18 * Implements first-order Markov models. The implementation is based on 19 * {@link HighOrderMarkovModel} and restricts the Markov order to 1. In 20 * comparison to {@link HighOrderMarkovModel}, more calculations are possible 21 * with first-order models, e.g., the calculation of the entropy ( 22 * {@link #calcEntropy()}). 23 * </p> 24 * 25 * @author Steffen Herbold 26 * @version 1.0 27 */ 28 public class FirstOrderMarkovModel extends HighOrderMarkovModel implements 29 IDotCompatible { 30 31 /** 32 * <p> 19 33 * Id for object serialization. 34 * </p> 20 35 */ 21 36 private static final long serialVersionUID = 1L; 22 37 38 /** 39 * <p> 40 * Maximum number of iterations when calculating the stationary distribution 41 * as the limit of multiplying the transmission matrix with itself. 42 * </p> 43 */ 23 44 final static int MAX_STATDIST_ITERATIONS = 1000; 24 45 46 /** 47 * <p> 48 * Constructor. Creates a new FirstOrderMarkovModel. 49 * </p> 50 * 51 * @param r 52 * random number generator used by probabilistic methods of the 53 * class 54 */ 25 55 public FirstOrderMarkovModel(Random r) { 26 56 super(1, r); 27 57 } 28 58 59 /** 60 * <p> 61 * Generates the transmission matrix of the Markov model. 62 * </p> 63 * 64 * @return transmission matrix 65 */ 29 66 private Matrix getTransmissionMatrix() { 30 List<Event<?>> knownSymbols = new ArrayList<Event<?>>(trie.getKnownSymbols()); 67 List<Event<?>> knownSymbols = new ArrayList<Event<?>>( 68 trie.getKnownSymbols()); 31 69 int numStates = knownSymbols.size(); 32 70 Matrix transmissionMatrix = new Matrix(numStates, numStates); 33 34 for ( int i=0 ; i<numStates ; i++) {71 72 for (int i = 0; i < numStates; i++) { 35 73 Event<?> currentSymbol = knownSymbols.get(i); 36 74 List<Event<?>> context = new ArrayList<Event<?>>(); 37 75 context.add(currentSymbol); 38 for ( int j=0 ; j<numStates ; j++) {76 for (int j = 0; j < numStates; j++) { 39 77 Event<?> follower = knownSymbols.get(j); 40 78 double prob = getProbability(context, follower); … … 44 82 return transmissionMatrix; 45 83 } 46 84 85 /** 86 * <p> 87 * Calculates the entropy of the model. To make it possible that the model 88 * is stationary, a transition from {@link Event#ENDEVENT} to 89 * {@link Event#STARTEVENT} is added. 90 * </p> 91 * 92 * @return entropy of the model or NaN if it could not be calculated 93 */ 94 public double calcEntropy() { 95 Matrix transmissionMatrix = getTransmissionMatrix(); 96 List<Event<?>> knownSymbols = new ArrayList<Event<?>>( 97 trie.getKnownSymbols()); 98 int numStates = knownSymbols.size(); 99 100 int startStateIndex = knownSymbols.indexOf(Event.STARTEVENT); 101 int endStateIndex = knownSymbols.indexOf(Event.ENDEVENT); 102 if (startStateIndex == -1) { 103 Console.printerrln("Error calculating entropy. Initial state of markov chain not found."); 104 return Double.NaN; 105 } 106 if (endStateIndex == -1) { 107 Console.printerrln("Error calculating entropy. End state of markov chain not found."); 108 return Double.NaN; 109 } 110 transmissionMatrix.set(endStateIndex, startStateIndex, 1); 111 112 // Calculate stationary distribution by raising the power of the 113 // transmission matrix. 114 // The rank of the matrix should fall to 1 and each two should be the 115 // vector of the stationory distribution. 116 int iter = 0; 117 int rank = transmissionMatrix.rank(); 118 Matrix stationaryMatrix = (Matrix) transmissionMatrix.clone(); 119 while (iter < MAX_STATDIST_ITERATIONS && rank > 1) { 120 stationaryMatrix = stationaryMatrix.times(stationaryMatrix); 121 rank = stationaryMatrix.rank(); 122 iter++; 123 } 124 125 if (rank != 1) { 126 Console.traceln("rank: " + rank); 127 Console.printerrln("Unable to calculate stationary distribution."); 128 return Double.NaN; 129 } 130 131 double entropy = 0.0; 132 for (int i = 0; i < numStates; i++) { 133 for (int j = 0; j < numStates; j++) { 134 if (transmissionMatrix.get(i, j) != 0) { 135 double tmp = stationaryMatrix.get(i, 0); 136 tmp *= transmissionMatrix.get(i, j); 137 tmp *= Math.log(transmissionMatrix.get(i, j)) / Math.log(2); 138 entropy -= tmp; 139 } 140 } 141 } 142 return entropy; 143 } 144 145 /** 146 * <p> 147 * The dot represenation of {@link FirstOrderMarkovModel}s is its graph 148 * representation with the states as nodes and directed edges weighted with 149 * transition probabilities. 150 * </p> 151 * 152 * @see de.ugoe.cs.eventbench.models.IDotCompatible#getDotRepresentation() 153 */ 154 @Override 47 155 public String getDotRepresentation() { 48 156 StringBuilder stringBuilder = new StringBuilder(); 49 157 stringBuilder.append("digraph model {" + StringTools.ENDLINE); 50 158 51 List<Event<?>> knownSymbols = new ArrayList<Event<?>>(trie.getKnownSymbols()); 52 53 for( Event<?> symbol : knownSymbols) { 54 final String thisSaneId = symbol.getShortId().replace("\"", "\\\"").replaceAll("[\r\n]",""); 55 stringBuilder.append(" " + symbol.hashCode() + " [label=\""+thisSaneId+"\"];" + StringTools.ENDLINE); 159 List<Event<?>> knownSymbols = new ArrayList<Event<?>>( 160 trie.getKnownSymbols()); 161 162 for (Event<?> symbol : knownSymbols) { 163 final String thisSaneId = symbol.getShortId().replace("\"", "\\\"") 164 .replaceAll("[\r\n]", ""); 165 stringBuilder.append(" " + symbol.hashCode() + " [label=\"" 166 + thisSaneId + "\"];" + StringTools.ENDLINE); 56 167 List<Event<?>> context = new ArrayList<Event<?>>(); 57 context.add(symbol); 168 context.add(symbol); 58 169 List<Event<?>> followers = trie.getFollowingSymbols(context); 59 for( Event<?> follower : followers ) { 60 stringBuilder.append(" "+symbol.hashCode()+" -> " + follower.hashCode() + " "); 61 stringBuilder.append("[label=\"" + getProbability(context, follower) + "\"];" + StringTools.ENDLINE); 170 for (Event<?> follower : followers) { 171 stringBuilder.append(" " + symbol.hashCode() + " -> " 172 + follower.hashCode() + " "); 173 stringBuilder.append("[label=\"" 174 + getProbability(context, follower) + "\"];" 175 + StringTools.ENDLINE); 62 176 } 63 177 } … … 65 179 return stringBuilder.toString(); 66 180 } 67 181 182 /** 183 * <p> 184 * Returns a {@link Graph} represenation of the model with the states as 185 * nodes and directed edges weighted with transition probabilities. 186 * </p> 187 * 188 * @return {@link Graph} of the model 189 */ 68 190 public Graph<String, MarkovEdge> getGraph() { 69 191 Graph<String, MarkovEdge> graph = new SparseMultigraph<String, MarkovEdge>(); 70 71 List<Event<?>> knownSymbols = new ArrayList<Event<?>>(trie.getKnownSymbols()); 72 73 for( Event<?> symbol : knownSymbols) { 192 193 List<Event<?>> knownSymbols = new ArrayList<Event<?>>( 194 trie.getKnownSymbols()); 195 196 for (Event<?> symbol : knownSymbols) { 74 197 String from = symbol.getShortId(); 75 198 List<Event<?>> context = new ArrayList<Event<?>>(); 76 context.add(symbol); 77 199 context.add(symbol); 200 78 201 List<Event<?>> followers = trie.getFollowingSymbols(context); 79 80 for ( Event<?> follower : followers) {202 203 for (Event<?> follower : followers) { 81 204 String to = follower.getShortId(); 82 MarkovEdge prob = new MarkovEdge(getProbability(context, follower)); 205 MarkovEdge prob = new MarkovEdge(getProbability(context, 206 follower)); 83 207 graph.addEdge(prob, from, to, EdgeType.DIRECTED); 84 208 } … … 86 210 return graph; 87 211 } 88 212 213 /** 214 * Inner class used for the {@link Graph} representation of the model. 215 * 216 * @author Steffen Herbold 217 * @version 1.0 218 */ 89 219 static public class MarkovEdge { 220 /** 221 * <p> 222 * Weight of the edge, i.e., its transition probability. 223 * </p> 224 */ 90 225 double weight; 91 MarkovEdge(double weight) { this.weight = weight; } 92 public String toString() { return ""+weight; } 93 } 94 95 public double calcEntropy() { 96 Matrix transmissionMatrix = getTransmissionMatrix(); 97 List<Event<?>> knownSymbols = new ArrayList<Event<?>>(trie.getKnownSymbols()); 98 int numStates = knownSymbols.size(); 99 100 int startStateIndex = knownSymbols.indexOf(Event.STARTEVENT); 101 int endStateIndex = knownSymbols.indexOf(Event.ENDEVENT); 102 if( startStateIndex==-1 ) { 103 Console.printerrln("Error calculating entropy. Initial state of markov chain not found."); 104 return Double.NaN; 105 } 106 if( endStateIndex==-1 ) { 107 Console.printerrln("Error calculating entropy. End state of markov chain not found."); 108 return Double.NaN; 109 } 110 transmissionMatrix.set(endStateIndex, startStateIndex, 1); 111 112 // Calculate stationary distribution by raising the power of the transmission matrix. 113 // The rank of the matrix should fall to 1 and each two should be the vector of the 114 // stationory distribution. 115 int iter = 0; 116 int rank = transmissionMatrix.rank(); 117 Matrix stationaryMatrix = (Matrix) transmissionMatrix.clone(); 118 while( iter<MAX_STATDIST_ITERATIONS && rank>1 ) { 119 stationaryMatrix = stationaryMatrix.times(stationaryMatrix); 120 rank = stationaryMatrix.rank(); 121 iter++; 122 } 123 124 if( rank!=1 ) { 125 Console.traceln("rank: " + rank); 126 Console.printerrln("Unable to calculate stationary distribution."); 127 return Double.NaN; 128 } 129 130 double entropy = 0.0; 131 for( int i=0 ; i<numStates ; i++ ) { 132 for( int j=0 ; j<numStates ; j++ ) { 133 if( transmissionMatrix.get(i,j)!=0 ) { 134 double tmp = stationaryMatrix.get(i, 0); 135 tmp *= transmissionMatrix.get(i, j); 136 tmp *= Math.log(transmissionMatrix.get(i,j))/Math.log(2); 137 entropy -= tmp; 138 } 139 } 140 } 141 return entropy; 226 227 /** 228 * <p> 229 * Constructor. Creates a new MarkovEdge. 230 * </p> 231 * 232 * @param weight 233 * weight of the edge, i.e., its transition probability 234 */ 235 MarkovEdge(double weight) { 236 this.weight = weight; 237 } 238 239 /** 240 * <p> 241 * The weight of the edge as {@link String}. 242 * </p> 243 */ 244 public String toString() { 245 return "" + weight; 246 } 142 247 } 143 248 -
trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/HighOrderMarkovModel.java
r93 r101 7 7 import de.ugoe.cs.eventbench.data.Event; 8 8 9 /** 10 * <p>Implements high-order Markov models.</p> 11 * 12 * @author Steffen Herbold 13 * @version 1.0 14 */ 9 15 public class HighOrderMarkovModel extends TrieBasedModel { 10 16 11 17 /** 18 * <p> 12 19 * Id for object serialization. 20 * </p> 13 21 */ 14 22 private static final long serialVersionUID = 1L; 15 23 24 /** 25 * <p>Constructor. Creates a new HighOrderMarkovModel with a defined Markov order.</p> 26 * @param maxOrder Markov order of the model 27 * @param r random number generator used by probabilistic methods of the class 28 */ 16 29 public HighOrderMarkovModel(int maxOrder, Random r) { 17 30 super(maxOrder, r); 18 31 } 19 32 33 /** 34 * <p> 35 * Calculates the probability of the next Event being symbol based on the order of the Markov model. The order is defined in the constructor {@link #HighOrderMarkovModel(int, Random)}. 36 * </p> 37 * @see de.ugoe.cs.eventbench.models.IStochasticProcess#getProbability(java.util.List, de.ugoe.cs.eventbench.data.Event) 38 */ 20 39 @Override 21 40 public double getProbability(List<? extends Event<?>> context, Event<?> symbol) { -
trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/IDotCompatible.java
r25 r101 1 1 package de.ugoe.cs.eventbench.models; 2 2 3 /** 4 * <p> 5 * Models implementing this interface provide a graph representation of 6 * themselves as a {@link String} with Dot syntax. 7 * </p> 8 * 9 * @author Steffen Herbold 10 * @version 1.0 11 */ 3 12 public interface IDotCompatible { 13 14 /** 15 * <p> 16 * Returns a Dot representation of the model. 17 * </p> 18 * 19 * @return string with Dot syntax that describes the model. 20 */ 4 21 public abstract String getDotRepresentation(); 5 22 } -
trunk/EventBenchCore/src/de/ugoe/cs/eventbench/models/PredictionByPartialMatch.java
r93 r101 7 7 import de.ugoe.cs.eventbench.data.Event; 8 8 9 /** 10 * <p> 11 * Implements Prediction by Partial Match (PPM) based on the following formula 12 * (LaTeX-style notation):<br> 13 * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^1 escape^{i-1} 14 * P_{MM^i}(X_n|X_{n-1},...,X_{n-i})(1-escape)<br> 15 * P_{MM^i} denotes the probability in an i-th order Markov model. 16 * </p> 17 * 18 * @author Steffen Herbold 19 * 20 */ 9 21 public class PredictionByPartialMatch extends TrieBasedModel { 10 22 11 23 /** 24 * <p> 12 25 * Id for object serialization. 26 * </p> 13 27 */ 14 28 private static final long serialVersionUID = 1L; 15 29 30 /** 31 * <p> 32 * Probability to use a lower-order Markov model 33 * </p> 34 */ 16 35 double probEscape; 17 36 37 /** 38 * <p> 39 * Constructor. Creates a new PredictionByPartialMatch model with a given 40 * Markov order and a default escape probability of 0.1. 41 * </p> 42 * 43 * @param markovOrder 44 * Markov order of the model 45 * @param r 46 * random number generator used by probabilistic methods of the 47 * class 48 */ 18 49 public PredictionByPartialMatch(int markovOrder, Random r) { 19 50 this(markovOrder, r, 0.1); 20 51 } 21 52 53 /** 54 * <p> 55 * Creates a new PredictionByPartialMatch model with a given Markov order 56 * and escape probability. 57 * </p> 58 * 59 * @param markovOrder 60 * Markov order of the model 61 * @param r 62 * random number generator used by probabilistic methods of the 63 * class 64 * @param probEscape 65 * escape probability used by the model 66 */ 22 67 public PredictionByPartialMatch(int markovOrder, Random r, double probEscape) { 23 68 super(markovOrder, r); 24 69 this.probEscape = probEscape; 25 70 } 26 71 72 /** 73 * <p> 74 * Sets the escape probability of the model. 75 * </p> 76 * 77 * @param probEscape 78 * new escape probability 79 */ 27 80 public void setProbEscape(double probEscape) { 28 81 this.probEscape = probEscape; 29 82 } 30 83 84 /** 85 * <p> 86 * Returns the escape probability of the model. 87 * </p> 88 * 89 * @return escape probability of the model 90 */ 31 91 public double getProbEscape() { 32 92 return probEscape; 33 93 } 34 94 95 /** 96 * <p> 97 * Calculates the probability of the next event based on the formula:<br> 98 * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^1 escape^{i-1} 99 * P_{MM^i}(X_n|X_{n-1},...,X_{n-i})(1-escape)<br> 100 * P_{MM^i} denotes the probability in an i-th order Markov model. 101 * </p> 102 */ 35 103 @Override 36 public double getProbability(List<? extends Event<?>> context, Event<?> symbol) { 104 public double getProbability(List<? extends Event<?>> context, 105 Event<?> symbol) { 37 106 double result = 0.0d; 38 107 double resultCurrentContex = 0.0d; 39 108 double resultShorterContex = 0.0d; 40 109 41 110 List<Event<?>> contextCopy; 42 if( context.size()>=trieOrder ) { 43 contextCopy = new LinkedList<Event<?>>(context.subList(context.size()-trieOrder+1, context.size())); 111 if (context.size() >= trieOrder) { 112 contextCopy = new LinkedList<Event<?>>(context.subList( 113 context.size() - trieOrder + 1, context.size())); 44 114 } else { 45 115 contextCopy = new LinkedList<Event<?>>(context); 46 116 } 47 117 48 49 118 List<Event<?>> followers = trie.getFollowingSymbols(contextCopy); // \Sigma' 50 119 int sumCountFollowers = 0; // N(s\sigma') 51 for ( Event<?> follower : followers) {120 for (Event<?> follower : followers) { 52 121 sumCountFollowers += trie.getCount(contextCopy, follower); 53 122 } 54 123 55 124 int countSymbol = trie.getCount(contextCopy, symbol); // N(s\sigma) 56 if ( contextCopy.size()==0) {125 if (contextCopy.size() == 0) { 57 126 resultCurrentContex = ((double) countSymbol) / sumCountFollowers; 58 127 } else { 59 if ( sumCountFollowers==0) {128 if (sumCountFollowers == 0) { 60 129 resultCurrentContex = 0.0; 130 } else { 131 resultCurrentContex = ((double) countSymbol / sumCountFollowers) 132 * (1 - probEscape); 61 133 } 62 else { 63 resultCurrentContex = ((double) countSymbol / sumCountFollowers)*(1-probEscape); 64 } 65 contextCopy.remove(0); 134 contextCopy.remove(0); 66 135 double probSuffix = getProbability(contextCopy, symbol); 67 if ( followers.size()==0) {136 if (followers.size() == 0) { 68 137 resultShorterContex = probSuffix; 69 138 } else { 70 resultShorterContex = probEscape *probSuffix;139 resultShorterContex = probEscape * probSuffix; 71 140 } 72 141 } 73 result = resultCurrentContex +resultShorterContex;74 142 result = resultCurrentContex + resultShorterContex; 143 75 144 return result; 76 145 }
Note: See TracChangeset
for help on using the changeset viewer.