コード例 #1
0
class TestSampleAggregator(unittest.TestCase):
    
    def setUp(self):
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()
        nodedata = NodeData()
        nodedata.load("unittestdict.txt")
        self.bn = DiscreteBayesianNetwork(skel, nodedata)
        agg = SampleAggregator()
        agg.aggregate(self.bn.randomsample(50))
        self.rseq = agg.seq
        self.ravg = agg.avg
        self.fn = TableCPDFactorization(self.bn)
        evidence = dict(Letter='weak')
        agg.aggregate(self.fn.gibbssample(evidence, 51))
        self.gseq = agg.seq
        self.gavg = agg.avg
        
    def test_rseq(self):
        self.assertTrue(len(self.rseq) == 50)
        for key in self.ravg.keys():
            summ = 0 
            for entry in self.ravg[key].keys():
                summ += self.ravg[key][entry]
            self.assertTrue(summ > .99 and summ < 1.01)
            
    def test_gseq(self):
        self.assertTrue(len(self.gseq) == 51)
        for key in self.gavg.keys():
            summ = 0 
            for entry in self.gavg[key].keys():
                summ += self.gavg[key][entry]
            self.assertTrue(summ > .99 and summ < 1.01)
コード例 #2
0
ファイル: run_unit_tests.py プロジェクト: CyberPoint/libpgm
class TestSampleAggregator(unittest.TestCase):

    def setUp(self):
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()
        nodedata = NodeData()
        nodedata.load("unittestdict.txt")
        self.bn = DiscreteBayesianNetwork(skel, nodedata)
        agg = SampleAggregator()
        agg.aggregate(self.bn.randomsample(50))
        self.rseq = agg.seq
        self.ravg = agg.avg
        self.fn = TableCPDFactorization(self.bn)
        evidence = dict(Letter='weak')
        agg.aggregate(self.fn.gibbssample(evidence, 51))
        self.gseq = agg.seq
        self.gavg = agg.avg

    def test_rseq(self):
        self.assertTrue(len(self.rseq) == 50)
        for key in self.ravg.keys():
            summ = 0
            for entry in self.ravg[key].keys():
                summ += self.ravg[key][entry]
            self.assertTrue(summ > .99 and summ < 1.01)

    def test_gseq(self):
        self.assertTrue(len(self.gseq) == 51)
        for key in self.gavg.keys():
            summ = 0
            for entry in self.gavg[key].keys():
                summ += self.gavg[key][entry]
            self.assertTrue(summ > .99 and summ < 1.01)
コード例 #3
0
ファイル: run_unit_tests.py プロジェクト: Anaphory/libpgm
class TestDiscreteBayesianNetwork(unittest.TestCase):

    def setUp(self):
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()
        nodedata = NodeData.load("unittestdict.txt")
        self.instance = DiscreteBayesianNetwork(nodedata)

    def test_randomsample(self):
        randomsample = self.instance.randomsample(5)
        self.assertTrue(randomsample[0]["Difficulty"] == 'easy' or randomsample[0]["Difficulty"] == 'hard')
        for key in randomsample[0].keys():
            self.assertTrue(randomsample[0][key] != "default")

    def test_randomsamplewithevidence(self):
    	evidence = dict(Difficulty='easy')
    	randomsample = self.instance.randomsample(10, evidence)
    	for entry in randomsample:
    		self.assertEqual(entry["Difficulty"], 'easy')
コード例 #4
0
ファイル: run_unit_tests.py プロジェクト: Anaphory/libpgm
class TestDiscreteBayesianNetwork(unittest.TestCase):
    def setUp(self):
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()
        nodedata = NodeData.load("unittestdict.txt")
        self.instance = DiscreteBayesianNetwork(nodedata)

    def test_randomsample(self):
        randomsample = self.instance.randomsample(5)
        self.assertTrue(randomsample[0]["Difficulty"] == 'easy'
                        or randomsample[0]["Difficulty"] == 'hard')
        for key in randomsample[0].keys():
            self.assertTrue(randomsample[0][key] != "default")

    def test_randomsamplewithevidence(self):
        evidence = dict(Difficulty='easy')
        randomsample = self.instance.randomsample(10, evidence)
        for entry in randomsample:
            self.assertEqual(entry["Difficulty"], 'easy')
コード例 #5
0
def createData():
   nd = NodeData()
   skel = GraphSkeleton()
   fpath = "job_interview.txt"
   nd.load(fpath)
   skel.load(fpath)
   skel.toporder()
   bn = DiscreteBayesianNetwork(skel, nd)

   learner = PGMLearner()
   data = bn.randomsample(1000)
   X, Y = 'Grades', 'Offer'
   c,p,w=learner.discrete_condind(data, X, Y, ['Interview'])
   print "independence between X and Y: ", c, " p-value ", p, " witness node: ", w
   result = learner.discrete_constraint_estimatestruct(data)
   print result.E
コード例 #6
0
    def test_structure_estimation(self):
        req = DiscreteStructureEstimationRequest()

        skel = GraphSkeleton()
        skel.load(self.data_path)
        skel.toporder()
        teacher_nd = NodeData()
        teacher_nd.load(self.teacher_data_path)
        bn = DiscreteBayesianNetwork(skel, teacher_nd)
        data = bn.randomsample(8000)
        for v in data:
            gs = DiscreteGraphState()
            for k_s, v_s in v.items():
                gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
            req.states.append(gs)

        res = self.struct_estimate(req)
        self.assertIsNotNone(res.graph)
        self.assertEqual(len(res.graph.nodes), 5)
        self.assertGreater(len(res.graph.edges), 0)
コード例 #7
0
    def test_structure_estimation(self):
        req = DiscreteStructureEstimationRequest()

        skel = GraphSkeleton()
        skel.load(self.data_path)
        skel.toporder()
        teacher_nd = NodeData()
        teacher_nd.load(self.teacher_data_path)
        bn = DiscreteBayesianNetwork(skel, teacher_nd)
        data = bn.randomsample(8000)
        for v in data:
            gs = DiscreteGraphState()
            for k_s, v_s in v.items():
                gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
            req.states.append(gs)

        res = self.struct_estimate(req)
        self.assertIsNotNone(res.graph)
        self.assertEqual(len(res.graph.nodes), 5)
        self.assertGreater(len(res.graph.edges), 0)
コード例 #8
0
    def test_param_estimation(self):
        req = DiscreteParameterEstimationRequest()

        # load graph structure
        skel = GraphSkeleton()
        skel.load(self.data_path)
        req.graph.nodes = skel.V
        req.graph.edges = [GraphEdge(k, v) for k, v in skel.E]
        skel.toporder()

        # generate trial data
        teacher_nd = NodeData()
        teacher_nd.load(self.teacher_data_path)
        bn = DiscreteBayesianNetwork(skel, teacher_nd)
        data = bn.randomsample(200)
        for v in data:
            gs = DiscreteGraphState()
            for k_s, v_s in v.items():
                gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
            req.states.append(gs)

        self.assertEqual(len(self.param_estimate(req).nodes), 5)
コード例 #9
0
    def test_param_estimation(self):
        req = DiscreteParameterEstimationRequest()

        # load graph structure
        skel = GraphSkeleton()
        skel.load(self.data_path)
        req.graph.nodes = skel.V
        req.graph.edges = [GraphEdge(k, v) for k,v in skel.E]
        skel.toporder()

        # generate trial data
        teacher_nd = NodeData()
        teacher_nd.load(self.teacher_data_path)
        bn = DiscreteBayesianNetwork(skel, teacher_nd)
        data = bn.randomsample(200)
        for v in data:
            gs = DiscreteGraphState()
            for k_s, v_s in v.items():
                gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
            req.states.append(gs)

        self.assertEqual(len(self.param_estimate(req).nodes), 5)
コード例 #10
0
class TestPGMLearner(unittest.TestCase):
    
    def setUp(self):
        # instantiate learner
        self.l = PGMLearner()

        # generate graph skeleton
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()

        # generate sample sequence to try to learn from - discrete
        nd = NodeData()
        nd.load("unittestdict.txt")
        self.samplediscbn = DiscreteBayesianNetwork(skel, nd)
        self.samplediscseq = self.samplediscbn.randomsample(5000)

        # generate sample sequence to try to learn from - discrete
        nda = NodeData()
        nda.load("unittestlgdict.txt")
        self.samplelgbn = LGBayesianNetwork(skel, nda)
        self.samplelgseq = self.samplelgbn.randomsample(10000)

        self.skel = skel

    def test_discrete_mle_estimateparams(self):
        result = self.l.discrete_mle_estimateparams(self.skel, self.samplediscseq)
        indexa = result.Vdata['SAT']['vals'].index('lowscore')
        self.assertTrue(result.Vdata['SAT']['cprob']["['low']"][indexa] < 1 and result.Vdata['SAT']['cprob']["['low']"][indexa] > .9)
        indexb = result.Vdata['Letter']['vals'].index('weak')
        self.assertTrue(result.Vdata['Letter']['cprob']["['A']"][indexb] < .15 and result.Vdata['Letter']['cprob']["['A']"][indexb] > .05)

    def test_lg_mle_estimateparams(self):
        result = self.l.lg_mle_estimateparams(self.skel, self.samplelgseq)
        self.assertTrue(result.Vdata['SAT']['mean_base'] < 15 and result.Vdata['SAT']['mean_base'] > 5)
        self.assertTrue(result.Vdata['Letter']['variance'] < 15 and result.Vdata['Letter']['variance'] > 5)

    def test_discrete_constraint_estimatestruct(self):
        result = self.l.discrete_constraint_estimatestruct(self.samplediscseq)
        self.assertTrue(["Difficulty", "Grade"] in result.E)

    def test_lg_constraint_estimatestruct(self):
        result = self.l.lg_constraint_estimatestruct(self.samplelgseq)
        self.assertTrue(["Intelligence", "Grade"] in result.E)

    def test_discrete_condind(self):
        chi, pv, witness = self.l.discrete_condind(self.samplediscseq, "Difficulty", "Letter", ["Grade"])
        self.assertTrue(pv > .05)
        self.assertTrue(witness, ["Grade"])
        chia, pva, witnessa = self.l.discrete_condind(self.samplediscseq, "Difficulty", "Intelligence", [])  
        self.assertTrue(pva < .05)

    def test_discrete_estimatebn(self):
        result = self.l.discrete_estimatebn(self.samplediscseq)
        self.assertTrue(result.V)
        self.assertTrue(result.E)
        self.assertTrue(result.Vdata["Difficulty"]["cprob"][0])

    def test_lg_estimatebn(self):
        result = self.l.lg_estimatebn(self.samplelgseq)
        self.assertTrue(result.V)
        self.assertTrue(result.E)
        self.assertTrue(result.Vdata["Intelligence"]["mean_base"])
    rospy.init_node("pgm_learner_sample_discrete")

    param_estimate = rospy.ServiceProxy(
        "pgm_learner/discrete/parameter_estimation",
        DiscreteParameterEstimation)

    req = DiscreteParameterEstimationRequest()

    dpath = os.path.join(PKG_PATH, "test", "graph-test.txt")
    tpath = dpath

    # load graph structure
    skel = GraphSkeleton()
    skel.load(dpath)
    req.graph.nodes = skel.V
    req.graph.edges = [GraphEdge(k, v) for k, v in skel.E]
    skel.toporder()

    # generate trial data
    teacher_nd = NodeData()
    teacher_nd.load(dpath)
    bn = DiscreteBayesianNetwork(skel, teacher_nd)
    data = bn.randomsample(200)
    for v in data:
        gs = DiscreteGraphState()
        for k_s, v_s in v.items():
            gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
        req.states.append(gs)

    PP.pprint(param_estimate(req).nodes)
コード例 #12
0
# Generate a sequence of samples from a discrete-CPD Bayesian network

# load nodedata and graphskeleton
nd = NodeData()
skel = GraphSkeleton()
nd.load("../tests/unittestdict.txt")
skel.load("../tests/unittestdict.txt")

# topologically order graphskeleton
skel.toporder()

# load bayesian network
bn = DiscreteBayesianNetwork(skel, nd)

# sample
result = bn.randomsample(10)

# output - toggle comment to see
#print json.dumps(result, indent=2)

# (2) ----------------------------------------------------------------------
# Generate a sequence of samples from a linear Gaussian-CPD Bayesian network

# load nodedata and graphskeleton
nd = NodeData()
skel = GraphSkeleton()
nd.load("../tests/unittestlgdict.txt")
skel.load("../tests/unittestdict.txt")

# topologically order graphskeleton
skel.toporder()
if __name__ == '__main__':
    rospy.init_node("pgm_learner_sample_discrete")

    param_estimate = rospy.ServiceProxy("pgm_learner/discrete/parameter_estimation", DiscreteParameterEstimation)

    req = DiscreteParameterEstimationRequest()

    dpath = os.path.join(PKG_PATH, "test", "graph-test.txt")
    tpath = dpath

    # load graph structure
    skel = GraphSkeleton()
    skel.load(dpath)
    req.graph.nodes = skel.V
    req.graph.edges = [GraphEdge(k, v) for k,v in skel.E]
    skel.toporder()

    # generate trial data
    teacher_nd = NodeData()
    teacher_nd.load(dpath)
    bn = DiscreteBayesianNetwork(skel, teacher_nd)
    data = bn.randomsample(200)
    for v in data:
        gs = DiscreteGraphState()
        for k_s, v_s in v.items():
            gs.node_states.append(DiscreteNodeState(node=k_s, state=v_s))
        req.states.append(gs)

    PP.pprint(param_estimate(req).nodes)
コード例 #14
0
import json

from libpgm.nodedata import NodeData
from libpgm.graphskeleton import GraphSkeleton
from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork
from libpgm.pgmlearner import PGMLearner

# generate some data to use
nd = NodeData()
nd.load("grades.txt")  # an input file
skel = GraphSkeleton()
skel.load("grades.txt")
skel.toporder()
bn = DiscreteBayesianNetwork(skel, nd)
data = bn.randomsample(80000)

# instantiate my learner
learner = PGMLearner()

# estimate structure
result = learner.discrete_constraint_estimatestruct(data)

# output
print json.dumps(result.E, indent=2)
コード例 #15
0
    "X3": '1'
}]
X1arms = {0: 0, 1: 1}
X2arms = {0: 2, 1: 3}
X3arms = {0: 4, 1: 5}

regrets2 = []
progress = 0
for i in range(simulations):
    if (100 * i) / simulations != progress:
        progress += 1
        print "part2", progress, "%"
    bandit = NetworkBetaBandit(bn, interventions, 'Y')
    for j in xrange(experiments):
        arm = bandit.get_recommendation()
        result = bn.randomsample(1, evidence=bandit.interventions[arm])[0]

        # add results for two arms, one for what X1 was and one for what X2 was
        a1 = X1arms.get(int(result.get("X1")))
        a2 = X2arms.get(int(result.get("X2")))
        a3 = X3arms.get(int(result.get("X3")))
        reward = result.get('Y')
        bandit.add_result(a1, reward)
        bandit.add_result(a2, reward)
        bandit.add_result(a3, reward)
        regrets2.append(bandit.regret(.4))

# a rough estimate how well we do with Causal Bayes Bandit - appears empirically better even in this setting. Now verify theoretically
#print np.mean(regrets2),"+-", stats.sem(regrets2)
o = open("causalreinforceresults.txt", "w")
for i in xrange(simulations):
コード例 #16
0
ファイル: run_unit_tests.py プロジェクト: CyberPoint/libpgm
class TestPGMLearner(unittest.TestCase):

    def setUp(self):
        # instantiate learner
        self.l = PGMLearner()

        # generate graph skeleton
        skel = GraphSkeleton()
        skel.load("unittestdict.txt")
        skel.toporder()

        # generate sample sequence to try to learn from - discrete
        nd = NodeData()
        nd.load("unittestdict.txt")
        self.samplediscbn = DiscreteBayesianNetwork(skel, nd)
        self.samplediscseq = self.samplediscbn.randomsample(5000)

        # generate sample sequence to try to learn from - discrete
        nda = NodeData()
        nda.load("unittestlgdict.txt")
        self.samplelgbn = LGBayesianNetwork(skel, nda)
        self.samplelgseq = self.samplelgbn.randomsample(10000)

        self.skel = skel

    def test_discrete_mle_estimateparams(self):
        result = self.l.discrete_mle_estimateparams(self.skel, self.samplediscseq)
        indexa = result.Vdata['SAT']['vals'].index('lowscore')
        self.assertTrue(result.Vdata['SAT']['cprob']["['low']"][indexa] < 1 and result.Vdata['SAT']['cprob']["['low']"][indexa] > .9)
        indexb = result.Vdata['Letter']['vals'].index('weak')
        self.assertTrue(result.Vdata['Letter']['cprob']["['A']"][indexb] < .15 and result.Vdata['Letter']['cprob']["['A']"][indexb] > .05)

    def test_lg_mle_estimateparams(self):
        result = self.l.lg_mle_estimateparams(self.skel, self.samplelgseq)
        self.assertTrue(result.Vdata['SAT']['mean_base'] < 15 and result.Vdata['SAT']['mean_base'] > 5)
        self.assertTrue(result.Vdata['Letter']['variance'] < 15 and result.Vdata['Letter']['variance'] > 5)

    def test_discrete_constraint_estimatestruct(self):
        result = self.l.discrete_constraint_estimatestruct(self.samplediscseq)
        self.assertTrue(["Difficulty", "Grade"] in result.E)

    def test_lg_constraint_estimatestruct(self):
        result = self.l.lg_constraint_estimatestruct(self.samplelgseq)
        self.assertTrue(["Intelligence", "Grade"] in result.E)

    def test_discrete_condind(self):
        chi, pv, witness = self.l.discrete_condind(self.samplediscseq, "Difficulty", "Letter", ["Grade"])
        self.assertTrue(pv > .05)
        self.assertTrue(witness, ["Grade"])
        chia, pva, witnessa = self.l.discrete_condind(self.samplediscseq, "Difficulty", "Intelligence", [])
        self.assertTrue(pva < .05)

    def test_discrete_estimatebn(self):
        result = self.l.discrete_estimatebn(self.samplediscseq)
        self.assertTrue(result.V)
        self.assertTrue(result.E)
        self.assertTrue(result.Vdata["Difficulty"]["cprob"][0])

    def test_lg_estimatebn(self):
        result = self.l.lg_estimatebn(self.samplelgseq)
        self.assertTrue(result.V)
        self.assertTrue(result.E)
        self.assertTrue(result.Vdata["Intelligence"]["mean_base"])
コード例 #17
0
ファイル: examples.py プロジェクト: Anaphory/libpgm
# Generate a sequence of samples from a discrete-CPD Bayesian network

# load nodedata and graphskeleton
nd = NodeData()
skel = GraphSkeleton()
nd.load("../tests/unittestdict.txt")
skel.load("../tests/unittestdict.txt")

# topologically order graphskeleton
skel.toporder()

# load bayesian network
bn = DiscreteBayesianNetwork(skel, nd)

# sample 
result = bn.randomsample(10)

# output - toggle comment to see
#print json.dumps(result, indent=2)

# (2) ----------------------------------------------------------------------
# Generate a sequence of samples from a linear Gaussian-CPD Bayesian network

# load nodedata and graphskeleton
nd = NodeData()
skel = GraphSkeleton()
nd.load("../tests/unittestlgdict.txt")
skel.load("../tests/unittestdict.txt")

# topologically order graphskeleton
skel.toporder()
コード例 #18
0
import json

from libpgm.nodedata import NodeData
from libpgm.graphskeleton import GraphSkeleton
from libpgm.discretebayesiannetwork import DiscreteBayesianNetwork
from libpgm.pgmlearner import PGMLearner

# generate some data to use
nd = NodeData()
nd.load("grades.txt")    # an input file
skel = GraphSkeleton()
skel.load("grades.txt")
skel.toporder()
bn = DiscreteBayesianNetwork(skel, nd)
data = bn.randomsample(80000)

# instantiate my learner 
learner = PGMLearner()

# estimate structure
result = learner.discrete_constraint_estimatestruct(data)

# output
print json.dumps(result.E, indent=2)
コード例 #19
0
ファイル: libcause.py プロジェクト: finnhacks42/causality
class BinaryNetworkBandit(object):
    """Class represents a Discrete Bayesian Network that supports Thompson sampling.
        Currently only supports interventions on a single variable at a time"""
    def __init__(self, bayesnetfile, targetVar = 'Y', prior=(1.0,1.0)):
        self.file = bayesnetfile
        self.theta_range = linspace(0.0001,0.9999,100)
        self.set_bayesnet()
        self.y = targetVar
        self.reset(prior = prior)

    def getCPD(self):
        """ required as querying a TableCPDFactorization leads modifies the underlying Bayesian network (refresh() appears broken) """
        self.set_bayesnet()
        return TableCPDFactorization(self.bn)

    def set_bayesnet(self):
        nd = NodeData()
        skel = GraphSkeleton()
        nd.load(self.file)
        skel.load(self.file)
        skel.toporder()
        self.bn = DiscreteBayesianNetwork(skel, nd)
        
    def reset(self,prior=(1.0,1.0)):
        """ Clears all the data on samples that have been taken so far but keeps graph structure.
            You can optionally specify a new prior"""  
        # possible single interventions on non-target variable
        self.prior = prior
        self.interventions = [] # a list of possible assignments
        self.variables = [] # store the variables - defines an ordering
        self.intervention_to_arm = {}
        self.variable_name_to_index = {}
        values = []
        index = 0
        variable_index = 0
        for variable, data in self.bn.Vdata.iteritems():
            if variable != self.y:
                self.variables.append(variable)
                self.variable_name_to_index[variable] = variable_index
                variable_index +=1
                vals = data.get("vals")
                values.append(vals)
                for value in vals:
                    self.interventions.append({variable:value})
                    self.intervention_to_arm[(variable,value)]=index
                    index +=1

        # lets calculate and print the actual value of theta for each arm (since we know it)
        
        truth = []
        for i in self.interventions:
             cpd = self.getCPD()
             answer = cpd.specificquery({self.y:"1"},i)
             truth.append(answer) 
        print "THETA",truth
        cpd = self.getCPD() # reset the network to its original state
                    

        # generate all possible assignments (intervention on all variables) to non-target values
        combinations = list(itertools.product(*values))
   
        self.assignements = [dict(zip(self.variables,v)) for v in combinations]
        num_assignments = len(self.assignements)
        self.assingment_map = dict(zip([str(list(v)) for v in combinations],range(num_assignments))) # builds a map from a each assingment to its indx
        
        self.atrials =  self.trials = zeros(shape=(num_assignments,), dtype=int) # stores how often each assignment occured
        self.asuccesses = zeros(shape=(num_assignments,), dtype=int) # stores how often each assignment paid off

        self.num_arms = len(self.interventions)
        self.trials = zeros(shape=(self.num_arms,), dtype=int) # stores how often each arm was selected
        self.successes = zeros(shape=(self.num_arms,), dtype=int) # stores how often each arm paid off

        # now here I'm going to assume models where X1 ... Xn mutually independent causes of Y

        # record distributions for P(X1), P(X2) ... - they update only when we observe Xn not when we do it
        self.observed_trials = zeros(shape=(self.num_arms,), dtype=int)
        self.observed_true = zeros(shape=(self.num_arms,), dtype=int)

        # records how many times each variable was set by intervention
        self.intervened_trials = zeros(shape=(self.num_arms,), dtype=int)
        self.intervened_true = zeros(shape=(self.num_arms,), dtype=int)
                
    
    def sample(self,n,plot=-1):
        """ returns n samples based on Thompson sampling """
        for i in xrange(n):
            if plot > 0 and i % plot == 0:
                do_plot = True
            else:
                do_plot = False
            arm = self.get_recommendation(do_plot)
            intervention = self.interventions[arm]
            # note: evidence is equivelent to do in libpgm
            result = self.bn.randomsample(1,evidence=intervention)[0] # returns a dictionary containing values for each variable
            reward = int(result.get(self.y))
           
            # update the counts for the pulled arm (P(Y|X?=?))
            self.trials[arm] = self.trials[arm] + 1
            if (reward == 1):
                self.successes[arm] = self.successes[arm] + 1

            # for variable we intervened on record that the we intervened
            assert(len(interventions.keys())==1)
            do_variable = intervention.keys()[0] # ASSUMING SINGLE INTERVENTIONS AT THIS POINT
            do_value = intervention.values()[0]
            do_variable_indx = self.variable_name_to_index[do_variable]
            self.intervened_trials[do_variable_indx] +=1
            self.intervened_true[do_variable_indx] +=1
            
            
            
            # for all variables we did not intervene on, update observed
            values = []
            for indx,v in enumerate(self.variables):
                value = result[v]
                values.append(value)
                if v not in intervention:
                    self.observed_trials[indx] += 1
                    if int(value) == 1:
                        self.observed_true[indx]+=1

            # update based on intervened and non-intervened ...

            # for the pulled arm
            self.trials_c[arm] = self.trials_c[arm] + 1
            if (reward == 1):
                self.successes_c[arm] = self.successes_c[arm] + 1
                
            # each other value in result corresponds to an arm
            for k,val in result:
                # calculate how much this should be weighted down
                otrials = self.observed_trials[do_variable_indx]
                oratio = (otrials+self.observed_true[do_variable_indx])/otrials
                itrials = self.intervened_trials[do_variable_indx]
                isuccess = itrials/
                total_success = osuccess+/
                w = 
                if k not in intervention:
                    o_arm = # get arm corresponding to setting variable k to var
                    self.trials_c[o_arm] = self.trials_c[o_arm]+w
                    if reward == 1:
                        self.successes_c[arm] = self.successes_c[arm] + w
                # the value of [arm] occured because of intervention so we need to weight down based on that - going to lead to fractional trials...
            
            
            # update relevent exact assignment
            key = str((values))
            a = self.assingment_map[key]
            self.atrials[a] = self.atrials[a]+1
            if (reward == 1):
                self.asuccesses[a] = self.asuccesses[a] + 1

    def plot_observed(self):
        # put labels under each plot
        f,sp = plt.subplots(1,len(self.variables),sharey=False,figsize=(15,5))
        for i in range(len(self.variables)):
            dist = beta(self.prior[0]+self.observed_true[i], self.prior[1]+self.observed_trials[i]-self.observed_true[i])
            sp[i].plot(self.theta_range,dist.pdf(self.theta_range))
        plt.show()

    def plot_assignments(self):
        print self.atrials
        print self.asuccesses
        f,sp = plt.subplots(1,len(self.assingment_map),sharey=False,figsize=(15,5))
        titles = [json.dumps(x) for x in self.assignements]
        for i in range(len(self.assingment_map)): # need to get rid of the unicode tags so things fit - dirty way is s.encode('ascii')
            dist = beta(self.prior[0]+self.asuccesses[i]+1, self.prior[1]+self.atrials[i]-self.asuccesses[i])
            sp[i].set_title(titles[i])
            sp[i].plot(self.theta_range,dist.pdf(self.theta_range))
        plt.show()
        
 
    def get_recommendation(self,do_plot=False):
        """ recommends which arm to pull next proportional to the estimated probability that it is the optimal one"""
        sampled_theta = []

        if do_plot:
            f,sp = plt.subplots(1,self.num_arms,sharey=False,figsize=(15,5))
        for i in range(self.num_arms):
            #Construct beta distribution for posterior
            dist = beta(self.prior[0]+self.successes[i], self.prior[1]+self.trials[i]-self.successes[i])

            if do_plot:
                sp[i].plot(self.theta_range,dist.pdf(self.theta_range))
            
            #Draw sample from beta distribution
            sampled_theta.append(dist.rvs())

            # Alternately calculate P(Y|X1) as sum(P(Y|X1,X2)P(X2))
            # Do this here ....
            
            
        if do_plot:
            plt.show()
      
        # Return the index of the sample with the largest value
        return sampled_theta.index( max(sampled_theta) )
    
               
    def regret(self, bestprob):
        """ regret as ratio between reward and expectation of reward had we always selected best """
        reward = sum(self.successes)/float(sum(self.trials))
        optimal = bestprob
        return 1 - reward/bestprob