예제 #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()))

        "*** 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
예제 #2
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
예제 #3
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
예제 #4
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
예제 #5
0
파일: inference.py 프로젝트: aayusht/proj4
    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
    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
예제 #7
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 ***"

        tmp = factor.unconditionedVariables()
        unconditionedVars = [x for x in tmp if x != eliminationVariable]

        newFactor = Factor(unconditionedVars, factor.conditionedVariables(), factor.variableDomainsDict())
        

        for assignmentDict in factor.getAllPossibleAssignmentDicts():
            prob = newFactor.getProbability(assignmentDict) + factor.getProbability(assignmentDict)
            newFactor.setProbability(assignmentDict, prob)

        return newFactor
예제 #8
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)
예제 #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)

        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)
예제 #10
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 ***"
        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
예제 #11
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 ***"
    # print "@@@@@@factorlength ", len(factors)
    # print "@@@@@@@factor 1", factors[0]
    # print "@@@@@@@factor 2", factors[1]
    # print "@@@@@@@variableDomainsDict ", Factor.variableDomainsDict(factors[0]), len(Factor.variableDomainsDict(factors[0]))
    # print "@@@@@@@conditionedVariables ", Factor.conditionedVariables(factors[0])
    # print "@@@@@@@getAllPossibleAssignmentDicts ", Factor.getAllPossibleAssignmentDicts(factors[0])
    # print "@@@@@@@oneassignmentdict ", Factor.getAllPossibleAssignmentDicts(factors[0])[0], Factor.getAllPossibleAssignmentDicts(factors[0])[0].get("W")
    # print "@@@@@@@getProbability ", Factor.getProbability(factors[0], Factor.getAllPossibleAssignmentDicts(factors[0])[0])
    #Factor.getAllPossibleAssignmentDicts(factors[0])
    joinedConditionedVariables = set()
    joinedUnconditionedVariables = set()
    for factor in factors:
        for condVar in factor.conditionedVariables():
            joinedConditionedVariables.add(condVar)
        for uncondVar in factor.unconditionedVariables():
            joinedUnconditionedVariables.add(uncondVar)
        # joinedConditionedVariables.union(factor.conditionedVariables())
        # joinedUnconditionedVariables.union(factor.unconditionedVariables())
        # print "@@@@@factor.unconditionedVariables() ", factor.unconditionedVariables(), type(factor.unconditionedVariables())
        # print "@@@@joinedConditionedVariables ", joinedConditionedVariables
        # print "@@@@joinedUnconditionedVariables ", joinedUnconditionedVariables
        # print "@@@@factor.conditionedVariables() ", factor.conditionedVariables()
        # print "@@@@factor.unconditionedVariables() ", factor.unconditionedVariables()

    # joinedUnconditionedVariables.remove(eliminationVariable)
    # reducedFactor = Factor(reducedUnconditionedVariables, factor.conditionedVariables(), factor.variableDomainsDict())
    for uncondVar in joinedUnconditionedVariables:
        if uncondVar in joinedConditionedVariables:
            joinedConditionedVariables.remove(uncondVar)
    # print "@@@@@@joinedUnconditionedVariables ", joinedUnconditionedVariables
    # print "@@@@@@joinedConditionedVariables ", joinedConditionedVariables
    joinedFactor = Factor(joinedUnconditionedVariables, joinedConditionedVariables, factors[0].variableDomainsDict())
    # print "@@@@joinedFactor.unconditionedVariables() ", joinedFactor.unconditionedVariables()
    # print "@@@@joinedFactor.conditionedVariables() ", joinedFactor.conditionedVariables()
    for joinedAssignment in joinedFactor.getAllPossibleAssignmentDicts():
        # print "@@@@joinedAssignment ", joinedAssignment
        factorAssignmentProduct = 1
        for factor in factors:
            # print "probability of ", joinedAssignment, Factor.getProbability(factor, joinedAssignment)
            factorAssignmentProduct = factorAssignmentProduct * Factor.getProbability(factor, joinedAssignment)
        Factor.setProbability(joinedFactor, joinedAssignment, factorAssignmentProduct)



    return joinedFactor
예제 #12
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 ***"
        # 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
예제 #13
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 ***"

        # create return factor
        newFactor = Factor(queryVariables, evidenceDict, bayesNet.variableDomainsDict())
        reducedVariableDomains = bayesNet.getReducedVariableDomains(evidenceDict)
        newFactor = newFactor.specializeVariableDomains(reducedVariableDomains)

        for i in range(numSamples):
            weight = 1.0
            allAssignments = {}
            allAssignments.update(evidenceDict)
            for var in bayesNet.linearizeVariables():

                tmpCPT = bayesNet.getCPT(var)
                if var in evidenceDict:
                    # accumulate weight
                    weight *= tmpCPT.getProbability(allAssignments)
                else:
                    newAssignment = sampleFromFactor(tmpCPT, allAssignments)
                    allAssignments.update(newAssignment)

            # accumulate sample
            p = newFactor.getProbability(allAssignments)
            newFactor.setProbability(allAssignments, p + weight)

        return normalize(newFactor)

        util.raiseNotDefined()
    def inferenceByLikelihoodWeightingSampling(bayesNet, queryVariables, evidenceDict, numSamples):
        """
        Question 6: Inference by likelihood weighted sampling

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

        P(queryVariables | evidenceDict)

        It should perform inference by performing likelihood weighting
        sampling.  It should sample numSamples times.

        In order for the autograder's solution to match yours, 
        your outer loop needs to iterate over the number of samples, 
        with the inner loop sampling from each variable's factor.
        Use the ordering of variables provided by BayesNet.linearizeVariables in 
        your inner loop so that the order of samples matches the autograder's.
        There are typically many linearization orders of a directed acyclic 
        graph (DAG), however we just use a particular one.

        The sum of the probabilities should sum to one (so that it is a true 
        conditional probability, conditioned on the evidence).

        bayesNet:       The Bayes Net on which we are making a query.
        queryVariables: A list of the variables which are unconditioned in
                        the inference query.
        evidenceDict:   An assignment dict {variable : value} for the
                        variables which are presented as evidence
                        (conditioned) in the inference query. 
        numSamples:     The number of samples that should be taken.


        Useful functions:
        sampleFromFactor
        normalize
        BayesNet.getCPT
        BayesNet.linearizeVariables
        """

        sampleFromFactor = sampleFromFactorRandomSource(randomSource)

        "*** YOUR CODE HERE ***"
        # create 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
예제 #15
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 ***"
        'sample = None'
        
        setsOfUnconditioned = set(queryVariables)
        setsOfConditioned = set(evidenceDict.keys())
        vDD = bayesNet.getReducedVariableDomains(evidenceDict)
        newFactor = Factor(setsOfUnconditioned, setsOfConditioned, vDD)
        
        sample = evidenceDict.copy()
        
        for i in range(numSamples):
            weight = 1.0
            for v in bayesNet.linearizeVariables():
                f = bayesNet.getCPT(v)
                'f = f.specializeVariableDomains(vDD)'
                if v in evidenceDict.keys():
                    weight = weight * f.getProbability(sample)
                    '''s = 0.0
                    sumAD = 0.0
                    for ad in f.getAllPossibleAssignmentDicts():
                        if all(item in ad.items() for item in evidenceDict.items()):
                            s += f.getProbability(ad)
                        sumAD += f.getProbability(ad)
                    weight = weight * s / sumAD'''
                else:
                    sample.update(sampleFromFactor(f, sample))
            newFactor.setProbability(sample, newFactor.getProbability(sample) + weight)
            
            sample = evidenceDict.copy()
            
            'sample = None'
        'pdb.set_trace()'
        '''totalSum = sum(sampleDict.values())
        all(item in aD.items() for item in ad.items()):'''
        
        newFactor = normalize(newFactor)
        return newFactor
예제 #16
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 ***"
    # util.raiseNotDefined()

    unconVars = set()
    conVars = set()
    varMap = {}

    def factorizer(factVariables, condi, varsy):
        for p in factVariables:
            if condi(p):
                varsy.add(p)
                varMap[p] = factor.variableDomainsDict()[p]

    [
        factorizer(f.unconditionedVariables(), lambda x: (x not in unconVars),
                   unconVars) for f in factors
    ]
    [
        factorizer(f.conditionedVariables(), lambda x:
                   (x not in unconVars and x not in conVars), conVars)
        for f in factors
    ]
    nuFact = Factor(list(unconVars), list(conVars), varMap)
    [
        nuFact.setProbability(n, float(1.0))
        for n in nuFact.getAllPossibleAssignmentDicts()
    ]
    for factor in factors:
        for n in nuFact.getAllPossibleAssignmentDicts():
            for fm in factor.getAllPossibleAssignmentDicts():
                works = True
                for var in fm.keys():
                    works = fm[var] == n[var]
                    if not works: break
                if works:
                    nuFact.setProbability(
                        n,
                        factor.getProbability(fm) * nuFact.getProbability(n))
                    break

    return nuFact
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 of unconditionedVariables
    ucs = {""}
    ucs.clear()
    # Conditioned Set of conditionedVariables
    cs = {""}
    cs.clear()
    # set default probability
    defaultProbability = 1.0

    # removes the unconditionedVariable from the conditioned variable set
    def removeUCVfromCS(uv, cs):
        if uv in cs:
            cs.remove(uv)

    # the union of unconditioned set with unconditioned variable
    def uniteUCS(ucs, uv):
        return ucs.union(uv)

    # the union of condiitoned set with conditioned variable
    def uniteCS(cs, cv):
        return cs.union(cv)

    # product of the corresponding rows of the input factors
    def product(jfp, fp):
        return jfp * fp

    for factor in factors:
        ucs = uniteUCS(ucs, factor.unconditionedVariables())
        cs = uniteCS(cs, factor.conditionedVariables())

    for unconditionedVariable in ucs:
        removeUCVfromCS(unconditionedVariable, cs)

    joinedFactor = Factor(ucs, cs, factor.variableDomainsDict())
    assignments = joinedFactor.getAllPossibleAssignmentDicts()

    for assign in assignments:
        joinedFactor.setProbability(assign, defaultProbability)

        for factor in factors:
            prob = product(joinedFactor.getProbability(assign),
                           factor.getProbability(assign))
            joinedFactor.setProbability(assign, prob)

    return joinedFactor

    util.raiseNotDefined()
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
    ]
    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 ***"
    # Combine conditioned/unconditioned variables(sets)
    conditionedList = set()
    unconditionedList = set()
    for s in setsOfConditioned:
        conditionedList = conditionedList | s
    for s in setsOfUnconditioned:
        unconditionedList = unconditionedList | s
    conditionedList = conditionedList - unconditionedList
    conditionedList = list(conditionedList)
    unconditionedList = list(unconditionedList)

    # Define new factor with variables.
    newFactor = Factor(unconditionedList, conditionedList,
                       factor.variableDomainsDict())

    # Initialize probability to 1.0
    for assignment in newFactor.getAllPossibleAssignmentDicts():
        newFactor.setProbability(assignment, 1.0)

    # Calculate joined probability(multiplying accumulatively).
    for factor in factors:
        for assignment in newFactor.getAllPossibleAssignmentDicts():
            items = list(assignment.items())
            for oldAssignment in factor.getAllPossibleAssignmentDicts():
                oldItems = list(oldAssignment.items())
                find = False
                for o in oldItems:
                    if o not in items:
                        find = True
                        break
                if find:
                    continue
                newFactor.setProbability(
                    assignment,
                    newFactor.getProbability(assignment) *
                    factor.getProbability(oldAssignment))
    # Return.
    return newFactor
예제 #19
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 ***"
        # print ("evidence",evidenceDict)
        unconditioned = evidenceDict.keys()
        sampleToWeightList = [] #list of tuples, each tuple is of type(dictionary, weight)
        weights = []
        count = 0
        reduced = bayesNet.getReducedVariableDomains(evidenceDict)
        # itemsToRemove =[]
        # for item in reduced:
        #     print item
        #     if (item not in queryVariables) or (item not in evidenceDict):
        #         print "removed"
        #         itemsToRemove.append(item)
        # for item in itemsToRemove:
        #     reduced.pop(item)
        # print ("reduced", reduced)
        # print ("queryVariables", queryVariables)
        # print("linearized", bayesNet.linearizeVariables())
        # print ("BAYES NET")
        # print bayesNet
 
        sample = {}
        while count != numSamples:
            sample = {}
            weight = 1
            for variable in bayesNet.linearizeVariables():
                # print ("variable", variable)
                # print("sample", sample)
                factor = bayesNet.getCPT(variable)
                if variable in evidenceDict.keys():
                    # print ("presample", sample)
                    sample.update({variable: evidenceDict[variable]})
                    # print("post", sample)
                    prob = factor.getProbability(sample)
                    # print ("prob", prob)
                    weight = weight * prob
                else:
                    assignmentDict = sampleFromFactor(factor, sample)
                    sample.update(assignmentDict)
                    # print ("appended", assignmentDict)
                    # print (sample)
                # print "=========="
            tup = (sample, weight)
            sampleToWeightList.append(tup)
            count += 1
            # print("====================================")
            
        # conditioned = queryVariables
        # conditionedFactor = Factor(queryVariables, [], bayesNet.variableDomainsDict())
        # print "conditionedFactor"
        # print conditionedFactor
        # conditionedDomain = conditionedFactor.variableDomainsDict()
        # print ("conditionedDomain", conditionedDomain)
        # unconditionedFactor = Factor(unconditioned, [], bayesNet.variableDomainsDict())
        # unconditionedDomain = unconditionedFactor.variableDomainsDict()
        # print "unconditionedFactor"
        # print unconditionedFactor
        # print ("unconditionedDomain", unconditionedDomain)
        # print "AAAAAAA"
        # print sampleToWeightList
        answer = Factor(queryVariables, unconditioned, reduced)
        #print ("answer domain ", answer.variableDomainsDict())

        for assignment in answer.getAllPossibleAssignmentDicts():
            print assignment
            sum0 = 0
            for tup in sampleToWeightList:
                if all(item in tup[0].items() for item in assignment.items()):
                #if "assignment" is a subset of the sample, which is stored in the tuple in the list of tuples
                    sum0 += tup[1]
            # print ("sum0", sum0)
            # print ("set assignment:")
            # print assignment
            # print "to be "
            # print answer.getProbability(assignment) + sum0
            answer.setProbability(assignment, answer.getProbability(assignment) + sum0)
        # print answer
        answer = normalize(answer)
        return answer
예제 #20
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 ***"

        linearizeVars = bayesNet.linearizeVariables()
        varDomainsDict = bayesNet.variableDomainsDict()

        # create a new factor
        queryEvidenceDomainsDict = {}
        for query in queryVariables:
            queryEvidenceDomainsDict[query] = varDomainsDict[query]
        for evidence, value in evidenceDict.items():
            queryEvidenceDomainsDict[evidence] = [value]
        sampleFactor = Factor(queryVariables, evidenceDict, queryEvidenceDomainsDict)
        #number of samples to take
        for x in xrange(1,numSamples+1):
            w = 1.0
            sampleVars = {} #vars set and encountered so far, including both the unconditioned and conditioned variables
            for var in linearizeVars:
                if var in evidenceDict.keys(): #if var is an evidence variable
                    factor = bayesNet.getCPT(var)
                    sampleVars[var] = evidenceDict[var]
                    probability = factor.getProbability(sampleVars)
                    w = w * probability
                else: #take a sample
                    sampleDict = sampleFromFactor(bayesNet.getCPT(var), sampleVars)
                    sampleVars.update(sampleDict)
            #update the corresponding row in the factor
            sampleFactor.setProbability(sampleVars, w+(sampleFactor.getProbability(sampleVars)))
        return normalize(sampleFactor)
        util.raiseNotDefined()
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 ***"
    new_uncond = []
    new_cond = []
    new_var_domain = {}
    for i in factors:
        for j in i.unconditionedVariables():
            if j not in new_uncond:
                new_uncond.append(j)
    for i in factors:
        for j in i.conditionedVariables():
            if j not in new_cond and j not in new_uncond:
                new_cond.append(j)
    for i in factors:
        new_var_domain = dict(new_var_domain.items() +
                              i.variableDomainsDict().items())

    new_factor = Factor(new_uncond, new_cond, new_var_domain)
    assignments = new_factor.getAllPossibleAssignmentDicts()
    for assignment in assignments:
        new_factor.setProbability(assignment, 1)
    for assignment in assignments:
        for factor in factors:
            p = new_factor.getProbability(assignment) * factor.getProbability(
                assignment)
            new_factor.setProbability(assignment, p)
    return new_factor
예제 #22
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)))

    uc = []
    c = []

    for factor in factors:
        for var in factor.unconditionedVariables():
            uc += [var]
    for factor in factors:
        for var in factor.conditionedVariables():
            if var not in uc:
                c += [var]

    joinedFactor = Factor(set(uc), set(c), factors[0].variableDomainsDict())

    for a in joinedFactor.getAllPossibleAssignmentDicts():
        joinedFactor.setProbability(a, 1)

    for a in joinedFactor.getAllPossibleAssignmentDicts():
        for factor in factors:
            newprob = factor.getProbability(a) * joinedFactor.getProbability(a)
            joinedFactor.setProbability(a, newprob)

    return joinedFactor
예제 #23
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 ***"
    domain = factor.variableDomainsDict()
    conVars = [a for a in factor.conditionedVariables()]
    unconVars = factor.unconditionedVariables()
    newunconVars = []
    eleVars = []
    for var in unconVars:
        if len(domain[var]) == 1:
            conVars.append(var)
            eleVars.append(var)
        else:
            newunconVars.append(var)

    res = Factor(newunconVars, conVars, factor.variableDomainsDict())
    probList = [
        factor.getProbability(a)
        for a in factor.getAllPossibleAssignmentDicts()
    ]
    if sum(probList) < 1e-10:
        return None

    for assignment in res.getAllPossibleAssignmentDicts():
        res.setProbability(assignment,
                           factor.getProbability(assignment) / sum(probList))

    for var in eleVars:
        tmpSum = 0.
        for assignment in res.getAllPossibleAssignmentDicts():
            if superDict(assignment, {var: domain[var][0]}):
                tmpSum += res.getProbability(assignment)
        for assignment in res.getAllPossibleAssignmentDicts():
            res.setProbability(assignment,
                               res.getProbability(assignment) / tmpSum)

    return res
    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 ***"
        # Combine conditioned/unconditioned variables(sets)
        conditionedList = list(
            factor.conditionedVariables().difference(eliminationVariable))
        unconditionedList = list(
            factor.unconditionedVariables().difference(eliminationVariable))
        if eliminationVariable in unconditionedList:
            unconditionedList.remove(eliminationVariable)
        if eliminationVariable in conditionedList:
            conditionedList.remove(eliminationVariable)

        # Define new factor with variables.
        newFactor = Factor(unconditionedList, conditionedList,
                           factor.variableDomainsDict())

        # Iterate through new factor and assign probability.
        for assignment in factor.getAllPossibleAssignmentDicts():
            items = list(assignment.items())
            for assign in newFactor.getAllPossibleAssignmentDicts():
                newItems = list(assign.items())
                find = False
                for o in newItems:
                    if o not in items:
                        find = True
                        break
                if find:
                    continue
                newFactor.setProbability(
                    assign,
                    newFactor.getProbability(assign) +
                    factor.getProbability(assignment))

        # Return.
        return newFactor
예제 #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 ***"
    unconVars = []
    varDomainDict = {}
    for factor in factors:
        for var in factor.unconditionedVariables():
            if var not in unconVars and var not in unconVars:
                unconVars.append(var)
            if var not in varDomainDict:
                varDomainDict[var] = factor.variableDomainsDict()[var]
    conVars = []
    for factor in factors:
        for var in factor.conditionedVariables():
            if var not in unconVars and var not in conVars:
                conVars.append(var)
            if var not in varDomainDict:
                varDomainDict[var] = factor.variableDomainsDict()[var]

    res = Factor(unconVars, conVars, varDomainDict)

    for assignment in res.getAllPossibleAssignmentDicts():
        res.setProbability(assignment, 1.)
    for factor in factors:
        factorAssigns = factor.getAllPossibleAssignmentDicts()
        for assignment in res.getAllPossibleAssignmentDicts():
            for factorAssign in factorAssigns:
                if superDict(assignment, factorAssign):
                    res.setProbability(
                        assignment,
                        factor.getProbability(factorAssign) *
                        res.getProbability(assignment))

    return res
    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
예제 #27
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()))

        newConditionedVars = set()
        newUnconditionedVars = set()
        for c in factor.conditionedVariables():
            newConditionedVars.add(c)
        for u in factor.unconditionedVariables():
            newUnconditionedVars.add(u)
                
        for u in newUnconditionedVars:
            if u in newConditionedVars:
                newConditionedVars.remove(u)
        if eliminationVariable in newConditionedVars:
            newConditionedVars.remove(eliminationVariable)
        if eliminationVariable in newUnconditionedVars:
			newUnconditionedVars.remove(eliminationVariable)
                
        NewFactor = Factor(newUnconditionedVars, newConditionedVars, factor.variableDomainsDict())
        for d in factor.getAllPossibleAssignmentDicts():
			#add the probs where the d is the same minus elim var
			newDict = dict(d)
			newDict.pop(eliminationVariable)
			prob = NewFactor.getProbability(newDict)+factor.getProbability(d)
			NewFactor.setProbability(newDict, prob)
        return NewFactor
예제 #28
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 ***"

        #create return factor
        newFactor = Factor(queryVariables, evidenceDict, bayesNet.variableDomainsDict())
        reducedVariableDomains = bayesNet.getReducedVariableDomains(evidenceDict)
        newFactor = newFactor.specializeVariableDomains(reducedVariableDomains)
        
        for i in range(numSamples):
            weight = 1.0
            allAssignments = {}
            allAssignments.update(evidenceDict)
            for var in bayesNet.linearizeVariables():

                tmpCPT = bayesNet.getCPT(var)
                if var in evidenceDict:
                    #accumulate weight
                    weight *= tmpCPT.getProbability(allAssignments)
                else:
                    newAssignment = sampleFromFactor(tmpCPT, allAssignments)
                    allAssignments.update(newAssignment)

            #accumulate sample
            p = newFactor.getProbability(allAssignments)
            newFactor.setProbability(allAssignments, p + weight)

        return normalize(newFactor)


        util.raiseNotDefined()
예제 #29
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 ***"
        # since we only can eliminate unconditional variables
        unconditionedVar = factor.unconditionedVariables()
        unconditionedVar.remove(eliminationVariable)
        newFactor = Factor(unconditionedVar, factor.conditionedVariables(),
                           factor.variableDomainsDict())

        for assign in newFactor.getAllPossibleAssignmentDicts():
            prob = 0.0
            for eliminate in factor.variableDomainsDict()[eliminationVariable]:
                old_assign = assign
                print "1", old_assign
                old_assign[eliminationVariable] = eliminate
                print "2", old_assign
                prob = prob + Factor.getProbability(factor, old_assign)
            Factor.setProbability(newFactor, assign, prob)

        return newFactor
def eliminateWithCallTracking(callTrackingList=None):
    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()))

        joinedConditionedVariables = set()

    joinedUnconditionedVariables = set()
    for factor in factors:
        for condVar in factor.conditionedVariables():
            joinedConditionedVariables.add(condVar)
        for uncondVar in factor.unconditionedVariables():
            joinedUnconditionedVariables.add(uncondVar)
        # joinedConditionedVariables.union(factor.conditionedVariables())
        # joinedUnconditionedVariables.union(factor.unconditionedVariables())
        # print "@@@@@factor.unconditionedVariables() ", factor.unconditionedVariables(), type(factor.unconditionedVariables())
        # print "@@@@joinedConditionedVariables ", joinedConditionedVariables
        # print "@@@@joinedUnconditionedVariables ", joinedUnconditionedVariables
        # print "@@@@factor.conditionedVariables() ", factor.conditionedVariables()
        # print "@@@@factor.unconditionedVariables() ", factor.unconditionedVariables()

    # joinedUnconditionedVariables.remove(eliminationVariable)
    # reducedFactor = Factor(reducedUnconditionedVariables, factor.conditionedVariables(), factor.variableDomainsDict())
    for uncondVar in joinedUnconditionedVariables:
        if uncondVar in joinedConditionedVariables:
            joinedConditionedVariables.remove(uncondVar)
    # print "@@@@@@joinedUnconditionedVariables ", joinedUnconditionedVariables
    # print "@@@@@@joinedConditionedVariables ", joinedConditionedVariables
    joinedFactor = Factor(joinedUnconditionedVariables,
                          joinedConditionedVariables,
                          factors[0].variableDomainsDict())
    # print "@@@@joinedFactor.unconditionedVariables() ", joinedFactor.unconditionedVariables()
    # print "@@@@joinedFactor.conditionedVariables() ", joinedFactor.conditionedVariables()
    for joinedAssignment in joinedFactor.getAllPossibleAssignmentDicts():
        # print "@@@@joinedAssignment ", joinedAssignment
        factorAssignmentProduct = 1
        for factor in factors:
            # print "probability of ", joinedAssignment, Factor.getProbability(factor, joinedAssignment)
            factorAssignmentProduct = factorAssignmentProduct * Factor.getProbability(
                factor, joinedAssignment)
        Factor.setProbability(joinedFactor, joinedAssignment,
                              factorAssignmentProduct)

    return joinedFactor
예제 #31
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 ***"
    conditionedVar = []
    unconditionedVar = []
    for condition in factor.conditionedVariables():
        if condition not in conditionedVar:
            conditionedVar.append(condition)
    for unconditioned in factor.unconditionedVariables():
        if unconditioned not in (unconditionedVar):
            unconditionedVar.append(unconditioned)

    prob_sum = 0.0
    for assign in factor.getAllPossibleAssignmentDicts():
        prob_sum = prob_sum + Factor.getProbability(factor, assign)
    if prob_sum == 0:
        return None

    # add with one entry
    for var in unconditionedVar:
        if len(factor.variableDomainsDict()
               [var]) == 1 and var not in conditionedVar:
            conditionedVar.append(var)
    unconditionedVar = [
        var for var in unconditionedVar if var not in conditionedVar
    ]

    newFactor = Factor(unconditionedVar, conditionedVar,
                       factor.variableDomainsDict())
    for assign in newFactor.getAllPossibleAssignmentDicts():
        prob = Factor.getProbability(factor, assign) / prob_sum
        Factor.setProbability(newFactor, assign, prob)

    return newFactor
예제 #32
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
    factors = list(factors)
    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 ***"
    joinedConditionedVariables = set()
    joinedUnconditionedVariables = set()
    for factor in factors:
        for condVar in factor.conditionedVariables():
            joinedConditionedVariables.add(condVar)
        for uncondVar in factor.unconditionedVariables():
            joinedUnconditionedVariables.add(uncondVar)
    for uncondVar in joinedUnconditionedVariables:
        if uncondVar in joinedConditionedVariables:
            joinedConditionedVariables.remove(uncondVar)
    joinedFactor = Factor(joinedUnconditionedVariables, joinedConditionedVariables, factors[0].variableDomainsDict())
    for joinedAssignment in joinedFactor.getAllPossibleAssignmentDicts():
        factorAssignmentProduct = 1
        for factor in factors:
            factorAssignmentProduct = factorAssignmentProduct * Factor.getProbability(factor, joinedAssignment)
        Factor.setProbability(joinedFactor, joinedAssignment, factorAssignmentProduct)

    return joinedFactor
예제 #33
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 ***"
    conditionedVar = []
    unconditionedVar = []
    for factor in factors:
        for condition in factor.conditionedVariables():
            if condition not in conditionedVar:
                conditionedVar.append(condition)
        for unconditioned in factor.unconditionedVariables():
            if unconditioned not in (unconditionedVar):
                unconditionedVar.append(unconditioned)

    print factors
    print unconditionedVar
    print conditionedVar

    conditionedVar = [
        var for var in conditionedVar if var not in unconditionedVar
    ]
    """for var in unconditionedVar:
        if var in conditionedVar:
            conditionedVar.remove(var)"""

    newFactor = Factor(unconditionedVar, conditionedVar,
                       factors[0].variableDomainsDict())
    for assign in newFactor.getAllPossibleAssignmentDicts():
        prob = 1.0
        for factor in factors:
            prob = prob * Factor.getProbability(factor, assign)
        Factor.setProbability(newFactor, assign, prob)

    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
예제 #35
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)))

    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