我正在尝试在Unity游戏中使用C#中的Bayes server创建一个动态的贝叶斯网络来进行参数学习。该实现基于此article。
下图所示模型的简要说明:当玩家开始玩关卡时,我给他们分配了0.5的初始概率,他们已经知道他们正在学习的东西,在所示的网络中被表示为Prior节点。与相关的变量称为priorKnowledge
。该先验节点链接到知识节点,该知识节点是表示潜在变量LearnRate
的隐藏节点,需要在游戏过程中学习。该节点又连接到“问题”节点,该节点具有两种状态正确或不正确,具体取决于玩家是否正确回答了问题。根据先前节点和问题节点的状态,一旦清除了先前的级别,就可以计算学习率并将其用作下一级别的先验。
我有以下代码段,这些代码使用贝叶斯服务器库表示C#中的网络。
BayesServer.Network beliefnet;
Variable priorKnowledge;
Node priorKnowledgeNode;
Variable learnRate;
Node knowledgeNode;
Node questionNode;
ParameterLearning learning;
ParameterLearningOptions learningOptions;
// numberOfDistractors and levelId will be used later for added complexity in modeling
void InitializeNetworkForLevel(int numberOfDistractors, int levelId)
{
beliefnet = new BayesServer.Network();
// add an intial knowledge node
priorKnowledge = new Variable("PriorKnowledge", VariableValueType.Continuous, VariableKind.Probability);
// initialize the priorKnowledge value to 0.5 if level = 1, else set it to learn rate (may be here, or in the queryNetwork method)
priorKnowledgeNode = new Node("Prior", priorKnowledge);
beliefnet.Nodes.Add(priorKnowledgeNode);
// add a knowledge node which is a latent variable (parameter to be learned from observed values
learnRate = new Variable("LearnRate", VariableValueType.Continuous, VariableKind.Probability);
knowledgeNode = new Node("Knowledge", learnRate);
beliefnet.Nodes.Add(knowledgeNode);
// add a link from prior node to knowledge node
beliefnet.Links.Add(new Link(priorKnowledgeNode, knowledgeNode));
// add a question node, which denotes the oberved variable whether the question is answered correctly or not
// this node has two states, namely correct or incorrect
State correct = new State("Correct");
State inCorrect = new State("Inorrect");
questionNode = new Node("Question", correct, inCorrect);
beliefnet.Nodes.Add(questionNode);
// add a link from knowledge node to question node
beliefnet.Links.Add(new Link(knowledgeNode, questionNode));
// We will use the RelevanceTree algorithm here, as it is optimized for parameter learning
learning = new ParameterLearning(beliefnet, new RelevanceTreeInferenceFactory());
learningOptions = new ParameterLearningOptions();
}
此外,下面是QueryNetwork()
方法。但是,我也不清楚在评论中也提到过很多有关它的事情。首先,我需要创建一个用于参数学习的EvidenceReaderCommand
对象,该对象需要3个参数:readerCommand
以读取非时间数据,variableList
用于非时间变量,以及ReaderOptions
。
variableList
需要一个变量列表,但我不确定在这种情况下应该使用什么变量。
readerCommand
需要一个带有行和列的表,我不确定在这种情况下该怎么做。谁能帮助我更好地阐明这两个方面以及如何为该网络正确构建它们?
void QueryNetwork()
{
DataColumn column;
DataRow row;
// don't know which nodes go into this table :(
// is this supposed to be the conditional probability table? where will the probabilities come from?
// most probably I'd need to add more columns, but not sure right now
DataTable table = new DataTable("ParentTable");
column = new DataColumn();
column.DataType = System.Type.GetType("System.Double");
column.ColumnName = "LearnRate";
column.ReadOnly = true;
column.Unique = true;
// i am not sure but table needs to have some rows of data as well, which will be their conditional probabilities
table.Columns.Add(column);
IDataReaderCommand readerCommand = new DataTableDataReaderCommand(table);
// don't know which variables should be a part of this variableList
IList<VariableReference> variableList = new List<VariableReference>();
variableList.Add(new VariableReference(learnRate, ColumnValueType.Value, "LearnRate"));
EvidenceReaderCommand evidenceReaderCommand = new EvidenceReaderCommand(readerCommand, variableList, new ReaderOptions(null));
ParameterLearningOutput result = learning.Learn(evidenceReaderCommand, learningOptions);
Debug.Log(result.LogLikelihood.Value);
}
答案 0 :(得分:0)
以下代码演示了如何创建一个简单的动态贝叶斯网络,类似于您的图像中显示的那样。
var network = new Network();
var knowledge = new Variable("Knowledge", new string[] { "False", "True" });
var nodeKnowledge = new Node(knowledge)
{
TemporalType = TemporalType.Temporal // this is a time series node, hence re-used for each time slice
};
network.Nodes.Add(nodeKnowledge);
var question = new Variable("Question", new string[] { "Incorrect", "Correct" });
var nodeQuestion = new Node(question)
{
TemporalType = TemporalType.Temporal // this is a time series node, hence re-used for each time slice
};
network.Nodes.Add(nodeQuestion);
network.Links.Add(new Link(nodeKnowledge, nodeKnowledge, 1)); // time series link (order/lag 1)
network.Links.Add(new Link(nodeKnowledge, nodeQuestion, 0));
这将创建一个DBN,如下图所示。 (这实际上只是一个简单的“隐马尔可夫”模型,但可以扩展以创建更复杂的模型)
如果要展开此DBN(推理不需要),它将看起来像这样(在紧凑视图中):
为了了解网络的参数,请参见以下链接,可以对其进行修改以了解该网络。
Parameter learning code example in C#
要查看如何布局数据,请参见以下链接: