贝叶斯分层回归模型的推理、EM求解和Java编程

本文作者:合肥工业大学 管理学院 钱洋 email:1563178220@qq.com 。
内容可能有不到之处,欢迎交流

未经本人允许禁止转载

模型

如下为模型:
在这里插入图片描述
这个模型中,参数和协方差服从正太逆Wishart先验。
根据模型,给出所有变量的联合似然,即:
在这里插入图片描述

公式推理

因变量和权重的联合概率分布可表示为:
在这里插入图片描述
求对数:
在这里插入图片描述
其中,
在这里插入图片描述

EM求解

在这里插入图片描述
令:
在这里插入图片描述
在这里插入图片描述
则:
在这里插入图片描述

编程

下面,给出了EM算法迭代的核心代码:

/**EM UPDATE
	 * @author Qianyang
	 * ****/
public static Map<Integer, RealMatrix> expectationMaximizationUpdating(double []  meaninitial,RealMatrix spmpling_inverse_wishartinitial,double varianceinitial,Map<Integer,RealMatrix > xMatrixList,Map<Integer,RealMatrix > ymatrix,double epsilon) {
		//总体均值 mean input
		double [] mean = meaninitial;
		//总体协方差 covariance input
		RealMatrix   spmpling_inverse_wishart = spmpling_inverse_wishartinitial;
		//EStep
		Map<Integer,List<RealMatrix>> edata = CalculateExpectaction(mean,spmpling_inverse_wishart,varianceinitial,xMatrixList,ymatrix);
		Map<Integer,RealMatrix > wMatrixList = new HashMap<Integer,RealMatrix >();
		Map<Integer,RealMatrix > covariancematrixlist = new HashMap<Integer,RealMatrix >();
		for( int itemnumber : edata.keySet() ){
			wMatrixList.put(itemnumber, edata.get(itemnumber).get(0));
			covariancematrixlist.put(itemnumber, edata.get(itemnumber).get(1));
		}
		//Mstep
		MStepData mStepData = CalculateMaximization(wMatrixList,covariancematrixlist,xMatrixList,ymatrix);
		RealMatrix meanupdate = mStepData.getMeanupdate();
		RealMatrix covarianceupdate = mStepData.getCovarianceupdate();
		double varianceupdate = mStepData.getVarianceupdate();
		System.out.println(mStepData.getVarianceupdate());
		//获取单个产品的w矩阵及方差矩阵
		MStepData wMatrixandvariance = new MStepData();
		Map<Integer,MStepData > wMatrixandvariancemap = new HashMap<Integer,MStepData >();
		if (Math.abs(varianceupdate - varianceinitial) < epsilon) {
			System.out.println("meanupdate:"+meanupdate+"\tcovarianceupdate:"+covarianceupdate+"\tvarianceupdate:"+varianceupdate);
//			for( int itemnumber : edata.keySet() ){
//				System.out.println(itemnumber+":\t w:"+wMatrixList.get(itemnumber));
//			}
			
			
		}else{
			iter++;
			System.out.println("the current iter:\t"+iter);
			meaninitial = meanupdate.getColumnVector(0).toArray();
			spmpling_inverse_wishartinitial = covarianceupdate;
			varianceinitial = varianceupdate;
			expectationMaximizationUpdating(meanupdate.getColumnVector(0).toArray(),covarianceupdate,varianceupdate,xMatrixList,ymatrix,epsilon);
		}
		
		return wMatrixList;
	}

其中,E步的代码为:

/**E-STEP 
	 * mean is the value that sampling from multivariate normal distribution
	 * spmpling_inverse_wishart is the value that sampling from inverse wishart distribution  
	 * variance is the our difine.
	 * @author Qianyang
	 * ****/
	private static Map<Integer,List<RealMatrix>> CalculateExpectaction(double [] mean,RealMatrix   spmpling_inverse_wishart,double variance,Map<Integer,RealMatrix > xmatrix,Map<Integer,RealMatrix > ymatrix) {
		Map<Integer,List<RealMatrix>> weMap=new HashMap<Integer,List<RealMatrix>>();
		for( int itemnumber : ymatrix.keySet() ){
			RealMatrix meanmatrix = new Array2DRowRealMatrix(mean);
			//计算逆矩阵
			RealMatrix inverse_inverse_wishartMatrix = inverseMatrix(spmpling_inverse_wishart);
			//计算x*x的和除以方差
			RealMatrix xtransposematrix = xmatrix.get(itemnumber).transpose();
			RealMatrix xxMatrix = xmatrix.get(itemnumber).preMultiply(xtransposematrix).scalarMultiply(1/variance);
			RealMatrix inverse_first = inverseMatrix(inverse_inverse_wishartMatrix.add(xxMatrix));
			RealMatrix second = xmatrix.get(itemnumber).transpose().multiply(ymatrix.get(itemnumber).transpose()).scalarMultiply(1/variance).add(inverse_inverse_wishartMatrix.multiply(meanmatrix));
			RealMatrix wMatrix = inverse_first.multiply(second);
			//下面对协方差矩阵更新进行计算
			RealMatrix covariancematrix = inverseMatrix(inverse_inverse_wishartMatrix.add(xxMatrix));
//			System.out.println("covariancematrix:"+covariancematrix);
			List<RealMatrix> listRealMatrix = new ArrayList<RealMatrix>();
			//获取的w及协方差
			listRealMatrix.add(wMatrix);
			listRealMatrix.add(covariancematrix);
			weMap.put(itemnumber, listRealMatrix);
		}
		return weMap;
	}

M步的代码为:

/**M-STEP 
	 * mean is the value that sampling from multivariate normal distribution
	 * spmpling_inverse_wishart is the value that sampling from inverse wishart distribution  
	 * variance is the our define.
	  * @author Qianyang
	 * ****/
	private static MStepData CalculateMaximization(Map<Integer,RealMatrix > wMatrixList,Map<Integer,RealMatrix > covariancematrixlist,Map<Integer,RealMatrix > xmatrix,Map<Integer,RealMatrix > ymatrix) {
		//uw update
		RealMatrix meanupdate = updatew(wMatrixList).scalarMultiply(1/Double.valueOf(wMatrixList.size()));
		//covariance update 
		RealMatrix covarianceupdate = updatecovariance(wMatrixList,covariancematrixlist,meanupdate).scalarMultiply(1/Double.valueOf(wMatrixList.size()));
		//variance update 
		double varianceupdate = updatevariance(wMatrixList,xmatrix,ymatrix);
		List<RealMatrix> listRealMatrix = new ArrayList<RealMatrix>();
		MStepData datamodel = new MStepData();
		datamodel.setMeanupdate(meanupdate);
		datamodel.setCovarianceupdate(covarianceupdate);
		datamodel.setVarianceupdate(varianceupdate);
		return datamodel;
	}

该算法的完整代码在本人的Github上:https://github.com/soberqian/NIWSamplingProcess

下面是一个利用贝叶斯分层模型计算回归系数的R代码示例: ``` library(rstan) # 构建贝叶斯分层模型 model_code <- " data { int N; // 样本数 int K; // 自变量数 vector[K] x[N]; // 自变量 vector[N] y; // 因变量 } parameters { vector[K] beta; // 回归系数 real<lower=0> sigma; // 模型误差的标准差 } model { beta ~ normal(0, 10); // 回归系数的先验分布 sigma ~ cauchy(0, 5); // 模型误差的先验分布 y ~ normal(x * beta, sigma); // 因变量的后验分布 } " # 准备数据 data <- list( N = nrow(df), K = ncol(df) - 1, x = as.matrix(df[, -ncol(df)]), y = as.numeric(df[, ncol(df)]) ) # 运行贝叶斯分层模型 model <- stan_model(model_code = model_code) fit <- sampling(model, data = data, chains = 4, iter = 2000, warmup = 1000) # 输出回归系数的后验分布 summary(fit, par = "beta") ``` 这段代码中,我们首先定义了一个贝叶斯分层模型的代码,其中包括了数据、参数和模型的先验分布。然后,我们准备了数据,包括样本数N、自变量数K、自变量x和因变量y。接着,我们使用rstan包中的stan_model函数编译模型,并使用sampling函数运行模型,得到回归系数的后验分布。最后,我们使用summary函数输出回归系数的后验分布统计信息,包括均值、标准差、置信区间等。 需要注意的是,贝叶斯分层模型需要在Stan编程语言中进行编写,并使用rstan包在R中进行调用和运行。此外,模型参数的先验分布和MCMC采样的设置需要根据具体问题进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值