Skip to content

Instantly share code, notes, and snippets.

@y-mitsui
Created May 6, 2022 00:16
Show Gist options
  • Select an option

  • Save y-mitsui/5968d943bcc54b932eb04dfd55b8f909 to your computer and use it in GitHub Desktop.

Select an option

Save y-mitsui/5968d943bcc54b932eb04dfd55b8f909 to your computer and use it in GitHub Desktop.
最も基本的なベイジアンネットワーク
/* ベイズ情報量基準 */
double bic(double logLike,int numSample,int numModel){
return -2*logLike+numModel*log(numSample);
}
/* 学習スコア */
double score(int numNode,int *edge,int numSample,double **likelies,int *variablePattern){
double like;
int i,j,numModel,numParents;
unsigned char parentPattern;
for(numModel=0,like=0.0,i=0;i<numNode;i++){
for(numParents=0,parentPattern=0,j=0;j<numNode;j++){
if(edge[i*numNode+j]==1){
parentPattern=parentPattern|(1<<j);
numParents++; /* 親の数*/
}
}
like+=likelies[i][parentPattern];
numModel+=numParents*(variablePattern[i]-1);
}
return bic(like,numSample,numModel);
}
/* アークを辿ってノードkeyにたどり着いたら0を返す */
int isExistChildrenChain(int *edge,int numNode,int child,int key){
int i;
if(edge[key*numNode+child]==1) return 0;
for(i=0;i<numNode;i++){
if(edge[i*numNode+child]==1){
if(isExistChildrenChain(edge,numNode,i,key)==0) return 0;
}
}
return 1;
}
/* idxにアークを引くことでループができれば0を返す*/
int isEnableArc(int *edge,int numNode,int idx){
int parent=idx%numNode;
int child=idx/numNode;
if(parent==child) return 0;
if(edge[idx]==1) return 0;
return isExistChildrenChain(edge,numNode,child,parent);
}
bayesianNetScore* makeBNScore(int *edge,int numEdge,double score){
bayesianNetScore *r=Malloc(bayesianNetScore,1);
r->edge=Malloc(int,numEdge);
memcpy(r->edge,edge,sizeof(int)*numEdge);
r->score=score;
return r;
}
/* ちょうどnumLineの数だけアークを引く場合の全パターンのベイジアンネットワークを構築し学習スコアを計算する
likelies:あらかじめ計算しておいた子ノードと親のパターンごとの対数尤度
variablePattern:各ノードごとのとりうる値の数
likely:学習スコアと対応するネットワーク構造(戻り値)
戻り値:構造数
*/
int __buildBayesianNet(int numNode,int *edge,int numLine,bayesianNetScore **likely,int numSample,double **likelies,int *variablePattern,int start,int rank){
int numLikely=0;
int i;
double tmp;
if(rank==numLine){
tmp=score(numNode,edge,numSample,likelies,variablePattern);
likely[numLikely++]=makeBNScore(edge,numNode*numNode,tmp);
return numLikely;
}else{
for(i=start;i<numNode*numNode;i++){
if(isEnableArc(edge,numNode,i)){
edge[i]=1;
numLikely+=__buildBayesianNet(numNode,edge,numLine,&likely[numLikely],numSample,likelies,variablePattern,i+1,rank+1);
edge[i]=0;
}
}
}
return numLikely;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment