贝叶斯软件genle教程_贝叶斯网络软件SMILE和GENIE的使用

[TOC]

For Beginners

预备步骤

下载和使用库文件

在官方网站上下载对应版本的SMILE库,解压文件后将库文件放在debug文件夹下。需要声明的是,SMILE有两个版本,只有Academic版本才是免费的,Commercial版本需要购买license。如果在Windows下,只需要在工程文件中包含SMILE头文件的地址,并引入头文件即可,此时头文件会自动根据系统设置选择库文件。

在Linux下,需要在g++中运行(假设库文件放在*.cpp文件同文件夹的子文件夹smile下),编译库文件并链接动态库(libsmile.a),系统输出二进制文件(可执行文件a.out)。

g++ -DNDEBUG -O3 -I./smile -L./smile -lsmile *.cpp

使用GeNIe可视化建图

使用GeNIe建图后,将文件保存成xdsl文件。具体参考文献[1]。当然,如果没有安装GeNIe就得自己写xdsl文件。

建立模型

建立网络

DSL_network

SMILE中有关网络的类是DSL_network该类的头文件在"network.h"中,除了构造函数外,成员函数包括:读写文件

int ReadFile(const char *filename, int fileType = 0, void *reserved = NULL);

int WriteFile(const char *filename, int fileType = 0, void *reserved = NULL);

int ReadString(const char *xdslString, void *reserved = NULL); //读xdslString的内容

int WriteString(std::string &xdslOutputString, void *reserved = NULL);建网络有关(点、边)

int FindNode(const char *nodeId) const;

DSL_node* GetNode(int handle);

弄清楚这两个函数的前提是能够用xdsl建图。在xdsl建图中结点的nodeID即是标识符(identifier),对应到SMILE库中就是const char *nodeID,这个在xdsl文件中必须指定,而且不能相同。以上两个函数的作用,FindNode是找到我们用identifier设置的node在系统中分配的handle是多少(int类型)。GetNode是真正用handle来获得该结点,GetNode的输入是handle,输出是结点类的指针(DSL_node),需要注意的是,handle并不是常值可能会改变,因此GetNode不能用一个定值handle,必须配合FindNode。FindNode的输出是handle,输入是标识符字符const char *nodeID。另外,还有一些特殊的函数:int MakeUniform();用以统一所有Node的definition。与目标结点有关

在SMILE库中,目标结点是指在推断算法中会进行更新的结点,其他没有被设为目标的结点,不能保证被更新(跟具体的更新算法有关)。如果用户没有设置目标结点,那么系统默认所有的结点都是目标结点。

int SetTarget(int nodeHandle);

int UnSetTarget(int nodeHandle);

int ClearAllTargets();

int IsTarget(int nodeHandle); //yes:non-zero;no:zero;invalid handle:negative与记录有关

在SMILE中,记录是用case来实现的。

DSL_simpleCase * AddCase(const std::string & name);

DSL_simpleCase * GetCase(int index) const;

int DeleteCase(int index);

void DeleteAllCases();

int GetNumberOfCases() const;

void EnableSyncCases(bool sync);贝叶斯推理--更新权值与设定参数有关

这些方法将在后面的小节中(设定参数与进行推论中)分别介绍如何使用。

int UpdateBeliefs();

void SetDefaultBNAlgorithm(int algorithm);

void SetDefaultIDAlgorithm(int algorithm);

int InvalidateAllBeliefs()

bool CalcProbEvidence(double &pe, bool forceChainRule = false);

int ClearAllEvidence();

DSL_node/DSL_nodeDefinition/DSL_nodeValue

SMILE中有关结点的类是DSL_node、DSL_nodeDefinition、DSL_nodeValue,这些类的头文件分别在"node.h","nodedef.h","nodeval.h"中,除了构造函数外,成员函数包括:DSL_nodeDefinition、DSL_nodeValue分别是结点的定义与条件概率的设定的关键,另外DSL_node还有一些与概率推论无关的,而与结点的颜色、name等属性有关的函数。返回推论相关的DSL_nodeDefinition、DSL_nodeValue指针

DSL_nodeDefinition *Definition();

DSL_nodeValue *Value();返回node其他的性质

const char* GetId() const; //nodeid 就是xdsl中identifier,所以返回值是一个字符串char*

int SetId(const char *newId);

DSL_nodeInfo &Info();

DSL_network *Network();

int Handle();

DSL_userPropertiesDSL_nodeDefinition [todo]

DSL_nodeValue [todo]

DSL_Dmatrix

SMILE中有关概率分布的类是DSL_Dmatrix,类的头文件在"dmatrix.h" 条件概率在DSL_Dmatrix用double类型的vector保存。具体的顺序参考手册中下图。

定位可以用coordinate或者是index的相加。 DSL_Dmatrix还可以用在功效表以及边缘概率分布中。

设定参数(enter observation, set evidence)节点(node)的表示:net.FindNode函数,该参数对应GeNIe中节点的标识符,而不是显示的Name!节点标识符对大小写敏感,并且命名规范为:起始字母为字符,只有字符、数字和下划线。节点状态的表示:net.GetNode函数与GetOutcomesNames函数,FindPosition函数。

设定evidence:注意的是,不是直接设置string函数,而是设定已有的状态,并用其index作为输入。

进行推论(perform inference, retrieve results)

UpdateBeliefs

参数学习

参数学习最好的方法也是通过GeNIe直接操作。

#include

#include

#include <.>

using namespace std;

int main(int argc, char *argv[])

{

ErrorH.RedirectToFile(stdout);

DSL_network net;

int res = net.ReadFile("VentureBN.xdsl");

if (DSL_OKAY != res)

{

return res;

}

int handle = net.FindNode("Forecast");

if(handle < 0)

{

return handle;

}

DSL_node *f = net.GetNode(handle);

int idx= f->Definition()->GetOutcomesNames() ->FindPosition("Poor");

if (idx < 0)

{

return idx;

}

f->Value()->SetEvidence(idx);

net.UpdateBeliefs();

handle=net.FindNode("Success");

if (handle < 0)

{

return handle;

}

DSL_node *s = net.GetNode(handle);

const DSL_Dmatrix &beliefs = *s->Value()->GetMatrix();

const DSL_idArray &outcomes = *s->Definition()->GetOutcomesNames();

for (int i=0;i

{

printf("%s=%g\n",outcomes[i],beliefs[i]);

}

cout << "Hello World!" << endl;

return DSL_OKAY;

}

常见问题

1.Windows下QT编译报错.error: LNK1104: cannot open file 'smile_dbg.lib'。 这种时候,不需要再额外去添加动态库,如下图。相反可以将所有的影子文件夹删除,并且重复几次“清理”和“构建”,并设置项目中的run运行配置。多等待几分钟会自动恢复。(这是非常奇怪的现象,个人猜测或许是Qt版本的原因,但今天确实遇到这个问题,尝试各种办法之后仍然无效,最后又自动恢复正常)

参考文献

你可能感兴趣的:(贝叶斯软件genle教程)