def genSingleOntologyStats(ontNext, ontLink, minLinkoSize, maxLinkoSize, stepLinkoSize, modelNum, runNum, precision=2, seeds=None): """Generate the stats on link models for a given ontology. inputs: ontNext: ontology used to generate Markov model that create the next state. ontLink: ontology used for constructing linkographs. minLinkoSize: the minimun number of nodes in the linkographs to consider. maxLinkoSize: the maximum number of nodes in the linkographs to consider. Note that the max is not included to match pythons convertions on lists and ranges. stepLinkoSize: the step size between minLinkoSize to maxLinkoSize for the number of linkographs to Consider. modelNum: the number of models. runNum: the number of linkographs to consider for each linkograph size. precision: the number of decimals places to use for the Markov models. seeds: a list of seeds to use for the generated next Markov models. The size of the list should be the same as the number of runs. output: a modelNum x number_of_linkographs array that records the Frobenius norm of the average Markov model for each model and each linkograph size. The (i, j) entry uses i-th model and the n-th size linkograph, constructs runNum number of linkographs of that size, finds the average link Markov model, and records the norm of this average. """ linkoSizes = range(minLinkoSize, maxLinkoSize, stepLinkoSize) ontSize = len(ontNext) absClasses = list(ontNext.keys()) absClasses.sort() results = np.zeros((modelNum, len(linkoSizes))) if seeds is None: seeds = [time.time()*i for i in range(modelNum)] models = [] # Create the generating models for i in range(modelNum): m = markel.genModelFromOntology(ontology=ontNext, precision=2, seed=seeds[i]) # Storing the model and the current state models.append(m) # For each size linkograph, generate the runNum links and # caculate the needed statistics. for size in linkoSizes: print('size: {0}'.format(size)) for modelIndex, m in enumerate(models): linkModels = np.zeros((ontSize, ontSize, runNum)) for i in range(runNum): # Randomize the initial state m.state = m.random.randint(1, len(m.absClasses)) - 1 linko = m.genLinkograph(size, ontology=ontLink) newModel = markel.genModelFromLinko(linko, precision=precision, ontology=None, seed=None, method='link_predictor', linkNum=1) linkModels[:, :, i] = newModel.tMatrix # Find the matrix norm for the average. index = (size - minLinkoSize)//stepLinkoSize norm = np.linalg.norm(np.mean(linkModels, axis=-1), ord='fro') results[modelIndex][index] = norm return results
# the Markov models are the same since there is a lot more state than # this. model.dist(model2) # We can also create a Markov model based on an ontology modelOnt = markel.genModelFromOntology(ont, seed=42) modelOnt.tMatrix # We can also create Markov models based on linkographs # First we create a linkograph of size 100 linko100 = model.genLinkograph(100) linko100.labels # Now we create a Markov model using the 'link' method which creates a # Markov model such that he probability of the transition 'A' to 'B' # is the same as the percentage of links that have a terminal node # labeled 'B', provided the current node is labeled 'A'. modelLinkoLink = markel.genModelFromLinko(linko100, ontology=ont, seed=42, method='link') # Now we create a Markov model useing the 'next method wich creae a # Markove mode such that the probability for the transition 'A' to 'B' # represents is the percentage of time the next node was labeled 'B' # provided the current node is 'A'. modelLinkoNext = markel.genModelFromLinko(linko100, ontology=ont, seed=42, method='next')
def genSingleOntologyStats(ontNext, ontLink, minLinkoSize, maxLinkoSize, stepLinkoSize, runNum, precision=2, seeds=None): """Generate the stats on link models for a given ontology. inputs: ontNext: ontology used to generate Markov model that create the next state. ontLink: ontology used for constructing linkographs. minLinkoSize: the minimun number of nodes in the linkographs to consider. maxLinkoSize: the maximum number of nodes in the linkographs to consider. Note that the max is not included to match pythons convertions on lists and ranges. stepLinkoSize: the step size between minLinkoSize to maxLinkoSize for the number of linkographs to Consider. runNum: the number of linkographs to consider for each linkograph size. precision: the number of decimals places to use for the Markov models. seeds: a list of seeds to use for the generated next Markov models. The size of the list should be the same as the number of runs. output: a numLinkos x ontologySize x ontologySize x 2 array where numLinkos is to the floor of ((maxLinkoSize - 1) - minLinkoSize) // stepLinkoSize and ontologySize is the size of the ontology used by the given model. The first dimension is for the linkograph size. For example, an i in this dimension selects the linkograph of size minLinkoSize + i*stepLinkoSize. The second and third dimensions give the link in the link Markov model. Thus, a (j, k) in these two dimensions represent the link (j, k) in the tMatrix of the link Markov model. The fourth dimension selects the mean or standard deviation. A 0 is the mean and 1 is the standard devation. Thus, the (i, j, k, 0) entry is the mean over all the links from the ith abstraction class to the jth abstraction class for linkNum linkograph of size minLinkoSize + i*stepLinkoSize. A similar statement holds for the (i, j, k, 1) and the standard deviation. """ linkoSizes = range(minLinkoSize, maxLinkoSize, stepLinkoSize) ontSize = len(ontNext) absClasses = list(ontNext.keys()) absClasses.sort() results = np.zeros((len(linkoSizes), ontSize, ontSize, 2)) if seeds is None: seeds = [time.time() for i in range(runNum)] models = [] # Create the generating models for i in range(runNum): m = markel.genModelFromOntology(ontology=ontNext, precision=2, seed=seeds[i]) # Storing the model and the current state models.append(m) # For each size linkograph, generate the runNum links and # caculate the needed statistics. for size in linkoSizes: # currentModels packs the transition matrix for each run into # a single matrix. linkModels = np.zeros((ontSize, ontSize, runNum)) print('size: {0}'.format(size)) for i in range(runNum): m = models[i] # Randomize the initial state m.state = m.random.randint(1, len(m.absClasses)) - 1 linko = m.genLinkograph(size, ontology=ontLink) newModel = markel.genModelFromLinko(linko, precision=precision, ontology=None, seed=None, method='link_predictor', linkNum=1) linkModels[:, :, i] = newModel.tMatrix # Find the mean of each transition across the different runs. index = (size - minLinkoSize) // stepLinkoSize results[index, :, :, 0] = np.mean(linkModels, axis=-1) # Find the standard deviation across the difference runs. results[index, :, :, 1] = np.std(linkModels, axis=-1) return results
ranstate = model.random.getstate() nnorms = np.zeros(args.max - args.min + 1) tnorms = np.zeros(args.max - args.min + 1) for i in range(args.min, args.max + 1): # Reset the random variable's state model.random.setstate(ranstate) # Generate a linkograph linko = model.genLinkograph(i) # Generate Markov model genNModel = markel.genModelFromLinko(linko, precision=args.precision, method='behavioral') genTModel = markel.genModelFromLinko(linko, precision=args.precision, method='link_predictor') # Compare generated Markov model to Markov model's tMatrix nnorms[i - args.min] = model.dist(genNModel) tnorms[i - args.min] = model.dist(genTModel) # graph it # step = (args.max - args.min) // 5 # labels = np.arange(args.min, args.max+1, step) # loc = labels - args.min
def genSingleOntologyStats(minLinkoSize, maxLinkoSize, stepLinkoSize, model, runNum, precision=2): """Generate the stats on link models for a given ontology. inputs: minLinkoSize: the minimun number of nodes in the linkographs to consider. maxLinkoSize: the maximum number of nodes in the linkographs to consider. Note that the max is not included to match pythons convertions on lists and ranges. stepLinkoSize: the step size between minLinkoSize to maxLinkoSize for the number of linkographs to Consider. model: the Markov model used to generate the linkographs. Note that the Markov model must have an ontology to generate the needed linkographs. runNum: the number of linkographs to consider for each linkograph size. precision: the number of decimals places to use for the Markov models. output: a numLinkos x ontologySize x ontologySize x 2 array where numLinkos is to the floor of (maxLinkoSize - minLinkoSize)/stepLinkoSize and ontologySize is the size of the ontology used by the given model. The first dimension is for the linkograph size. For example, an i in this dimension selects the linkograph of size minLinkoSize + i*stepLinkoSize. The second and third dimensions give the link in the link Markov model. Thus, a (j, k) in these two dimensions represent the link (j, k) in the tMatrix of the link Markov model. The fourth dimension selects the mean or standard deviation. A 0 is the mean and 1 is the standard devation. Thus, the (i, j, k, 0) entry is the mean over all the links from the ith abstraction class to the jth abstraction class for linkNum linkograph of size minLinkoSize + i*stepLinkoSize. A similar statement holds for the (i, j, k, 1) and the standard deviation. """ linkoSizes = range(minLinkoSize, maxLinkoSize, stepLinkoSize) ontSize = len(model.ontology) results = np.zeros((len(linkoSizes), ontSize, ontSize, 2)) # For each size linkograph, generate the runNum links and caculate # the needs statistics. for size in linkoSizes: # currentModels packs the transition matrix for each run into # a single matrix. currentModels = np.zeros((ontSize, ontSize, runNum)) print('Processing linkographs of size {0}'.format(size)) for i in range(runNum): # Change the state. model.state = model.random.randint(1, len(model.absClasses)) model.state -= 1 linko = model.genLinkograph(size) newModel = markel.genModelFromLinko(linko, precision=precision, ontology=model.ontology, seed=None, method='link_predictor', linkNum=1) currentModels[:, :, i] = newModel.tMatrix # Find the mean of each transition across the different runs. index = (size - minLinkoSize) // stepLinkoSize results[index, :, :, 0] = np.mean(currentModels, axis=-1) # Find the standard deviation across the difference runs. results[index, :, :, 1] = np.std(currentModels, axis=-1) return results