读书笔记:Algorithms for Decision Making(3)

读书笔记:Algorithms for Decision Making

上一篇 读书笔记:Algorithms for Decision Making(2)
下一篇 读书笔记:Algorithms for Decision Making(4)



二、概率推理(2)

上一部分给出了概率分布的表示论。本部分将展示如何使用概率表示进行推理,即确定一组给定观察变量相关值的一个或多个未观察变量的分布。在该部分中首先介绍直接推断的办法,然后给出几种有效的近似方法。


2. 推断

2.1 贝叶斯网络中的推断

在推断问题中,通过给定的可观测的证据变量 A A A,推断查询变量(query variables ) B B B的分布。 其他节点被称为隐藏变量(hidden variables)。通常将在给定证据变量前提下的查询变量的分布 P ( B ∣ A ) \mathbb{P} (B \mid A) P(BA)称为后验分布(posterior distribution)。

使用条件概率定义、边缘化和链式规则可用于在任何贝叶斯网络中进行精确推理。用因子代表多元分布,可描述为:

  • 使用因子乘积组合两个因子,以产生更大的因子,其范围是输入因子的组合范围。 φ ( X , Y ) , ψ ( Y , Z ) → ( φ ⋅ ψ ) ( X , Y , Z ) = φ ( X , Y ) ψ ( Y , Z ) . \varphi(X, Y), \psi(Y, Z) \to (\varphi \cdot \psi) (X, Y, Z) = \varphi(X, Y) \psi(Y, Z) . φ(X,Y),ψ(Y,Z)(φψ)(X,Y,Z)=φ(X,Y)ψ(Y,Z).
    	function Base.:*(ϕ::Factor, ψ::Factor)
    	ϕnames = variablenames(ϕ)
    	ψnames = variablenames(ψ)
    	ψonly = setdiff(ψ.vars, ϕ.vars)
    	table = FactorTable()
    	for (ϕa,ϕp) in ϕ.table
    		for a in assignments(ψonly)
    			a = merge(ϕa, a)
    			ψa = select(a, ψnames)
    			table[a] = ϕp * get(ψ.table, ψa, 0.0)
    		end
    	end
    	vars = vcat(ϕ.vars, ψonly)
    	return Factor(vars, table)
    end
    
  • 使用因子边缘化从整个因子表中求出特定变量,并将其从结果范围中移除。
    function marginalize(ϕ::Factor, name)
    	table = FactorTable()
    	for (a, p) in ϕ.table
    		a′ = delete!(copy(a), name)
    		table[a′] = get(table, a′, 0.0) + p
    	end
    	vars = filter(v -> v.name != name, ϕ.vars)
    	return Factor(vars, table)
    end
    
  • 对一些证据使用因子条件,以删除表中与该证据不一致的任何行。
    in_scope(name, ϕ) = any(name == v.name for v in ϕ.vars)
    
    function condition(ϕ::Factor, name, value)
    	if !in_scope(name, ϕ)
    		return ϕ
    	end
    	table = FactorTable()
    	for (a, p) in ϕ.table
    		if a[name] == value
    			table[delete!(copy(a), name)] = p
    		end
    	end
    	vars = filter(v -> v.name != name, ϕ.vars)
    	return Factor(vars, table)
    end
    
    function condition(ϕ::Factor, evidence)
    	for (name, value) in pairs(evidence)
    		ϕ = condition(ϕ, name, value)
    	end
    	return ϕ
    end
    
    将上述三部分可统一为
    struct ExactInference end
    
    function infer(M::ExactInference, bn, query, evidence)
    	ϕ = prod(bn.factors)
    	ϕ = condition(ϕ, evidence)
    	for name in setdiff(variablenames(ϕ), query)
    		ϕ = marginalize(ϕ, name)
    	end
    	return normalize!(ϕ)
    end
    

朴素贝叶斯模型是贝叶斯模型的一个特例,因为它假设了给定类的证据变量之间具有条件独立性。

2.2 和积变量消去(Sum-Product Variable Elimination)法

和积变量消除法将消除隐藏变量(和)与应用链式规则(积)交错。尽早将变量边缘化更有效,以避免产生大的因素。

struct VariableElimination
	ordering # array of variable indices
end

function infer(M::VariableElimination, bn, query, evidence)
	Φ = [condition(ϕ, evidence) for ϕ in bn.factors]
	for i in M.ordering
		name = bn.vars[i].name
		if name ∉ query
			inds = findall(ϕ->in_scope(name, ϕ), Φ)
			if !isempty(inds)
				ϕ = prod(Φ[inds])
				deleteat!(Φ, inds)
				ϕ = marginalize(ϕ, name)
				push!(Φ, ϕ)
			end
		end
	end
	return normalize!(prod(Φ))
end

2.3 置信传播(Belief Propagation)1

置信传播通过使用和积算法在网络中传播“消息”,以计算查询变量的边际分布。该方法的时间复杂度为线性时间,但仅当网络没有无向循环时才提供精确答案。如果网络具有无向循环,则可以通过使用连接树(junction tree)算法将多个变量组合成单个节点,将其转换为树。如果必须组合到结果网络中的任何一个节点中的变量数量较少,则可以有效地进行推理。

其变形算法——循环置信传播(loopy belief propagation)可以在具有无向循环的网络中提供近似解。尽管这种方法不提供任何保证,也可能不收敛,但在实践中它可以很好地工作。

2.4 直接采样

由于精确推理在计算上难以处理,许多近似方法被开发出来。最简单的推断方法之一是基于直接抽样,其中联合分布的随机样本用于获得概率估计。
从贝叶斯网络表示的联合分布中采样是直接的。

  • 第一步涉及在贝叶斯网络中找到节点的拓扑排序。
  • 从有拓扑排序的贝叶斯网络中进行条件概率采样。
    function Base.rand(ϕ::Factor)
    	tot, p, w = 0.0, rand(), sum(values(ϕ.table))
    	for (a,v) in ϕ.table
    		tot += v/w
    		if tot >= p
    			return a
    		end
    	end
    	return Assignment()
    end
    
    function Base.rand(bn::BayesianNetwork)
    	a = Assignment()
    	for i in topological_sort(bn.graph)
    		name, ϕ = bn.vars[i].name, bn.factors[i]
    		a[name] = rand(condition(ϕ, a))[name]
    	end
    	return a
    end
    
  • 直接采样的实现
    struct DirectSampling
    	m # number of samples
    end
    
    function infer(M::DirectSampling, bn, query, evidence)
    	table = FactorTable()
    	for i in 1:(M.m)
    		a = rand(bn)
    		if all(a[k] == v for (k,v) in pairs(evidence))
    			b = select(a, query)
    			table[b] = get(table, b, 0) + 1
    		end
    	end
    	vars = filter(v->v.name ∈ query, bn.vars)
    	return normalize!(Factor(vars, table))
    end
    

2.5 似然加权采样

直接采样的问题是,可能会浪费时间生成与观测结果不一致的样本,尤其是在观测结果不太可能的情况下。似然加权抽样生成与观测结果一致的加权样本。

struct LikelihoodWeightedSampling
	m # number of samples
end

function infer(M::LikelihoodWeightedSampling, bn, query, evidence)
	table = FactorTable()
	ordering = topological_sort(bn.graph)
	for i in 1:(M.m)
		a, w = Assignment(), 1.0
		for j in ordering
			name, ϕ = bn.vars[j].name, bn.factors[j]
			if haskey(evidence, name)
				a[name] = evidence[name]
				w *= ϕ.table[select(a, variablenames(ϕ))]
			else
				a[name] = rand(condition(ϕ, a))[name]
			end
		end
		b = select(a, query)
		table[b] = get(table, b, 0) + w
	end
	vars = filter(v->v.name ∈ query, bn.vars)
	return normalize!(Factor(vars, table))
end

2.6 Gibbs采样

Gibbs采样是一种马尔可夫链Monte Carlo方法,以不涉及加权的方式抽取与证据一致的样本。与迄今讨论的其他采样方法不同,该方法产生的样本不是独立的。然而,可以证明,在极限情况下,样本是从给定观测值的未观测变量的联合分布中精确提取的。

function blanket(bn, a, i)
	name = bn.vars[i].name
	val = a[name]
	a = delete!(copy(a), name)
	Φ = filter(ϕ -> in_scope(name, ϕ), bn.factors)
	ϕ = prod(condition(ϕ, a) for ϕ in Φ)
	return normalize!(ϕ)
end

其实现过程为

function update_gibbs_sample!(a, bn, evidence, ordering)
	for i in ordering
		name = bn.vars[i].name
		if !haskey(evidence, name)
			b = blanket(bn, a, i)
			a[name] = rand(b)[name]
		end
	end
end

function gibbs_sample!(a, bn, evidence, ordering, m)
	for j in 1:m
		update_gibbs_sample!(a, bn, evidence, ordering)
	end
end

struct GibbsSampling
	m_samples # number of samples to use
	m_burnin # number of samples to discard during burn-in
	m_skip # number of samples to skip for thinning
	ordering # array of variable indices
end

function infer(M::GibbsSampling, bn, query, evidence)
	table = FactorTable()
	a = merge(rand(bn), evidence)
	gibbs_sample!(a, bn, evidence, M.ordering, M.m_burnin)
	for i in 1:(M.m_samples)
		gibbs_sample!(a, bn, evidence, M.ordering, M.m_skip)
		b = select(a, query)
		table[b] = get(table, b, 0) + 1
	end
	vars = filter(v->v.name ∈ query, bn.vars)
	return normalize!(Factor(vars, table))
end


  1. F.Kschischang, B. Frey, and H.-A.Loeliger, “Factor graphs and the sum-product algorithm,” IEEE Transactions on Information Theory, vol. 47, no. 2, pp. 498–519, 2001. ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值