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 ***" conditioned = factor.conditionedVariables() unconditioned = factor.unconditionedVariables() unconditioned.remove(eliminationVariable) factor_ = Factor(unconditioned, conditioned, factor.variableDomainsDict()) for assignment in factor_.getAllPossibleAssignmentDicts(): prob = 0 for i in (factor_.variableDomainsDict())[eliminationVariable]: tmp = assignment.copy() tmp[eliminationVariable] = i prob += factor.getProbability(tmp) factor_.setProbability(assignment, prob) return factor_
def eliminate(factor, eliminationVariable): """ Question 2: 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 ***" new_unconditioned = factor.unconditionedVariables() new_unconditioned.remove(eliminationVariable) new_Factor = Factor(new_unconditioned,factor.conditionedVariables(), factor.variableDomainsDict()) for j in new_Factor.getAllPossibleAssignmentDicts(): probabilitySum = 0 for i in new_Factor.variableDomainsDict().get(eliminationVariable): j[eliminationVariable] = i currentProb = factor.getProbability(j) probabilitySum += currentProb del j[eliminationVariable] new_Factor.setProbability(j, probabilitySum) return new_Factor
def eliminate(factor, eliminationVariable): """ Question 2: 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())) new_unconditioned = factor.unconditionedVariables() new_unconditioned.remove(eliminationVariable) new_Factor = Factor(new_unconditioned, factor.conditionedVariables(), factor.variableDomainsDict()) for j in new_Factor.getAllPossibleAssignmentDicts(): probabilitySum = 0 for i in new_Factor.variableDomainsDict().get(eliminationVariable): j[eliminationVariable] = i currentProb = factor.getProbability(j) probabilitySum += currentProb del j[eliminationVariable] new_Factor.setProbability(j, probabilitySum) return new_Factor
def joinFactors(factors): """ Question 3: Your join implementation Input factors is a list of factors. You should calculate the set of unconditioned variables and conditioned variables for the join of those factors. Return a new factor that has those variables and whose probability entries are product of the corresponding rows of the input factors. You may assume that the variableDomainsDict for all the input factors are the same, since they come from the same BayesNet. joinFactors will only allow unconditionedVariables to appear in one input factor (so their join is well defined). Hint: Factor methods that take an assignmentDict as input (such as getProbability and setProbability) can handle assignmentDicts that assign more variables than are in that factor. Useful functions: Factor.getAllPossibleAssignmentDicts Factor.getProbability Factor.setProbability Factor.unconditionedVariables Factor.conditionedVariables Factor.variableDomainsDict """ # typecheck portion setsOfUnconditioned = [ set(factor.unconditionedVariables()) for factor in factors ] if len(factors) > 1: intersect = reduce(lambda x, y: x & y, setsOfUnconditioned) if len(intersect) > 0: print "Factor failed joinFactors typecheck: ", factor raise ValueError, ( "unconditionedVariables can only appear in one factor. \n" + "unconditionedVariables: " + str(intersect) + "\nappear in more than one input factor.\n" + "Input factors: \n" + "\n".join(map(str, factors))) "*** YOUR CODE HERE ***" conditionedList = list() unconditionedList = list() for factor in factors: tempUnconditioned = factor.unconditionedVariables() for var in tempUnconditioned: if var not in unconditionedList: unconditionedList.append(var) for variable in factor.conditionedVariables(): if (variable not in unconditionedList) and (variable not in conditionedList): conditionedList.append(variable) conditionedList = [ var for var in conditionedList if var not in unconditionedList ] _newFactor = Factor(unconditionedList, conditionedList, Factor.variableDomainsDict(factors[0])) for assignment in _newFactor.getAllPossibleAssignmentDicts(): for factor in factors: product = 1 for x in factors: product *= x.getProbability(assignment) _newFactor.setProbability(assignment, product) return _newFactor
def joinFactors(factors): """ Question 3: Your join implementation Input factors is a list of factors. You should calculate the set of unconditioned variables and conditioned variables for the join of those factors. Return a new factor that has those variables and whose probability entries are product of the corresponding rows of the input factors. You may assume that the variableDomainsDict for all the input factors are the same, since they come from the same BayesNet. joinFactors will only allow unconditionedVariables to appear in one input factor (so their join is well defined). Hint: Factor methods that take an assignmentDict as input (such as getProbability and setProbability) can handle assignmentDicts that assign more variables than are in that factor. Useful functions: Factor.getAllPossibleAssignmentDicts Factor.getProbability Factor.setProbability Factor.unconditionedVariables Factor.conditionedVariables Factor.variableDomainsDict """ # typecheck portion setsOfUnconditioned = [ set(factor.unconditionedVariables()) for factor in factors ] if len(factors) > 1: intersect = reduce(lambda x, y: x & y, setsOfUnconditioned) if len(intersect) > 0: print "Factor failed joinFactors typecheck: ", factor raise ValueError, ( "unconditionedVariables can only appear in one factor. \n" + "unconditionedVariables: " + str(intersect) + "\nappear in more than one input factor.\n" + "Input factors: \n" + "\n".join(map(str, factors))) "*** YOUR CODE HERE ***" newfactor = factors[0] while len(factors) >= 2: factors.pop(0) joinfactor = factors[0] oldfactor = newfactor olduncon = oldfactor.unconditionedVariables() oldcon = oldfactor.conditionedVariables() joinuncon = joinfactor.unconditionedVariables() joincon = joinfactor.conditionedVariables() newuncon = olduncon.union(joinuncon) newcon = oldcon.union(joincon) for con in newuncon: if con in newcon: newcon.remove(con) newfactor = Factor(newuncon, newcon, newfactor.variableDomainsDict()) for assignment in newfactor.getAllPossibleAssignmentDicts(): newfactor.setProbability( assignment, oldfactor.getProbability(assignment) * joinfactor.getProbability(assignment)) return newfactor
def joinFactors(factors): """ Question 3: Your join implementation Input factors is a list of factors. You should calculate the set of unconditioned variables and conditioned variables for the join of those factors. Return a new factor that has those variables and whose probability entries are product of the corresponding rows of the input factors. You may assume that the variableDomainsDict for all the input factors are the same, since they come from the same BayesNet. joinFactors will only allow unconditionedVariables to appear in one input factor (so their join is well defined). Hint: Factor methods that take an assignmentDict as input (such as getProbability and setProbability) can handle assignmentDicts that assign more variables than are in that factor. Useful functions: Factor.getAllPossibleAssignmentDicts Factor.getProbability Factor.setProbability Factor.unconditionedVariables Factor.conditionedVariables Factor.variableDomainsDict """ # typecheck portion setsOfUnconditioned = [ set(factor.unconditionedVariables()) for factor in factors ] if len(factors) > 1: intersect = reduce(lambda x, y: x & y, setsOfUnconditioned) if len(intersect) > 0: print "Factor failed joinFactors typecheck: ", factor raise ValueError, ( "unconditionedVariables can only appear in one factor. \n" + "unconditionedVariables: " + str(intersect) + "\nappear in more than one input factor.\n" + "Input factors: \n" + "\n".join(map(str, factors))) #do not remove above un_var = set([]) con_var = set([]) dom_list = {} # go through the list of factors and store all of the unconditioned variables, # conditioned variables, along with the variable domains for fac in factors: un_var.update(fac.unconditionedVariables()) con_var.update(fac.conditionedVariables()) dom_list.update(fac.variableDomainsDict()) # remove from the conditioned variables all of the unconditioned variables # because we are able to turn these into into unconditioned varaibles con_var = con_var.difference(un_var) #build the new factor newFac = Factor(un_var, con_var, dom_list) pairs = [[]] for doms in newFac.variableDomainsDict().iterkeys(): t = [] for tmp in newFac.variableDomainsDict()[doms]: for i in pairs: t.append(i + [tmp]) pairs = t #add the probabilities to the factor for dic in newFac.getAllPossibleAssignmentDicts(): prob = 1 for fac in factors: prob = prob * fac.getProbability(dic) newFac.setProbability(dic, prob) return newFac