示例#1
0
    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()))

        #print factor
        eliminate_domain = factor.variableDomainsDict()[eliminationVariable]
        unconditionedVariables = [var for var in factor.unconditionedVariables() if var != eliminationVariable]
        domain = {}
        for var, dom in factor.variableDomainsDict().iteritems():
            if var != eliminationVariable:
                domain[var] = dom
        resultingFactor = Factor(unconditionedVariables, factor.conditionedVariables(), domain)

        for assignment in resultingFactor.getAllPossibleAssignmentDicts():
            valProbab = 0
            for eliminate_val in eliminate_domain:
                new_assign = dict(assignment.items() + [(eliminationVariable, eliminate_val)])
                valProbab += factor.getProbability(new_assign)
            resultingFactor.setProbability(assignment, valProbab)
               
        return resultingFactor
示例#2
0
def normalize(factor):
    """
    Question 5: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" + 
                            str(factor))
    uncond_var = factor.unconditionedVariables()
    cond_var = factor.conditionedVariables()
    uncond_var_one_value = [x for x in uncond_var if len(variableDomainsDict[x])==1]
    for i in range(0, len(uncond_var_one_value)):
        uncond_var.remove(uncond_var_one_value[i])
        cond_var.add(uncond_var_one_value[i])

    result_fac = Factor(uncond_var,cond_var,variableDomainsDict)
    prob_total = 0
    for assignment in factor.getAllPossibleAssignmentDicts():
        prob_total+=factor.getProbability(assignment)
    for assignment in factor.getAllPossibleAssignmentDicts():
        result_fac.setProbability(assignment,factor.getProbability(assignment)/prob_total)
    return result_fac
示例#3
0
    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()))

        uc = []
        c = []

        for v in factor.unconditionedVariables():
            if v != eliminationVariable:
                uc += [v]
        for v in factor.conditionedVariables():
            if v != eliminationVariable:
                c += [v]

        newFactor = Factor(set(uc), set(c), factor.variableDomainsDict())

        for a in factor.getAllPossibleAssignmentDicts():
            val = factor.getProbability(a) + newFactor.getProbability(a)
            newFactor.setProbability(a, val)

        return newFactor
示例#4
0
    def jointwo(a, b):
        aSet = a.unconditionedVariables().union(a.conditionedVariables())
        bSet = b.unconditionedVariables().union(b.conditionedVariables())
        #gets common dictionary of two factors
        commonDict = combineDict(a.variableDomainsDict(),
                                 b.variableDomainsDict())

        #finds unconditioned and conditioned variables in total
        uncondVar = set()
        conditionedVar = set()
        for factor in [a, b]:
            for unVar in factor.unconditionedVariables():
                if unVar not in uncondVar:
                    uncondVar.add(unVar)
            for condVar in factor.conditionedVariables():
                if condVar not in conditionedVar:
                    conditionedVar.add(condVar)
        #puts condVar intp uncondVar
        currVar = [con for con in conditionedVar]
        for c in currVar:
            if c in uncondVar:
                uncondVar.add(c)
                conditionedVar.remove(c)
        #creates a new factor and gives it the probabilities
        newFactor = Factor(uncondVar, conditionedVar, commonDict)
        for combo in newFactor.getAllPossibleAssignmentDicts():
            prob = a.getProbability(combo) * b.getProbability(combo)
            newFactor.setProbability(combo, prob)
        return newFactor
示例#5
0
    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 ***"
        # Simplify variables
        setOfUnconditioned = factor.unconditionedVariables() - \
                             set([eliminationVariable])
        eliminatedFactor = Factor(setOfUnconditioned,
                                  factor.conditionedVariables(),
                                  factor.variableDomainsDict())

        # Get product of probabilities for every assignment
        for assignment in eliminatedFactor.getAllPossibleAssignmentDicts():
            probSum = sum([factor.getProbability(a) for a in \
                           factor.getAllPossibleAssignmentDicts() if \
                           all(a[var] == assignment[var] for var in \
                               assignment.keys())])
            eliminatedFactor.setProbability(assignment, probSum)

        return eliminatedFactor
示例#6
0
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)))

    unconditioned = []
    conditioned = []
    varDomain = {}
    for factor in factors:
        varDomain = factor.variableDomainsDict()
        unconditioned += factor.unconditionedVariables()
        conditioned = set.union(factor.conditionedVariables(), conditioned)
    conditioned = set.difference(conditioned, unconditioned)
    newFactor = Factor(unconditioned, conditioned, varDomain)
    for assignment in newFactor.getAllPossibleAssignmentDicts():
        prob = 1
        for factor in factors:
            prob *= factor.getProbability(assignment)
        newFactor.setProbability(assignment, prob)
    return newFactor
示例#7
0
    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 ***"
        unconditioned = factor.unconditionedVariables()
        unconditioned = [
            var for var in unconditioned if var != eliminationVariable
        ]
        conditioned = factor.conditionedVariables()
        variableDomainsDict = factor.variableDomainsDict()
        domain = variableDomainsDict[eliminationVariable]
        newFactor = Factor(unconditioned, conditioned, variableDomainsDict)
        for assignment in newFactor.getAllPossibleAssignmentDicts():
            prob = 0
            for elim_val in domain:
                old_assignment = assignment.copy()
                old_assignment[eliminationVariable] = elim_val
                prob += factor.getProbability(old_assignment)
            newFactor.setProbability(assignment, prob)
        return newFactor
示例#8
0
    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 ***"
        #It's similar to joinFactor, first get  unconditionedSet and conditionedSet
        #then construct a newFactor to return
        unconditionedSet = factor.unconditionedVariables()
        unconditionedSet.remove(eliminationVariable)
        conditionedSet = factor.conditionedVariables()

        newFactor = Factor(unconditionedSet, conditionedSet,
                           factor.variableDomainsDict())

        #all of the rows mentioning eliminationVariable are summed with rows that match assignments on the other variables.
        for assignment in factor.getAllPossibleAssignmentDicts():
            newFactor.setProbability(
                assignment,
                newFactor.getProbability(assignment) +
                factor.getProbability(assignment))
        return newFactor
示例#9
0
    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 ***"
        unconditioned = evidenceDict.keys()
        new_domain = bayesNet.getReducedVariableDomains(evidenceDict)
        new_factor = Factor(queryVariables, unconditioned, new_domain)
        for x in range(0, numSamples):
            assignment_dict = {}
            sample = [1]
            linearized_var = bayesNet.linearizeVariables()
            for var in linearized_var:
                var_cpt = bayesNet.getCPT(var)
                if var in unconditioned:
                    assignment_dict[var] = evidenceDict[var]
                    sample.append(var_cpt.getProbability(assignment_dict))
                else:
                    assignment_dict[var] = sampleFromFactor(var_cpt, assignment_dict)[var]
            prob = reduce(lambda x, y: x*y, sample)
            new_factor.setProbability(assignment_dict, new_factor.getProbability(assignment_dict) + prob)
        new_factor = normalize(new_factor)
        return new_factor
示例#10
0
    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

        NOTES: Definition of marginalization; if you have distribution P(A,B|C),
        P(A=a|C=c)= Sum over b of P(A=a, B=b|C=c)
        """
        # 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()))

        # construct new factor
        unconditionedVariables = {v for v in factor.unconditionedVariables() if v != eliminationVariable}
        marginalizedFactor = Factor(unconditionedVariables, factor.conditionedVariables(), factor.variableDomainsDict())

        # calculate marginalized probabilities
        eliminatedVariableDomain = factor.variableDomainsDict()[eliminationVariable]
        for assignment in factor.getAllPossibleAssignmentDicts():
            marginalizedProbabilities = []
            for value in eliminatedVariableDomain:
                assignment[eliminationVariable] = value
                marginalizedProbabilities.append(factor.getProbability(assignment))
            marginalizedFactor.setProbability(assignment, sum(marginalizedProbabilities))
        return marginalizedFactor
示例#11
0
    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 ***"
        variableDomains         = factor.variableDomainsDict()
        conditionedVariables    = factor.conditionedVariables()
        unconditionedVariables  = factor.unconditionedVariables()
        if eliminationVariable in conditionedVariables:
            conditionedVariables.remove(eliminationVariable)
        if eliminationVariable in unconditionedVariables:
            unconditionedVariables.remove(eliminationVariable)
        del variableDomains[eliminationVariable]
        newFactor       = Factor(unconditionedVariables, conditionedVariables, variableDomains)
        newAssignments  = newFactor.getAllPossibleAssignmentDicts()
        assignments     = factor.getAllPossibleAssignmentDicts()
        for newAssignment in newAssignments:
            runningProbability = 0
            for assignment in assignments:
                if isSubset(assignment, newAssignment):
                    runningProbability += factor.getProbability(assignment)
            newFactor.setProbability(newAssignment, runningProbability)
        return newFactor
示例#12
0
    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 ***"
        # Note: "reduced" indicates its the unconditioned variables minus the elimVar, and "full" means its all the starting unconditioned variables
        reducedUnconditionedVariables = factor.unconditionedVariables()
        reducedUnconditionedVariables.remove(eliminationVariable)
        reducedFactor = Factor(reducedUnconditionedVariables, factor.conditionedVariables(), factor.variableDomainsDict())

        for reducedAssignment in reducedFactor.getAllPossibleAssignmentDicts():
            prob = 0
            for elimVarVal in factor.variableDomainsDict()[eliminationVariable]:
                fullAssignment = reducedAssignment
                fullAssignment[eliminationVariable] = elimVarVal

                prob = prob + factor.getProbability(fullAssignment)
            reducedFactor.setProbability(reducedAssignment, prob)

        return reducedFactor
示例#13
0
def normalize(factor):
    """
    Question 5: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" + 
                            str(factor))

    unconditioned_variables = set(filter(lambda var: len(factor.variableDomainsDict()[var]) != 1, factor.unconditionedVariables()))
    conditioned_variables = set(factor.conditionedVariables()).union(filter(lambda var: len(factor.variableDomainsDict()[var]) == 1, 
        factor.unconditionedVariables()))

    normalized = Factor(unconditioned_variables, conditioned_variables, factor.variableDomainsDict())

    total_prob = sum([factor.getProbability(ass) for ass in factor.getAllPossibleAssignmentDicts()])

    for ass in normalized.getAllPossibleAssignmentDicts():
        normalized.setProbability(ass, factor.getProbability(ass) / total_prob)

    return normalized
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]
    setsOfConditioned = [set(factor.conditionedVariables()) for factor in factors]
    factors_domains = [factor.variableDomainsDict() 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)))
        else:
            final_uncondition = reduce(lambda x, y: x | y, setsOfUnconditioned)
            final_condition = reduce(lambda x, y: x | y, setsOfConditioned)-final_uncondition
            final_domain = reduce(lambda x, y: dict(x.items()+y.items()), factors_domains)
            new_factor = Factor(final_uncondition, final_condition,final_domain)
            for assign_large in new_factor.getAllPossibleAssignmentDicts():
                assign_large_prob = 1
                for small_factor in factors:
                    # print(small_factor)
                    assign_large_prob *= small_factor.getProbability(get_new_assig(assign_large,small_factor))
                new_factor.setProbability(assign_large,assign_large_prob)
            return new_factor
    else:
        return factors[0]
示例#15
0
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]
    variableDict= factors[0].variableDomainsDict()
    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)))
    setsOfConditioned = [set(factor.conditionedVariables()) for factor in factors]
    unconditioned_var  = list(reduce(lambda x, y: x | y, setsOfUnconditioned))
    conditioned_var = list(reduce(lambda x, y: x | y, setsOfConditioned))
    conditioned_var = [var for var in conditioned_var if var not in unconditioned_var]


    result_fac = Factor(unconditioned_var,conditioned_var,variableDict)
    assignments = result_fac.getAllPossibleAssignmentDicts()
    for assignment in assignments:
        prob = 1
        for factor in factors:
            assign_tmp = {key:value for key,value in assignment.items() if key in factor.variablesSet()}
            prob*= factor.getProbability(assign_tmp)
        result_fac.setProbability(assignment,prob)

    return result_fac
示例#16
0
    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 ***"
        unCondVar = factor.unconditionedVariables()
        unCondVar.remove(eliminationVariable)
        condVar = factor.conditionedVariables()
        varDomainsDict = factor.variableDomainsDict()
        result = Factor(unCondVar, condVar, varDomainsDict)
        
        for assignmentDict in result.getAllPossibleAssignmentDicts():
            prob = 0
            for eliminationValue in varDomainsDict[eliminationVariable]:
                assignmentDictCopy = assignmentDict
                assignmentDictCopy[eliminationVariable] = eliminationValue
                prob += factor.getProbability(assignmentDictCopy)
            result.setProbability(assignmentDict, prob)

        return result
示例#17
0
    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()))

        unconditioned = factor.unconditionedVariables()
        unconditioned.remove(eliminationVariable)
        newFactor = Factor(unconditioned, factor.conditionedVariables(),factor.variableDomainsDict())

        tempProbTable = dict()
        allAssignments = factor.getAllPossibleAssignmentDicts()
        for assignment in allAssignments:
            prunedAssignment = {key:value for key,value in assignment.items() if key != eliminationVariable}
            prunedAssignment = frozenset(prunedAssignment.items())
            if prunedAssignment not in tempProbTable:
                tempProbTable[prunedAssignment] = 0
            tempProbTable[prunedAssignment] += factor.getProbability(assignment)
        for assignment in tempProbTable:
            defrozenAssignment = dict(assignment)
            newFactor.setProbability(defrozenAssignment,tempProbTable[assignment])
        return newFactor
示例#18
0
    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 ***"
        # util.raiseNotDefined()
        varDict, conVariables, unconVariables = factor.variableDomainsDict(
        ), factor.conditionedVariables(), []
        for uncon in factor.unconditionedVariables():
            if uncon != eliminationVariable:
                unconVariables.append(uncon)
        new = Factor(unconVariables, conVariables, varDict)
        for each in new.getAllPossibleAssignmentDicts():
            probability = 0
            for rem in varDict[eliminationVariable]:
                past = each.copy()
                past[eliminationVariable] = rem
                probability += factor.getProbability(past)
            new.setProbability(each, probability)
        return new
    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 ***"
        # Note: "reduced" indicates its the unconditioned variables minus the elimVar, and "full" means its all the starting unconditioned variables
        reducedUnconditionedVariables = factor.unconditionedVariables()
        reducedUnconditionedVariables.remove(eliminationVariable)
        reducedFactor = Factor(reducedUnconditionedVariables,
                               factor.conditionedVariables(),
                               factor.variableDomainsDict())

        for reducedAssignment in reducedFactor.getAllPossibleAssignmentDicts():
            prob = 0
            for elimVarVal in factor.variableDomainsDict(
            )[eliminationVariable]:
                fullAssignment = reducedAssignment
                fullAssignment[eliminationVariable] = elimVarVal

                prob = prob + factor.getProbability(fullAssignment)
            reducedFactor.setProbability(reducedAssignment, prob)

        return reducedFactor
示例#20
0
    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()))

        unconditioned = factor.unconditionedVariables()
        unconditioned.remove(eliminationVariable)
        result = Factor(unconditioned, factor.conditionedVariables(),
                        factor.variableDomainsDict())

        for v in result.getAllPossibleAssignmentDicts():
            copy = v.copy()
            s = 0
            for e in factor.variableDomainsDict()[eliminationVariable]:
                copy[eliminationVariable] = e
                s += factor.getProbability(copy)
            result.setProbability(v, s)
        return result
示例#21
0
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).
    """
    # 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)))

    
    # Calculate the set of unconditioned variables and conditioned 
    # variables for the join of those factors.
    condVars = set()
    unCondVars = set()

    for factor in factors:  
        for var in factor.conditionedVariables():
            condVars.add(var)
        for var in factor.unconditionedVariables():
            unCondVars.add(var)

    # Remove any unconditioned variables from the list of conditioned variables
    for var in unCondVars:
        if var in condVars:
            condVars.remove(var)

    newFactor = Factor(unCondVars, condVars, factors[0].variableDomainsDict())

    # Assign the correct probabilities to each assignment through multiplication
    for assignment in newFactor.getAllPossibleAssignmentDicts():
        chainRuleResult = 1
        for factor in factors:
            chainRuleResult *= factor.getProbability(assignment)
            newFactor.setProbability(assignment, chainRuleResult)

    return newFactor
示例#22
0
    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)
        new_f = Factor(queryVariables, evidenceDict.keys(),
                       bayesNet.getReducedVariableDomains(evidenceDict))

        for i in range(numSamples):
            w = 1
            cur = dict()
            for variable in bayesNet.linearizeVariables():
                if variable in evidenceDict:
                    cur[variable] = evidenceDict.get(variable)
                    w *= bayesNet.getCPT(variable).getProbability(cur)
                else:
                    cur.update(sampleFromFactor(bayesNet.getCPT(variable),
                                                cur))
            new_f.setProbability(cur, w + new_f.getProbability(cur))
        new_f = normalize(new_f)
        return new_f
示例#23
0
def joinFactors(factors):
    """
    Question 1: 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 ***"
    unconditionals, conditionals, variableDomainsDict = getVariablesFromAllFactors(factors)
    newFactor   = Factor(unconditionals, conditionals, variableDomainsDict)
    for unconditional in unconditionals:
        toRemove    = []
        newFactor   = Factor(unconditionals, conditionals, variableDomainsDict)
        possAssigns = newFactor.getAllPossibleAssignmentDicts()
        newFactor   = initiateProbsToOne(newFactor, possAssigns)
        for factor in factors:
            factorUnconditionals    = factor.unconditionedVariables()
            factorConditionals      = factor.conditionedVariables()
            if unconditional in factorUnconditionals and not unconditional in factorConditionals:
                toRemove.append(factor)
                assignments = factor.getAllPossibleAssignmentDicts()
                for assignment in assignments:
                    for possAssign in possAssigns:
                        newFactor = adjustProbability(possAssign, assignment, newFactor, factor)
        factors = purgeFactors(toRemove, factors, newFactor)
    return newFactor
    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
示例#25
0
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 ***"
    uncondVars = set([var for factor in factors for var in factor.unconditionedVariables()]) #self-explanatory
    condVars = set([var for factor in factors for var in factor.conditionedVariables()]) 
    condVars = condVars.difference(uncondVars) #remove any duplicate vars
    resultingFactor = Factor(uncondVars,condVars,factors[0].variableDomainsDict()) #create factor based on ^ & ^^
    for val in resultingFactor.getAllPossibleAssignmentDicts():
        totalProbab = 1
        for factor in factors:
            #calculate probability for each individual assignedment over the full list of factors
            totalProbab *= factor.getProbability(val) 
        resultingFactor.setProbability(val,totalProbab)
    return resultingFactor
示例#26
0
    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()))

        uncond_var = factor.unconditionedVariables()
        cond_var = factor.conditionedVariables()
        uncond_var.remove(eliminationVariable)
        result_fac = Factor(uncond_var,cond_var,factor.variableDomainsDict())
        for assignment in result_fac.getAllPossibleAssignmentDicts():
            prob  =0
            assigns_for_eliminate  = factor.variableDomainsDict()[eliminationVariable]
            for val in assigns_for_eliminate:
                assignment[eliminationVariable] = val
                prob+= factor.getProbability(assignment)
            assignment.pop(eliminationVariable)
            result_fac.setProbability(assignment,prob)
        return result_fac
示例#27
0
    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 ***"
        #uncondVarSet = set()
        condVarSet = factor.conditionedVariables()
        uncondVarSet = factor.unconditionedVariables()
        uncondVarSet.remove(eliminationVariable) #removes elimination variable
        newFactor = Factor(uncondVarSet, condVarSet, factor.variableDomainsDict()) 
        for assignment in newFactor.getAllPossibleAssignmentDicts():
            probSum = 0
            for val in factor.variableDomainsDict()[eliminationVariable]: 
                assignment[eliminationVariable] = val
                probSum += factor.getProbability(assignment) #obtain probability of all assignments affiliated to entry add to other rows it matches with
            newFactor.setProbability(assignment, probSum)
        return newFactor
示例#28
0
def joinTwoFactors(factor, otherFactor):
    unconditionedVaribles = factor.unconditionedVariables() | otherFactor.unconditionedVariables()
    conditionedVaribles = factor.conditionedVariables() | otherFactor.conditionedVariables()
    conditionedVaribles = conditionedVaribles - unconditionedVaribles
    retFactor = Factor(list(unconditionedVaribles), list(conditionedVaribles), factor.variableDomainsDict())
    for assignmentDict in retFactor.getAllPossibleAssignmentDicts():
        prob1 = factor.getProbability(assignmentDict)
        prob2 = otherFactor.getProbability(assignmentDict)
        retFactor.setProbability(assignmentDict, prob1*prob2)
    return retFactor
示例#29
0
    def inferenceByLikelihoodWeightingSampling(bayesNet, queryVariables, evidenceDict, numSamples):
        """
        Question 7: 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 ***"
        linearVars = bayesNet.linearizeVariables() # queryVariables are unconditional variables
        newFactor = Factor(queryVariables, evidenceDict.keys(), bayesNet.getReducedVariableDomains(evidenceDict)) #keys of evidenceDict are the conditional vars
        for sample in range(numSamples):
            weight = 1
            assignment = dict()
            for variable in linearVars:
                if variable in evidenceDict:
                    assignment[variable] = evidenceDict.get(variable)
                    weight *= bayesNet.getCPT(variable).getProbability(assignment)
                else:
                    assignment.update(sampleFromFactor(bayesNet.getCPT(variable), assignment))
            newFactor.setProbability(assignment, weight + newFactor.getProbability(assignment))
        return normalize(newFactor)
示例#30
0
    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)

        currentFactorsList = bayesNet.getAllCPTsWithEvidence(evidenceDict)
        newFactor = Factor(queryVariables, evidenceDict.keys(), currentFactorsList[0].variableDomainsDict())
        for _ in range(numSamples):
            w = 1.0
            conditionedAssignments = {}
            for variable in bayesNet.linearizeVariables():
                if variable in evidenceDict:
                    conditionedAssignments[variable] = evidenceDict[variable]
                    w = w * bayesNet.getCPT(variable).getProbability(conditionedAssignments)
                else:
                    conditionedAssignments.update(sampleFromFactor(bayesNet.getCPT(variable), conditionedAssignments))
            newFactor.setProbability(conditionedAssignments, w + newFactor.getProbability(conditionedAssignments))
        return normalize(newFactor)
示例#31
0
    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.

        """
        # 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()))

        # Calculate the set of unconditioned and conditioned variables 
        condVars = factor.conditionedVariables()
        unCondVars = factor.unconditionedVariables()
        unCondVars.remove(eliminationVariable)

        # Create a new factor using the new sets
        newFactor = Factor(unCondVars, condVars, factor.variableDomainsDict())

        # Sum over the probabilities of the removed variable for the new factor
        for assignment in newFactor.getAllPossibleAssignmentDicts():
            probSum = 0
            for value in factor.variableDomainsDict()[eliminationVariable]:
                assignment[eliminationVariable] = value
                probSum += factor.getProbability(assignment)
            newFactor.setProbability(assignment, probSum)

        return newFactor
示例#32
0
def joinTwoFactors(factor1,factor2):
    conditionedVariables = set(factor1.conditionedVariables()) | set(factor2.conditionedVariables())
    unconditionedVariables = set(factor1.unconditionedVariables()) | set(factor2.unconditionedVariables())
    conditionedVariables = conditionedVariables - unconditionedVariables
    newFactor = Factor(list(unconditionedVariables),list(conditionedVariables),factor1.variableDomainsDict())
    for assignment in newFactor.getAllPossibleAssignmentDicts():
        variables1 = set(factor1.unconditionedVariables()) | set(factor1.conditionedVariables())
        assignment1 = {key:value for key,value in assignment.items() if key in variables1}
        prob1 = factor1.getProbability(assignment1)
        variables2 = set(factor2.unconditionedVariables()) | set(factor2.conditionedVariables())
        assignment2 = {key:value for key,value in assignment.items() if key in variables2}
        prob2 = factor2.getProbability(assignment2)
        newFactor.setProbability(assignment,prob1*prob2)
    return newFactor
def join(f1, f2, commonVars):
    jointUncond = f1.unconditionedVariables() | f2.unconditionedVariables()
    jointCond = (f1.conditionedVariables()
                 | f2.conditionedVariables()) - jointUncond
    jointFactor = Factor(
        list(jointUncond), list(jointCond),
        dict(f2.variableDomainsDict(), **f1.variableDomainsDict()))
    for a1 in f1.getAllPossibleAssignmentDicts():
        for a2 in f2.getAllPossibleAssignmentDicts():
            next = False
            for v in commonVars:
                if a1[v] != a2[v]:
                    next = True
                    break
            if not next:
                prob1 = f1.getProbability(a1)
                prob2 = f2.getProbability(a2)
                jointFactor.setProbability(dict(a2, **a1), prob1 * prob2)
    return jointFactor
示例#34
0
    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 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()))

        else:
            new_condition = factor.conditionedVariables()
            new_uncondition = factor.unconditionedVariables() - set([eliminationVariable])
            eliminate_factor = Factor(new_uncondition, new_condition, factor.variableDomainsDict())
            # print(factor.unconditionedVariables(),eliminationVariable)
            # print(eliminate_factor)
            for assignment in factor.getAllPossibleAssignmentDicts():
                small_assign = get_new_assig(assignment, eliminate_factor)
                if eliminate_factor.getProbability(small_assign) != 0:
                    eliminate_factor.setProbability(small_assign, factor.getProbability(assignment)+eliminate_factor.getProbability(small_assign)) 
                else:
                    eliminate_factor.setProbability(small_assign, factor.getProbability(assignment))

            return eliminate_factor
示例#36
0
def joinFactors(factors):
    """
    Question 1: 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 ***"
    uncondVarSet = set()
    condVarSet = set()
    for factor in factors:
    	for uncond in factor.unconditionedVariables():
     		uncondVarSet.add(uncond)
    for factor in factors:
     	for cond in factor.conditionedVariables():
     		if cond not in uncondVarSet:
     			condVarSet.add(cond)
    newFactor = Factor(uncondVarSet, condVarSet, factors[0].variableDomainsDict()) #factor[0]
    for assignment in newFactor.getAllPossibleAssignmentDicts():
     	probability = 1
     	for factor in factors:
     		probability *= factor.getProbability(assignment) # retrieves the value from that factor in table to use to compute new value
     	newFactor.setProbability(assignment, probability) #displays result on to table	
    return newFactor
    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 ***"
        unconditioned = set()
        conditioned = set()
        for eachVar in factor.unconditionedVariables():
            if not eachVar == eliminationVariable:
                unconditioned.add(eachVar)
        for eachVar in factor.conditionedVariables():
            conditioned.add(eachVar)
        # build a new blank factor
        variableDomainsDict = factor.variableDomainsDict()
        newFactor = Factor(unconditioned, conditioned, variableDomainsDict)

        # eliminate the given variables
        assignmentDicts = factor.getAllPossibleAssignmentDicts()
        for assignment in assignmentDicts:
            oldProb = factor.getProbability(assignment)
            newProb = newFactor.getProbability(assignment)
            newFactor.setProbability(assignment, oldProb + newProb)
        return newFactor
示例#38
0
def normalize(factor):
    """
    Question 3: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" +
                            str(factor))

    "*** YOUR CODE HERE ***"

    conditionedVariables = []
    for each in factor.unconditionedVariables():
        if len(factor.variableDomainsDict()[each]) == 1:
            conditionedVariables.append(each)
    conditionedVariables = list(
        set(conditionedVariables + list(factor.conditionedVariables())))

    unconditionedVariables = []
    for each in factor.unconditionedVariables():
        if each not in conditionedVariables:
            unconditionedVariables.append(each)

    newFactor = Factor(unconditionedVariables, conditionedVariables,
                       factor.variableDomainsDict())
    z = 0
    for each in factor.getAllPossibleAssignmentDicts():
        z += factor.getProbability(each)
    for each in newFactor.getAllPossibleAssignmentDicts():
        newFactor.setProbability(each, factor.getProbability(each) / z)
    return newFactor
    util.raiseNotDefined()
def normalize(factor):
    """
    Question 5: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" + 
                            str(factor))

    "*** YOUR CODE HERE ***"
    # If the sum of probabilities in the input factor is 0,
    # you should return None.
    variableDomainsDict = factor.variableDomainsDict()
    unconditioned = factor.unconditionedVariables()
    conditioned = factor.conditionedVariables()

    prob_sum = 0
    old_assignments = factor.getAllPossibleAssignmentDicts()
    for row in old_assignments:
        prob_sum += factor.getProbability(row)
    if prob_sum == 0:
        return None

    for var in unconditioned:
        if len(variableDomainsDict[var]) == 1:
            conditioned.add(var)
    unconditioned = [var for var in unconditioned if var not in conditioned]
    newFactor = Factor(unconditioned, conditioned, variableDomainsDict)

    for assignment in newFactor.getAllPossibleAssignmentDicts():
        prob = factor.getProbability(assignment)
        newFactor.setProbability(assignment, prob / prob_sum)
    return newFactor
示例#40
0
def normalize(factor):
    """
    Question 3: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" + 
                            str(factor))

    "*** YOUR CODE HERE ***"
    all_possible_assignments = factor.getAllPossibleAssignmentDicts()
    all_unconditioned = factor.unconditionedVariables()
    all_conditioned = factor.conditionedVariables()
    vars_domain = factor.variableDomainsDict()

    for unconditioned in all_unconditioned:
        if(len(vars_domain[unconditioned]) == 1):
            all_unconditioned.remove(unconditioned)
            all_conditioned.append(unconditioned)
    normalized_factor = Factor(all_unconditioned, all_conditioned, vars_domain)

    sum_prob = 0
    for assign in all_possible_assignments:
        sum_prob += factor.getProbability(assign)
    #print sum_prob
    for assign in all_possible_assignments:
        normalized_factor.setProbability(assign, (factor.getProbability(assign)) / sum_prob)

    return normalized_factor
示例#41
0
def normalize(factor):
    """
    Question 5: Your normalize implementation

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists
    of the input factor's conditioned variables as well as any of the
    input factor's unconditioned variables with exactly one entry in their
    domain.  Since there is only one entry in that variable's domain, we
    can either assume it was assigned as evidence to have only one variable
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables
    with single value domains, but that is alright since we have to assign
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print("Factor failed normalize typecheck: ", factor)
            raise ValueError(
                "The factor to be normalized must have only one " +
                "assignment of the \n" + "conditional variables, " +
                "so that total probability will sum to 1\n" + str(factor))

    "*** YOUR CODE HERE ***"
    new_unconditioned = factor.unconditionedVariables()
    new_conditioned = factor.conditionedVariables()
    new_doamin = factor.variableDomainsDict()

    temp_set = set()
    for var in new_unconditioned:
        if (len(new_doamin[var]) == 1):
            temp_set.add(var)
    new_conditioned = new_conditioned | temp_set
    new_unconditioned = new_unconditioned - temp_set

    new_factor = Factor(new_unconditioned, new_conditioned, new_doamin)

    prob = 0
    for assignment in factor.getAllPossibleAssignmentDicts():
        prob += factor.getProbability(assignment)

    for assignment in factor.getAllPossibleAssignmentDicts():
        new_factor.setProbability(assignment,
                                  factor.getProbability(assignment) / prob)

    return new_factor
示例#42
0
def normalize(factor):
    """
    Question 5: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" +
                            str(factor))

    "*** YOUR CODE HERE ***"
    #util.raiseNotDefined()
    domainvarDict = factor.variableDomainsDict()
    uncondVar = factor.unconditionedVariables()
    condVar = factor.conditionedVariables()
    #if the probabilities sum upto 0 then return none
    probSum = 0
    prevassignmentVal = factor.getAllPossibleAssignmentDicts()
    for row in prevassignmentVal:
        probSum += factor.getProbability(row)
    if probSum == 0:
        return None

    for var in uncondVar:
        if len(domainvarDict[var]) == 1:
            condVar.add(var)
    uncondVar = [var for var in uncondVar if var not in condVar]
    newFactor = Factor(uncondVar, condVar, domainvarDict)

    for assignmentVal in newFactor.getAllPossibleAssignmentDicts():
        prob = factor.getProbability(assignmentVal)
        newFactor.setProbability(assignmentVal, prob / probSum)
    return newFactor
示例#43
0
    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 ***"
        #util.raiseNotDefined()
        uncondVar = factor.unconditionedVariables()
        uncondVar = [var for var in uncondVar if var != eliminationVariable]
        condVar = factor.conditionedVariables()
        domainvarDict = factor.variableDomainsDict()
        umbrella = domainvarDict[eliminationVariable]
        #new factor with the elimnation var
        newFactor = Factor(uncondVar, condVar, domainvarDict)
        for assignment in newFactor.getAllPossibleAssignmentDicts():
            prob = 0
            #parsing for the eliminaion value in the umbrella
            for elimVal in umbrella:
                #storing the copy of the assignment val
                prevassignmentVal = assignment.copy()
                #eliminating the assignment
                prevassignmentVal[eliminationVariable] = elimVal
                #calculating the probability of the assignment
                prob += factor.getProbability(prevassignmentVal)
            #setting the probability of the new assignment
            newFactor.setProbability(assignment, prob)
        return newFactor
示例#44
0
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 ***"
    #P(X|Y) + P(Y) -> P(X,Y)
    #Product rule, multiply variables not in conditional together.
    uncond = []
    cond = []
    variableDomainsDict = {}

    if len(factors) > 0:
        variableDomainsDict = factors[0].variableDomainsDict()

    for f in factors:
        tempUncond = f.unconditionedVariables()
        tempCond = f.conditionedVariables()
        uncond.extend(tempUncond)
        for conditionedVar in tempCond:
            if conditionedVar not in cond:
                cond.append(conditionedVar)
    #for var in cond:
    #if var not in cond:aeorhgijoarejh
    cond = [var for var in cond if var not in uncond]

    returnedFactor = Factor(uncond, cond, variableDomainsDict)
    assignments = returnedFactor.getAllPossibleAssignmentDicts()

    #multiply those not in conditioned
    for assignment in assignments:
        p = 1
        for factor in factors:
            p = p * factor.getProbability(assignment)
        returnedFactor.setProbability(assignment, p)

    return returnedFactor
示例#45
0
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

    NOTES: P(A|B) is the conditional distribution of A given B, and A is 
    conditioned on B. In this project, B is referred to as a "conditioned 
    variable" (since it's being conditioned on), and then A is called 
    "unconditioned." Better terminology might be something like "conditioned 
    on" for B and "not conditioned on" for A. 
    """

    # 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)))

    tempConditionedVariables = set()
    inputUnconditionedVariables = set()
    variableDomains = factors[0].variableDomainsDict()

    # construct factor inputs
    for factor in factors:
        for variable in factor.conditionedVariables():
            tempConditionedVariables.add(variable)
        for variable in factor.unconditionedVariables():
            inputUnconditionedVariables.add(variable)

    inputConditionedVariables = {v for v in tempConditionedVariables if v not in inputUnconditionedVariables}

    joinedFactor = Factor(inputUnconditionedVariables, inputConditionedVariables, variableDomains)

    # calculate joint probabilities
    for assignment in joinedFactor.getAllPossibleAssignmentDicts():
        probability = 1
        for factor in factors:
            try:
                probability *= factor.getProbability(assignment)
            except(ValueError):
                continue
        joinedFactor.setProbability(assignment, probability)

    return joinedFactor
示例#46
0
def joinFactors(factors):
    """
    Question 1: 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)))


    listOfUnconditioned = []
    for factor in factors:
        for variable in factor.unconditionedVariables():
            if variable not in listOfUnconditioned:
                listOfUnconditioned.append(variable)
    listOfConditioned = []
    for factor in factors:
        for variable in factor.conditionedVariables():
            if variable not in listOfUnconditioned and variable not in listOfConditioned:
                listOfConditioned.append(variable)
    newFactor = Factor(listOfUnconditioned, listOfConditioned, factors[0].variableDomainsDict())
    for assignment in newFactor.getAllPossibleAssignmentDicts():
        possibility = 1
        for factor in factors:
            possibility = possibility * factor.getProbability(assignment)
        newFactor.setProbability(assignment, possibility)
    return newFactor
    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 a conditionedAssignments dict
        conditionedAssignments = {}
        #print conditionedAssignments
        #print bayesNet.getCPT()
        variableList = bayesNet.linearizeVariables()
        evidenceList = set(evidenceDict.keys())

        # build a new blank factor
        variableDomainsDict = bayesNet.getReducedVariableDomains(evidenceDict)
        #print variableDomainsDict
        #print queryVariables
        #print evidenceList
        newFactor = Factor(queryVariables, evidenceList, variableDomainsDict)
        #print newFactor
        # sample numSamples times
        for idx in range(numSamples):
            weight = 1.0
            assignmentDict = {}
            for variable in variableList:
                factor = bayesNet.getCPT(variable)
                #print factor
                if (variable in evidenceList): 
                    assignmentDict[variable] = evidenceDict[variable]
                    prob = factor.getProbability(assignmentDict)
                    #print 'Prob: ', prob
                    weight *= prob 
                else:
                    newDict = sampleFromFactor(factor, assignmentDict)
                    # update assignment dict
                    for key in newDict:
                        assignmentDict[key] = newDict[key]
                    #print 'new assignment dict: ', assignmentDict
            # what to do with final Assignment and weight?
            finalAssignment = assignmentDict
            #print finalAssignment
            currentProb = newFactor.getProbability(finalAssignment)
            newProb = currentProb + weight
            newFactor.setProbability(finalAssignment, newProb)

        # normalize
        queryConditionedOnEvidence = normalize(newFactor)
        return queryConditionedOnEvidence
示例#48
0
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 ***"

    unconditioned = []
    conditioned = []
    variableDomainsDict = {}
    #checking for non empty factors
    if factors and len(factors) > 0:
        variableDomainsDict = factors[0].variableDomainsDict()
        #parsing through all the factors
    for fac in factors:
        #initialized temp cond and uncon vars
        uncondtempVar = fac.unconditionedVariables()
        condtempVar = fac.conditionedVariables()
        unconditioned.extend(uncondtempVar)
        #parsing through the condvars list
        for currcondVar in condtempVar:
            #if the current cond var is not in the list
            if currcondVar not in conditioned:
                #append it
                conditioned.append(currcondVar)
    #initializing the array
    conditioned = [var for var in conditioned if var not in unconditioned]

    newFactor = Factor(unconditioned, conditioned, variableDomainsDict)
    legalAssignments = newFactor.getAllPossibleAssignmentDicts()
    #parsing through all the assignments
    for currAssignment in legalAssignments:
        prob = 1
        #parsing through all the factors
        for factor in factors:
            #calculating the prob of the current assignment
            prob *= factor.getProbability(currAssignment)
        #setting the probability of the curr assignment vs prob
        newFactor.setProbability(currAssignment, prob)

    return newFactor
示例#49
0
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 ***"

    unconditioned = set()
    conditioned = set()
    domainDict = dict()

    for factor in factors:
        conditioned = conditioned | factor.conditionedVariables()
        unconditioned = unconditioned | factor.unconditionedVariables()
        domainDict = dict(domainDict, **factor.variableDomainsDict())

    conditioned = conditioned - (conditioned & unconditioned)
    returnFactor = Factor(unconditioned, conditioned, domainDict)

    for assignmentDict in returnFactor.getAllPossibleAssignmentDicts():
        probability = 1
        for factor in factors:
            assignmentCopy = dict()
            for variable in assignmentDict:
                if (variable in (factor.unconditionedVariables()
                                 | factor.conditionedVariables())):
                    assignmentCopy[variable] = assignmentDict[variable]
            probability = probability * factor.getProbability(assignmentCopy)
        returnFactor.setProbability(assignmentDict, probability)

    return returnFactor
def joinFactors(factors):
    """
    Question 1: 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 ***"
    # for factor in factors:
    #    print factor

    # get the unconditioned and conditioned variables.
    unconditioned = set()
    conditioned = set()
    for factor in factors:
        for eachVar in factor.unconditionedVariables():
            unconditioned.add(eachVar)
    # only variables not unconditioned will be considered conditioned
    for factor in factors:
        for eachVar in factor.conditionedVariables():
            if not eachVar in unconditioned:
                conditioned.add(eachVar)
    # build a new blank factor
    variableDomainsDict = factors[0].variableDomainsDict()
    newFactor = Factor(unconditioned, conditioned, variableDomainsDict)

    # test assignmentDicts
    assignmentDicts = newFactor.getAllPossibleAssignmentDicts()
    for assignment in assignmentDicts:
        prob = 1.0
        for factor in factors:
            prob *= factor.getProbability(assignment)
        newFactor.setProbability(assignment, prob)
    # print newFactor
    return newFactor
示例#51
0
    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_coditioned = factor.conditionedVariables()
        new_domain = {}
        for key in factor.variableDomainsDict().iterkeys():
            if (key != eliminationVariable):
                new_domain[key] = factor.variableDomainsDict()[key]
        # new_domain = factor.variableDomainsDict()

        new_factor = Factor(new_unconditioned, new_coditioned, new_domain)
        all_new_pos = new_factor.getAllPossibleAssignmentDicts()
        all_old_pos = factor.getAllPossibleAssignmentDicts()

        for assignment in all_new_pos:
            prob = 0;
            for elim_pos in factor.variableDomainsDict()[eliminationVariable]:
                temp_assignment = assignment
                temp_assignment[eliminationVariable] = elim_pos
                prob += factor.getProbability(temp_assignment)
            new_factor.setProbability(assignment, prob)
        return new_factor
示例#52
0
    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 ***"
        setsOfUnconditioned = [set(factor.unconditionedVariables())]
        setsOfUnconditioned =  reduce(lambda x, y: x | y, setsOfUnconditioned)
        setsOfConditioned = [set(factor.conditionedVariables())]
        setsOfConditioned = reduce(lambda x, y: x | y, setsOfConditioned)
        

        setsOfUnconditioned = setsOfUnconditioned.difference([eliminationVariable])
        setsOfConditioned = setsOfConditioned.difference([eliminationVariable])
        

        domain = factor.variableDomainsDict()
        
        newFactor = Factor(setsOfUnconditioned, setsOfConditioned, domain)
        modifiedDict = factor.getAllPossibleAssignmentDicts()
        for assignments in modifiedDict:
            newFactor.setProbability(assignments, newFactor.getProbability(assignments) + factor.getProbability(assignments))
        return newFactor
示例#53
0
def joinFactors(factors):
    """
    Question 1: 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 ***"
    set_of_unconditioned = set(factors[0].unconditionedVariables())
    set_Of_variables = set(factors[0].variables())
    variable_domains = factors[0].variableDomainsDict()
    
    for factor in factors[1:]:
        for var in factor.variables():
            set_Of_variables.add(var)
        for var in factor.unconditionedVariables():
            set_of_unconditioned.add(var)

    set_of_conditioned = set_Of_variables - set_of_unconditioned
    new_factor = Factor(list(set_of_unconditioned), list(set_of_conditioned), variable_domains)
    #print isinstance(new_factor, Factor)
    all_possible_assignments = new_factor.getAllPossibleAssignmentDicts()

    for assignment in all_possible_assignments:
        prob = factors[0].getProbability(assignment)
        for factor in factors[1:]:
            prob = prob * factor.getProbability(assignment)
            #print prob
        new_factor.setProbability(assignment, prob)
    return new_factor
示例#54
0
def normalize(factor):
    """
    Question 3: Your normalize implementation 

    Input factor is a single factor.

    The set of conditioned variables for the normalized factor consists 
    of the input factor's conditioned variables as well as any of the 
    input factor's unconditioned variables with exactly one entry in their 
    domain.  Since there is only one entry in that variable's domain, we 
    can either assume it was assigned as evidence to have only one variable 
    in its domain, or it only had one entry in its domain to begin with.
    This blurs the distinction between evidence assignments and variables 
    with single value domains, but that is alright since we have to assign 
    variables that only have one value in their domain to that single value.

    Return a new factor where the sum of the all the probabilities in the table is 1.
    This should be a new factor, not a modification of this factor in place.

    If the sum of probabilities in the input factor is 0,
    you should return None.

    This is intended to be used at the end of a probabilistic inference query.
    Because of this, all variables that have more than one element in their 
    domain are assumed to be unconditioned.
    There are more general implementations of normalize, but we will only 
    implement this version.

    Useful functions:
    Factor.getAllPossibleAssignmentDicts
    Factor.getProbability
    Factor.setProbability
    Factor.unconditionedVariables
    Factor.conditionedVariables
    Factor.variableDomainsDict
    """

    # typecheck portion
    variableDomainsDict = factor.variableDomainsDict()
    for conditionedVariable in factor.conditionedVariables():
        if len(variableDomainsDict[conditionedVariable]) > 1:
            print "Factor failed normalize typecheck: ", factor
            raise ValueError, ("The factor to be normalized must have only one " + \
                            "assignment of the \n" + "conditional variables, " + \
                            "so that total probability will sum to 1\n" + 
                            str(factor))

    "*** YOUR CODE HERE ***"
    setsOfUnconditioned = [set(factor.unconditionedVariables())]
    setsOfUnconditioned =  reduce(lambda x, y: x | y, setsOfUnconditioned)
    setsOfConditioned = [set(factor.conditionedVariables())]
    setsOfConditioned = reduce(lambda x, y: x | y, setsOfConditioned)
    # print setsOfUnconditioned
    # print setsOfConditioned

    # overlap = setsOfUnconditioned.intersection(setsOfConditioned)
    # setsOfUnconditioned = setsOfUnconditioned.union(overlap)
    # setsOfConditioned = setsOfConditioned.difference(overlap)

    domain = factor.variableDomainsDict()

    for key in factor.variableDomainsDict():
        if len(factor.variableDomainsDict()[key]) == 1:
            if key in setsOfUnconditioned:
                setsOfUnconditioned = setsOfUnconditioned.difference([(key)])
                setsOfConditioned = setsOfConditioned.union([(key)])                

    newFactor = Factor(setsOfUnconditioned, setsOfConditioned, domain)
    z = 0
    for assignments in factor.getAllPossibleAssignmentDicts():
        z += factor.getProbability(assignments)
    if z == 0:
        return None
    for assignments in factor.getAllPossibleAssignmentDicts():
        newFactor.setProbability(assignments, float(factor.getProbability(assignments)/z))
    return newFactor
def joinFactors(factors):
    """
    Question 1: 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 ***"

    factor1 = factors[0]

    totalUnconditionedVars = set()
    totalConditionedVars = set()
    varsToDomain = {}


    for factor in factors:
        for uncon in factor.unconditionedVariables():
            if uncon not in totalUnconditionedVars:
                totalUnconditionedVars.add(uncon)
                varsToDomain[uncon] = factor.variableDomainsDict()[uncon]
    for factor in factors:
        for con in factor.conditionedVariables():
            if con not in totalUnconditionedVars and con not in totalConditionedVars:
                totalConditionedVars.add(con)
                varsToDomain[con] = factor.variableDomainsDict()[con]

    newFactor = Factor(list(totalUnconditionedVars), list(totalConditionedVars), varsToDomain)

    for ass in newFactor.getAllPossibleAssignmentDicts():
        newFactor.setProbability(ass, float(1.0))

    for factor in factors:
        asses = newFactor.getAllPossibleAssignmentDicts()
        for ass in asses:
            for facAss in factor.getAllPossibleAssignmentDicts():
                pro = factor.getProbability(facAss)
                works = True
                for var in facAss.keys():
                    if facAss[var] != ass[var]:
                        works = False
                        break
                if works:
                    newFactor.setProbability(ass, newFactor.getProbability(ass) * pro)
                    break

    return newFactor
示例#56
0
def joinFactors(factors):
    """
    Question 1: 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 
    [{'W': 'sun'}, {'W': 'rain'}]
    
    Factor.getProbability 
    factor.getProbability({'W': 'sun'}) 
    
    Factor.setProbability 
    factor.setProbability({'W': 'sun'}, probability):

    Factor.unconditionedVariables 
    ['W']
    
    Factor.conditionedVariables 
    []
    
    Factor.variableDomainsDict 
    {'D': ['wet', 'dry'], 'W': ['sun', 'rain']}

    P(unconditioned|conditioned)
    """

    # 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 ***"

    setsOfUnconditioned = [set(factor.unconditionedVariables()) for factor in factors]
    setsOfUnconditioned =  reduce(lambda x, y: x | y, setsOfUnconditioned)
    setsOfConditioned = [set(factor.conditionedVariables()) for factor in factors]
    setsOfConditioned = reduce(lambda x, y: x | y, setsOfConditioned)
    overlap = setsOfUnconditioned.intersection(setsOfConditioned)
    # print setsOfUnconditioned
    # print setsOfConditioned
    # print overlap
    setsOfUnconditioned = setsOfUnconditioned.union(overlap)
    setsOfConditioned = setsOfConditioned.difference(overlap)
    # print 'NEW unconditioned'
    # print setsOfUnconditioned
    # print 'NEW conditioned'
    # print setsOfConditioned

    domain = factor.variableDomainsDict()
    for factor in factors:
        domain.update(factor.variableDomainsDict())

    newFactor = Factor(setsOfUnconditioned, setsOfConditioned, domain)
    for assignments in newFactor.getAllPossibleAssignmentDicts():
        listP = [factor.getProbability(assignments) for factor in factors]
        probability = 1
        for p in listP:
            probability *= p 
        newFactor.setProbability(assignments, probability)
    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 ***"
    unconditioned = []
    conditioned = []
    variableDomainsDict = {}

    if factors and len(factors) > 0:
        variableDomainsDict = factors[0].variableDomainsDict()

    for f in factors:
        temp_unconditioned = f.unconditionedVariables()
        temp_conditioned = f.conditionedVariables()
        unconditioned.extend(temp_unconditioned)
        for conditioned_var in temp_conditioned:
            if conditioned_var not in conditioned:
                conditioned.append(conditioned_var)
    conditioned = [var for var in conditioned if var not in unconditioned]

    newFactor = Factor(unconditioned, conditioned, variableDomainsDict)
    assignments = newFactor.getAllPossibleAssignmentDicts()
    for assignment in assignments:
        prob = 1
        for factor in factors:
            prob *= factor.getProbability(assignment)
        newFactor.setProbability(assignment, prob)

    return newFactor
示例#58
0
    def inferenceByVariableElimination(bayesNet, queryVariables, evidenceDict, eliminationOrder):
        """
        Question 4: Your inference by variable elimination implementation

        This function should perform a probabilistic inference query that
        returns the factor:

        P(queryVariables | evidenceDict)

        It should perform inference by interleaving joining on a variable
        and eliminating that variable, in the order of variables according
        to eliminationOrder.  See inferenceByEnumeration for an example on
        how to use these functions.

        You need to use joinFactorsByVariable to join all of the factors 
        that contain a variable in order for the autograder to 
        recognize that you performed the correct interleaving of 
        joins and eliminates.

        If a factor that you are about to eliminate a variable from has 
        only one unconditioned variable, you should not eliminate it 
        and instead just discard the factor.  This is since the 
        result of the eliminate would be 1 (you marginalize 
        all of the unconditioned variables), but it is not a 
        valid factor.  So this simplifies using the result of eliminate.

        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. 
        eliminationOrder: The order to eliminate the variables in.

        Hint: BayesNet.getAllCPTsWithEvidence will return all the Conditional 
        Probability Tables even if an empty dict (or None) is passed in for 
        evidenceDict. In this case it will not specialize any variable domains 
        in the CPTs.

        Useful functions:
        BayesNet.getAllCPTsWithEvidence
        normalize
        eliminate
        joinFactorsByVariable
        joinFactors
        """

        # this is for autograding -- don't modify
        joinFactorsByVariable = joinFactorsByVariableWithCallTracking(callTrackingList)
        eliminate             = eliminateWithCallTracking(callTrackingList)
        if eliminationOrder is None: # set an arbitrary elimination order if None given
            eliminationVariables = bayesNet.variablesSet() - set(queryVariables) -\
                                   set(evidenceDict.keys())
            eliminationOrder = sorted(list(eliminationVariables))

        "*** YOUR CODE HERE ***"
        # evidenceVariablesSet = set(evidenceDict.keys())
        # queryVariablesSet = set(queryVariables)
        # print evidenceVariablesSet
        # print queryVariables
        # print eliminationOrder
        currentFactorsList = bayesNet.getAllCPTsWithEvidence(evidenceDict)
      
        for elim_var in eliminationOrder:
            currentFactorsList, joinedFactor = joinFactorsByVariable(currentFactorsList, elim_var)
            if (len(joinedFactor.unconditionedVariables()) > 1):
                elim_factor = eliminate(joinedFactor, elim_var)
                currentFactorsList.append(elim_factor)

        fullJointOverQueryAndEvidence = joinFactors(currentFactorsList)
        queryConditionedOnEvidence = normalize(fullJointOverQueryAndEvidence)

        set_of_unconditioned = set(queryVariables)
        set_Of_variables = set(queryConditionedOnEvidence.variables())
        variable_domains = queryConditionedOnEvidence.variableDomainsDict()
        set_of_conditioned = set_Of_variables - set_of_unconditioned
        new_factor = Factor(list(set_of_unconditioned), list(set_of_conditioned), variable_domains)
        all_possible_assignments = new_factor.getAllPossibleAssignmentDicts()

        for assignment in all_possible_assignments:
            prob = queryConditionedOnEvidence.getProbability(assignment)
            new_factor.setProbability(assignment, prob)
        #print queryConditionedOnEvidence.unconditionedVariables()
        #print queryConditionedOnEvidence.conditionedVariables()
        return new_factor
示例#59
0
def joinFactors(factors):
    """
    Question 1: 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 ***"

    if len(factors) == 1:
        return factors.pop()
    first = factors.pop(0)
    firstAssignments = first.getAllPossibleAssignmentDicts()

    second = factors.pop(0)
    secondAssignments = second.getAllPossibleAssignmentDicts()

    unconditionedVariables = list(first.unconditionedVariables()) + list(
        second.unconditionedVariables())
    conditionedVariables = list(first.conditionedVariables()) + list(
        second.conditionedVariables())
    conditionedVar = []
    for var in conditionedVariables:
        if var not in unconditionedVariables:
            conditionedVar.append(var)

    conditionedVar = list(set(conditionedVar))
    newFactor = Factor(unconditionedVariables, conditionedVar,
                       first.variableDomainsDict())
    for each in newFactor.getAllPossibleAssignmentDicts():
        firstFactor = 0
        for firstEach in firstAssignments:
            if set(firstEach.items()).issubset(set(each.items())):
                firstFactor = first.getProbability(firstEach)
        secondFactor = 0
        for secondEach in secondAssignments:
            if set(secondEach.items()).issubset(set(each.items())):
                secondFactor = second.getProbability(secondEach)
        probability = firstFactor * secondFactor
        newFactor.setProbability(each, probability)

    return joinFactors(factors + [newFactor])
    util.raiseNotDefined()
示例#60
0
    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 ***"
        #print factor
        unconditioned = factor.unconditionedVariables()
        conditioned = factor.conditionedVariables()
        for item in unconditioned:
            if item == eliminationVariable:
                unconditioned.remove(item)
        for item in conditioned:
            if item == eliminationVariable:
                conditioned.remove(item)
        variableDomainsDict = factor.variableDomainsDict()

        newFactor = Factor(unconditioned, conditioned, factor.variableDomainsDict())
        # print "newFactor"
        # print newFactor

        for newPossibleAssignment in newFactor.getAllPossibleAssignmentDicts():
            # print("new possible assignment", newPossibleAssignment)
            assignment = 0
            for possibleAssignment in factor.getAllPossibleAssignmentDicts():
                if all(item in possibleAssignment.items() for item in newPossibleAssignment.items()):
                #check if newpossibleassignment is a subset of possibleassignment
                    # print("possible assignment", possibleAssignment)
                    prob = factor.getProbability(possibleAssignment)
                    # print("prob", prob)
                    assignment += prob
            newFactor.setProbability(newPossibleAssignment, assignment)
        return newFactor