def eliminate(factor, eliminationVariable): """ Question 4: Your eliminate implementation Input factor is a single factor. Input eliminationVariable is the variable to eliminate from factor. eliminationVariable must be an unconditioned variable in factor. You should calculate the set of unconditioned variables and conditioned variables for the factor obtained by eliminating the variable eliminationVariable. Return a new factor where all of the rows mentioning eliminationVariable are summed with rows that match assignments on the other variables. Useful functions: Factor.getAllPossibleAssignmentDicts Factor.getProbability Factor.setProbability Factor.unconditionedVariables Factor.conditionedVariables Factor.variableDomainsDict """ # autograder tracking -- don't remove if not (callTrackingList is None): callTrackingList.append(('eliminate', eliminationVariable)) # typecheck portion if eliminationVariable not in factor.unconditionedVariables(): print "Factor failed eliminate typecheck: ", factor raise ValueError, ("Elimination variable is not an unconditioned variable " \ + "in this factor\n" + "eliminationVariable: " + str(eliminationVariable) + \ "\nunconditionedVariables:" + str(factor.unconditionedVariables())) if len(factor.unconditionedVariables()) == 1: print "Factor failed eliminate typecheck: ", factor raise ValueError, ("Factor has only one unconditioned variable, so you " \ + "can't eliminate \nthat variable.\n" + \ "eliminationVariable:" + str(eliminationVariable) + "\n" +\ "unconditionedVariables: " + str(factor.unconditionedVariables())) "*** YOUR CODE HERE ***" unconditionedVariables = [x for x in factor.unconditionedVariables() if x != eliminationVariable] conditionedVariables = [x for x in factor.conditionedVariables()] domainDict = dict() for k,v in factor.variableDomainsDict().items(): if not (k == eliminationVariable): domainDict[k] = v retFactor = Factor(unconditionedVariables, conditionedVariables, domainDict) for assignmentDict in factor.getAllPossibleAssignmentDicts(): prob = factor.getProbability(assignmentDict) preProb = retFactor.getProbability(assignmentDict) retFactor.setProbability(assignmentDict, preProb+prob) retFactor = retFactor.specializeVariableDomains(factor.variableDomainsDict()) return retFactor
def inferenceByLikelihoodWeightingSampling(bayesNet, queryVariables, evidenceDict, numSamples): """ Question 6: Inference by likelihood weighted sampling This function should perform a probabilistic inference query that returns the factor: P(queryVariables | evidenceDict) It should perform inference by performing likelihood weighting sampling. It should sample numSamples times. In order for the autograder's solution to match yours, your outer loop needs to iterate over the number of samples, with the inner loop sampling from each variable's factor. Use the ordering of variables provided by BayesNet.linearizeVariables in your inner loop so that the order of samples matches the autograder's. There are typically many linearization orders of a directed acyclic graph (DAG), however we just use a particular one. The sum of the probabilities should sum to one (so that it is a true conditional probability, conditioned on the evidence). bayesNet: The Bayes Net on which we are making a query. queryVariables: A list of the variables which are unconditioned in the inference query. evidenceDict: An assignment dict {variable : value} for the variables which are presented as evidence (conditioned) in the inference query. numSamples: The number of samples that should be taken. Useful functions: sampleFromFactor normalize BayesNet.getCPT BayesNet.linearizeVariables """ sampleFromFactor = sampleFromFactorRandomSource(randomSource) "*** YOUR CODE HERE ***" #create return factor newFactor = Factor(queryVariables, evidenceDict, bayesNet.variableDomainsDict()) reducedVariableDomains = bayesNet.getReducedVariableDomains(evidenceDict) newFactor = newFactor.specializeVariableDomains(reducedVariableDomains) for i in range(numSamples): weight = 1.0 allAssignments = {} allAssignments.update(evidenceDict) for var in bayesNet.linearizeVariables(): tmpCPT = bayesNet.getCPT(var) if var in evidenceDict: #accumulate weight weight *= tmpCPT.getProbability(allAssignments) else: newAssignment = sampleFromFactor(tmpCPT, allAssignments) allAssignments.update(newAssignment) #accumulate sample p = newFactor.getProbability(allAssignments) newFactor.setProbability(allAssignments, p + weight) return normalize(newFactor) util.raiseNotDefined()
def inferenceByLikelihoodWeightingSampling(bayesNet, queryVariables, evidenceDict, numSamples): """ Question 6: Inference by likelihood weighted sampling This function should perform a probabilistic inference query that returns the factor: P(queryVariables | evidenceDict) It should perform inference by performing likelihood weighting sampling. It should sample numSamples times. In order for the autograder's solution to match yours, your outer loop needs to iterate over the number of samples, with the inner loop sampling from each variable's factor. Use the ordering of variables provided by BayesNet.linearizeVariables in your inner loop so that the order of samples matches the autograder's. There are typically many linearization orders of a directed acyclic graph (DAG), however we just use a particular one. The sum of the probabilities should sum to one (so that it is a true conditional probability, conditioned on the evidence). bayesNet: The Bayes Net on which we are making a query. queryVariables: A list of the variables which are unconditioned in the inference query. evidenceDict: An assignment dict {variable : value} for the variables which are presented as evidence (conditioned) in the inference query. numSamples: The number of samples that should be taken. Useful functions: sampleFromFactor normalize BayesNet.getCPT BayesNet.linearizeVariables """ sampleFromFactor = sampleFromFactorRandomSource(randomSource) "*** YOUR CODE HERE ***" # create return factor newFactor = Factor(queryVariables, evidenceDict, bayesNet.variableDomainsDict()) reducedVariableDomains = bayesNet.getReducedVariableDomains(evidenceDict) newFactor = newFactor.specializeVariableDomains(reducedVariableDomains) for i in range(numSamples): weight = 1.0 allAssignments = {} allAssignments.update(evidenceDict) for var in bayesNet.linearizeVariables(): tmpCPT = bayesNet.getCPT(var) if var in evidenceDict: # accumulate weight weight *= tmpCPT.getProbability(allAssignments) else: newAssignment = sampleFromFactor(tmpCPT, allAssignments) allAssignments.update(newAssignment) # accumulate sample p = newFactor.getProbability(allAssignments) newFactor.setProbability(allAssignments, p + weight) return normalize(newFactor) util.raiseNotDefined()