Skip to main content

Infer.NET user guide : Tutorials and examples

Page 1 | Page 2

Defining the model using Infer.Net:

Initializing variables:

In this example, we assume the probabilities which represent whether a user will examine the next document (conditioned on whether a user clicks and whether the document is relevant) are specified by the user. These values do not need to be specified during model specification, and are needed only during inference. Therefore, we just create them as new variables, and hold off on giving them values until we run the model:

Variable<double>[] probNextIfNotClick = Variable.New<double>();  
Variable<double>[] probNextIfClickNotRel = Variable.New<double>();  
Variable<double>[] probNextIfClickRel = Variable.New<double>();

By the same argument, the number of users is also deferred to run-time:

Variable<int> nUsers = Variable.New<int>();

For every document, we have its (user-independent) relevance the summary appeal, which are created as .NET arrays over variables:

Variable<double>[] appeal = new Variable<double>[nRanks];  
Variable<double>[] relevance = new Variable<double>[nRanks];

Appeal and relevance are given uniform priors for each document:

for (int d = 0; d < nRanks; d++)  
    appeal[d] = Variable.Beta(1, 1);  
    relevance[d] = Variable.Beta(1, 1);  

For every user, and for every document, we have the variables which represent whether the user examined the document, whether they clicked on it, and whether is was relevant for them. For each document, for each document rank we use VariableArrays to model across users:

VariableArray<bool>[] examine = new VariableArray<bool>[nRanks];  
VariableArray<bool>[] click = new VariableArray<bool>[nRanks];  
VariableArray<bool>[] isRel = new VariableArray<bool>[nRanks];

The clicks are observed, and we will specify those observations for the click arrays at run time; however, we do not need to have the observations at the time we specify the model.

At each rank, these variables, examine, click, and isRel follow the same conditional distribution across all users. So, we use the range variable, user, to specify the distribution across all users simultaneously. The range variable can be specified as:

Range u = new Range(nUsers).Named("User");
examine[d] = Variable.Array<bool>(u);  
click[d] = Variable.Array<bool>(u);  
isRel[d] = Variable.Array<bool>(u);

Specifying the model:

In Infer.NET, we can specify the model in the same way as we would sample from it. In this section, we elaborate how to define our probabilistic model of clicks.

First, let’s consider the examine variable. We assume all users have examined the very first document (d==0) so that:

examine[0][u] = Variable.Bernoulli(1).ForEach(u);

The documents at other ranks are examined according to the conditional distribution specified by:

using (Variable.ForEach(u))  
    var nextIfClick = Variable.New<bool>();  
    using (Variable.If(isRel[d-1][u]))  
    using (Variable.IfNot(isRel[d-1][u]))  
    var nextIfNotClick = Variable.Bernoulli(probNextIfNotClick);  
    var next = (((!click[d - 1][u]) & nextIfNotClick) | (click[d - 1][u] & nextIfClick));  
    examine[d][u] = examine[d - 1][u] & next;  

The conditional probability table for examine[d][u] is specified by using Variable.If and Variable.IfNot constructs, along with “and” and “or” factors as shown in the factor graph. The variables nextIfClick, nextIfNotClick, and next are represented by small circles in the factor graph on Page 1. Note that this whole piece of model code is embedded in a ForEach block. This ensures that the calls to Variable.Bernoulli create a separate variable for each user.

The conditional distribution over the click variable isRel variables at each rank and across all users can now be specified as:

using (Variable.ForEach(u))  
    click[d][u] = examine[d][u] & Variable.Bernoulli(appeal[d]);  
    isRel[d][u] = click[d][u] & Variable.Bernoulli(relevance[d]);  

Instantiation of the inference engine:

We create an inference engine with EP as the inference algorithm:

InferenceEngine ie = new InferenceEngine(new ExpectationPropagation());

Specifying the parameters and the observed variables:

In this code, all the required parameters and observations are provided by a ‘user’ object. Using this, we set the observed values as follows:

nUsers.ObservedValue = user.nUsers;  
probNextIfNotClick.ObservedValue = user.probExamine[0];  
probNextIfClickNotRel.ObservedValue = user.probExamine[1];  
probNextIfClickRel.ObservedValue = user.probExamine[2];  
for (int d = 0; d < nRanks; d++)  
    click[d].ObservedValue = user.clicks[d];

Performing inference:

for (int d = 0; d < nRanks; d++)  
    docStats[d].inferredRelevance = ie.Infer<Beta>(relevance[d]);  
    docStats[d].inferredAppeal = ie.Infer<Beta>(appeal[d]);  

Page 1 | Page 2