Talk is cheap, I show you the code

  第一章的作业主要是关于PGM的因子操作。实际上,因子是整个概率图的核心。对于有向图而言,因子对应的是CPD(条件分布);对无向图而言,因子对应的是势函数。总而言之,因子是一个映射,将随机变量空间映射到实数空间。因子表现的是对变量之间关系的一种设计。每个因子都编码了一定的信息。

  因子的数据结构:

  

  1. phi = struct('var', [3 1 2], 'card', [2 2 2], 'val', ones(1, 8));

  在matlab中,因子被定义为一个结构体。结构体中有三个变量,分别是 var : variable, card : cardinate, val : value.这三个变量构成了因子表。其中,var 后面是变量名 X_3,X_2,X_1. card 是每个变量所对应的取值范围。[2 2 2]表示这三个变量都是二值变量。如果是骰子,则应该写成[6 6 6]。val 后面接的是一个列向量。该向量的长度应该为 prod(card).

1、因子相乘

  两个Scope相同或不同或部分不同的因子可以相乘,称为因子联合。对于有向图而言,因子相乘就是贝耶斯的链式法则。对于无向图而言,因子相乘就是合并两个相似的信息。因子相乘的原则是能够冲突,也就是只有对应项相乘(因子都是表)。

  1. % FactorProduct Computes the product of two factors.
  2. % C = FactorProduct(A,B) computes the product between two factors, A and B,
  3. % where each factor is defined over a set of variables with given dimension.
  4. % The factor data structure has the following fields:
  5. % .var Vector of variables in the factor, e.g. [1 2 3]
  6. % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2]
  7. % .val Value table of size prod(.card)
  8. %
  9. % See also FactorMarginalization.m, IndexToAssignment.m, and
  10. % AssignmentToIndex.m
  11.  
  12. function C = FactorProduct(A, B)
  13. %A = struct('var', [1], 'card', [2], 'val', [0.11, 0.89]);
  14. %B = struct('var', [2, 1], 'card', [2, 2], 'val', [0.59, 0.41, 0.22, 0.78]);
  15. % Check for empty factors
  16. if (isempty(A.var)), C = B; return; end;
  17. if (isempty(B.var)), C = A; return; end;
  18.  
  19. % Check that variables in both A and B have the same cardinality
  20. [dummy iA iB] = intersect(A.var, B.var);
  21. if ~isempty(dummy)
  22. % A and B have at least 1 variable in common
  23. assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors');
  24. end
  25.  
  26. % Set the variables of C
  27. C.var = union(A.var, B.var);
  28.  
  29. % Construct the mapping between variables in A and B and variables in C.
  30. % In the code below, we have that
  31. %
  32. % mapA(i) = j, if and only if, A.var(i) == C.var(j)
  33. %
  34. % and similarly
  35. %
  36. % mapB(i) = j, if and only if, B.var(i) == C.var(j)
  37. %
  38. % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5],
  39. % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3
  40. % and C.var(2) = 3, so A.var(1) == C.var(2).
  41.  
  42. [dummy, mapA] = ismember(A.var, C.var);
  43. [dummy, mapB] = ismember(B.var, C.var);
  44.  
  45. % Set the cardinality of variables in C
  46. C.card = zeros(1, length(C.var));
  47. C.card(mapA) = A.card;
  48. C.card(mapB) = B.card;
  49.  
  50. % Initialize the factor values of C:
  51. % prod(C.card) is the number of entries in C
  52. C.val = zeros(1, prod(C.card));
  53.  
  54. % Compute some helper indices
  55. % These will be very useful for calculating C.val
  56. % so make sure you understand what these lines are doing.
  57. assignments = IndexToAssignment(1:prod(C.card), C.card);
  58. indxA = AssignmentToIndex(assignments(:, mapA), A.card);
  59. indxB = AssignmentToIndex(assignments(:, mapB), B.card);
  60.  
  61. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  62. % YOUR CODE HERE:
  63. % Correctly populate the factor values of C
  64. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  65. for i = 1:size(indxA)
  66. C.val(i) = A.val(indxA(i))*B.val(indxB(i));
  67. end
  68. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  69.  
  70. end

2、变量边际化

  变量边际化是概率图模型的核心操作,其目的是消除其他变量,获得单个变量的边缘分布。例如有CPD:  struct('var', [3 1 2], 'card', [2 2 2], 'val', ones(1, 8)), 如果我们需要知道x_1 最本质的分布,则需要对x_2,x_3进行边际化操作。变量边际化最大的难点在于算法。比如要边际 x_2,那么应该把x_1,x_3取值相同的组合求和。此函数用了一个巧妙的方法来解决:先由var 求assignment,之后抽去assignment里需要消除的变量所对应列,在将assignment转成index.此时index里数字相同的编码就是需要求和的。

  1. % FactorMarginalization Sums given variables out of a factor.
  2. % B = FactorMarginalization(A,V) computes the factor with the variables
  3. % in V summed out. The factor data structure has the following fields:
  4. % .var Vector of variables in the factor, e.g. [1 2 3]
  5. % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2]
  6. % .val Value table of size prod(.card)
  7. %
  8. % The resultant factor should have at least one variable remaining or this
  9. % function will throw an error.
  10. %
  11. % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m
  12.  
  13. function B = FactorMarginalization(A, V)
  14. % A = Joint;
  15. % V = [2];
  16. % Check for empty factor or variable list
  17. if (isempty(A.var) || isempty(V)), B = A; return; end;
  18.  
  19. % Construct the output factor over A.var \ V (the variables in A.var that are not in V)
  20. % and mapping between variables in A and B
  21. [B.var, mapB] = setdiff(A.var, V);
  22.  
  23. % Check for empty resultant factor
  24. if isempty(B.var)
  25. error('Error: Resultant factor has empty scope');
  26. end;
  27.  
  28. % Initialize B.card and B.val
  29. B.card = A.card(mapB);
  30. B.val = zeros(1, prod(B.card));
  31.  
  32. % Compute some helper indices
  33. % These will be very useful for calculating B.val
  34. % so make sure you understand what these lines are doing
  35. assignments = IndexToAssignment(1:length(A.val), A.card);
  36. indxB = AssignmentToIndex(assignments(:, mapB), B.card);
  37.  
  38. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  39. % YOUR CODE HERE
  40. % Correctly populate the factor values of B
  41. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  42.  
  43. shunxu = 1:size(indxB);
  44. hunhe = [indxB,shunxu'];
  45. hunhe_paixu = sortrows(hunhe,1);
  46. tmp_1 = hunhe_paixu(:,1);
  47. tmp_2 = hunhe_paixu(:,2);
  48. k = 1;
  49. for i = 1:length(tmp_1)-1
  50. if tmp_1(i) == tmp_1(i+1)
  51. B.val(k) = B.val(k) + A.val(tmp_2(i));
  52. else
  53. B.val(k) = B.val(k) + A.val(tmp_2(i));
  54. k = k+1;
  55. end
  56. end
  57. B.val(k) = B.val(k) + A.val(i+1);
  58.  
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. end

3、变量观测

  变量观测是将未知的变量置为已知。那么该变量其他不符合观测条件的取值都应该置为0. 该算法的核心思想是首先获得变量的assignment,之后选出被观测变量所占assignment的列。最后依次读取该列的值,将不符合观测结果的value置0.

  1. % ObserveEvidence Modify a vector of factors given some evidence.
  2. % F = ObserveEvidence(F, E) sets all entries in the vector of factors, F,
  3. % that are not consistent with the evidence, E, to zero. F is a vector of
  4. % factors, each a data structure with the following fields:
  5. % .var Vector of variables in the factor, e.g. [1 2 3]
  6. % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2]
  7. % .val Value table of size prod(.card)
  8. % E is an N-by-2 matrix, where each row consists of a variable/value pair.
  9. % Variables are in the first column and values are in the second column.
  10.  
  11. function F = ObserveEvidence(F, E)
  12.  
  13. % Iterate through all evidence
  14.  
  15. for i = 1:size(E, 1)
  16. v = E(i, 1); % variable
  17. x = E(i, 2); % value
  18.  
  19. % Check validity of evidence
  20. if (x == 0),
  21. warning(['Evidence not set for variable ', int2str(v)]);
  22. continue;
  23. end;
  24.  
  25. for j = 1:length(F),
  26. % Does factor contain variable?
  27. indx = find(F(j).var == v);
  28.  
  29. if (~isempty(indx)),
  30.  
  31. % Check validity of evidence
  32. if (x > F(j).card(indx) || x < 0 ),
  33. error(['Invalid evidence, X_', int2str(v), ' = ', int2str(x)]);
  34. end;
  35.  
  36. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  37. % YOUR CODE HERE
  38. % Adjust the factor F(j) to account for observed evidence
  39. % Hint: You might find it helpful to use IndexToAssignment
  40. % and SetValueOfAssignment
  41. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  42. for k = 1:prod(F(j).card)
  43. Assignment_ = IndexToAssignment(k,F(j).card);
  44. if Assignment_(indx) ~= x
  45. indx_ = AssignmentToIndex(Assignment_,F(j).card);
  46. F(j).val(indx_) = 0;
  47. end
  48. end
  49.  
  50. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  51.  
  52. % Check validity of evidence / resulting factor
  53. if (all(F(j).val == 0)),
  54. warning(['Factor ', int2str(j), ' makes variable assignment impossible']);
  55. end;
  56.  
  57. end;
  58. end;
  59. end;
  60.  
  61. end

4、计算联合分布

  计算联合分布就是将若干个变量进行相乘。联合分布的输入是因子集。将因子集中的变量依次相乘,所得最后结果则为联合分布。

  

  1. %ComputeJointDistribution Computes the joint distribution defined by a set
  2. % of given factors
  3. %
  4. % Joint = ComputeJointDistribution(F) computes the joint distribution
  5. % defined by a set of given factors
  6. %
  7. % Joint is a factor that encapsulates the joint distribution given by F
  8. % F is a vector of factors (struct array) containing the factors
  9. % defining the distribution
  10. %
  11.  
  12. % FACTORS.INPUT(1) = struct('var', [1], 'card', [2], 'val', [0.11, 0.89]);
  13. %
  14. % % FACTORS.INPUT(2) contains P(X_2 | X_1)
  15. % FACTORS.INPUT(2) = struct('var', [2, 1], 'card', [2, 2], 'val', [0.59, 0.41, 0.22, 0.78]);
  16. %
  17. % % FACTORS.INPUT(3) contains P(X_3 | X_2)
  18. % FACTORS.INPUT(3) = struct('var', [3, 2], 'card', [2, 2], 'val', [0.39, 0.61, 0.06, 0.94]);
  19. %
  20. % F = FACTORS.INPUT;
  21.  
  22. function Joint = ComputeJointDistribution(F)
  23.  
  24. % Check for empty factor list
  25. if (numel(F) == 0)
  26. warning('Error: empty factor list');
  27. Joint = struct('var', [], 'card', [], 'val', []);
  28. return;
  29. end
  30.  
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. % YOUR CODE HERE:
  33. % Compute the joint distribution defined by F
  34. % You may assume that you are given legal CPDs so no input checking is required.
  35. %
  36. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  37. F_ = F;
  38. %Joint = struct('var', [], 'card', [], 'val', []); % Returns empty factor. Change this.
  39. for i = 2 : numel(F_)
  40. F_(i) = FactorProduct(F_(i),F_(i-1));
  41. end
  42. Joint = F_(i);
  43. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  44. end

5、计算边缘分布

  边缘分布是在联合分布的基础上更进一步的处理,对于给定联合分布,某些变量可能被观测到。某些变量可能需要边际掉,最后的结果就是边缘分布。边缘分布得名于其在因子表中处以边缘的位置。其关键操作在于得到联合分布后必须归一化。因为边缘分布的和总是1.

  1. %ComputeMarginal Computes the marginal over a set of given variables
  2. % M = ComputeMarginal(V, F, E) computes the marginal over variables V
  3. % in the distribution induced by the set of factors F, given evidence E
  4. %
  5. % M is a factor containing the marginal over variables V
  6. % V is a vector containing the variables in the marginal e.g. [1 2 3] for
  7. % X_1, X_2 and X_3.
  8. % F is a vector of factors (struct array) containing the factors
  9. % defining the distribution
  10. % E is an N-by-2 matrix, each row being a variable/value pair.
  11. % Variables are in the first column and values are in the second column.
  12. % If there is no evidence, pass in the empty matrix [] for E.
  13.  
  14. % % FACTORS.INPUT(1) contains P(X_1)
  15. % FACTORS.INPUT(1) = struct('var', [1], 'card', [2], 'val', [0.11, 0.89]);
  16. %
  17. % % FACTORS.INPUT(2) contains P(X_2 | X_1)
  18. % FACTORS.INPUT(2) = struct('var', [2, 1], 'card', [2, 2], 'val', [0.59, 0.41, 0.22, 0.78]);
  19. %
  20. % % FACTORS.INPUT(3) contains P(X_3 | X_2)
  21. % FACTORS.INPUT(3) = struct('var', [3, 2], 'card', [2, 2], 'val', [0.39, 0.61, 0.06, 0.94]);
  22. %
  23. % V = [3];
  24. % F = FACTORS.INPUT;
  25. % E = [];
  26. function M = ComputeMarginal(V, F, E)
  27.  
  28. % Check for empty factor list
  29. if (numel(F) == 0)
  30. warning('Warning: empty factor list');
  31. M = struct('var', [], 'card', [], 'val', []);
  32. return;
  33. end
  34.  
  35. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  36. % YOUR CODE HERE:
  37. % M should be a factor
  38. % Remember to renormalize the entries of M!
  39. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  40. Joint = ComputeJointDistribution(F);
  41. Obser = ObserveEvidence(Joint,E);
  42. To_be_Mglzed = setdiff(Joint.var,V);
  43. if ~isempty(To_be_Mglzed)
  44. M = FactorMarginalization(Obser,To_be_Mglzed);
  45. else
  46. M = Obser;
  47. end
  48. M.val = M.val/sum(M.val);
  49. % M = struct('var', [], 'card', [], 'val', []); % Returns empty factor. Change this.
  50.  
  51. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52.  
  53. M = StandardizeFactors(M);
  54. end

  最后,所有代码请点这里

机器学习 —— 概率图模型(Homework: Factors)的更多相关文章

  1. 机器学习 —— 概率图模型(Homework: Exact Inference)

    在前三周的作业中,我构造了概率图模型并调用第三方的求解器对器进行了求解,最终获得了每个随机变量的分布(有向图),最大后验分布(双向图).本周作业的主要内容就是自行编写概率图模型的求解器.实际上,从根本 ...

  2. 机器学习 —— 概率图模型(Homework: CRF Learning)

    概率图模型的作业越往后变得越来越有趣了.当然,难度也是指数级别的上涨啊,以至于我用了两个周末才完成秋名山神秘车牌的寻找,啊不,CRF模型的训练. 条件随机场是一种强大的PGM,其可以对各种特征进行建模 ...

  3. 机器学习 —— 概率图模型(Homework: MCMC)

    除了精确推理之外,我们还有非精确推理的手段来对概率图单个变量的分布进行求解.在很多情况下,概率图无法简化成团树,或者简化成团树后单个团中随机变量数目较多,会导致团树标定的效率低下.以图像分割为例,如果 ...

  4. 机器学习 —— 概率图模型(Homework: Representation)

    前两周的作业主要是关于Factor以及有向图的构造,但是概率图模型中还有一种更强大的武器——双向图(无向图.Markov Network).与有向图不同,双向图可以描述两个var之间相互作用以及联系. ...

  5. 机器学习 —— 概率图模型(Homework: StructuredCPD)

    Week2的作业主要是关于概率图模型的构造,主要任务可以分为两个部分:1.构造CPD;2.构造Graph.对于有向图而言,在获得单个节点的CPD之后就可依据图对Combine CPD进行构造.在获得C ...

  6. 机器学习 —— 概率图模型(学习:CRF与MRF)

    在概率图模型中,有一类很重要的模型称为条件随机场.这种模型广泛的应用于标签—样本(特征)对应问题.与MRF不同,CRF计算的是“条件概率”.故其表达式与MRF在分母上是不一样的. 如图所示,CRF只对 ...

  7. 机器学习 —— 概率图模型(Homework: Structure Learning)

    概率图的学习真的要接近尾声了啊,了解的越多越发感受到它的强大.这周的作业本质上是data mining.从数据中学习PGM的结构和参数,完全使用数据驱动 —— No structure, No par ...

  8. 机器学习 —— 概率图模型(CPD)

    CPD是conditional probability distribution的缩写,翻译成中文叫做 条件概率分布.在概率图中,条件概率分布是一个非常重要的概念.因为概率图研究的是随机变量之间的练习 ...

  9. 机器学习 —— 概率图模型(推理:MAP)

    MAP 是最大后验概率的缩写.后验概率指的是当有一定观测结果的情况下,对其他随机变量进行推理.假设随机变量的集合为X ,观察到的变量为 e, W = X-e , AP = P(W|e). 后验概率和联 ...

随机推荐

  1. Microsoft Azure Powershell 获取Azure-Location

    首先要切换至AzureResourceManager模式下 http://www.cnblogs.com/SignalTips/p/4110790.html 国际版Get-AzureLocation ...

  2. snmptrap使用

    SNMP简单网络管理协议,其中其支持的一个命令snmptrap命令,用于模拟向管理机发送trap消息.   启动陷阱方法: snmptrapd -C -c /etc/snmp/snmptrapd.co ...

  3. ASP.NET MVC +EasyUI 权限设计(二)环境搭建

    请注明转载地址:http://www.cnblogs.com/arhat 今天突然发现博客园出问题了,老魏使用了PC,手机,平板都访问博客园了,都是不能正常的访问,原因是不能加载CSS,也就是不能访问 ...

  4. 非常实用的10个PHP高级应用技巧

    PHP 独特的语法混合了 C.Java.Perl 以及 PHP 自创新的语法.它可以比 CGI或者Perl更快速的执行动态网页.用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML ...

  5. UpdateData(false) and UpdateData(true)

    数据更新函数: UpdateData(false); 控件的关联变量的值传给控件并改变控件状态(程序--->EXE) UpdateData(true); 控件的状态传给其关联的变量(EXE--- ...

  6. cocos2.2.3中创建精灵对象的三大类方法

    1.众生相,皆精灵 2.精灵的类继承关系 class CCSprite : public CCNode, public CCNodeRGBA, public CCTextureProtocol 3.创 ...

  7. 史上最全的Excel数据编辑处理技巧(转)

    史上最全的数据编辑处理技巧,让你在日常数据分析处理的疯魔状态中解放出来. 一.隐藏行列 “不得了了,Excel出现灵异事件,部分区域消失不见了!”办公室里的一个MM跑过来大声喊叫着,着实吓了俺一跳.待 ...

  8. 爬虫组NABC

    Need(需求): 我们小组的研究课题是编写一个更实用的爬虫软件,编写时会应用到学长的部分代码并在其基础上完善创新. 鉴于学长代码已经实现了基本功能,即从网站上面爬取相关的Word文档等与计算机有关的 ...

  9. WPF解析Word为图片

    偶遇需要解析Word为单张图,此做 http://git.oschina.net/jiailiuyan/OfficeDecoder using System; using System.Collect ...

  10. nenu contest2

    http://vjudge.net/vjudge/contest/view.action?cid=54562#overview H  B. Polygons http://codeforces.com ...