权重确定方法四:主成分分析法确定权重(PCA)

 我想在列车里和你相爱

阳光流淌

都漫过我们的灵魂尽头

然后看着人间

安静的盛开在一扇窗里

目录

1.原理介绍

2.步骤详解

2.1 确定指标在各主成分线性组合中的系数

2.2 利用主成分的方差贡献率确定综合得分模型系数

2.3 指标权重归一化

3. 案例分析

3.1 数据获取

3.2 确定指标在各主成分线性组合中的系数

3.3 利用主成分的方差贡献率确定综合得分模型系数

3.4 指标权重归一化

 4. 完整代码(Java)


1.原理介绍

        在阅读本文前建议先阅读上一篇文章 “数据降维:主成分分析法(PCA)”,因为在本文中需要用到部分数据降维中的数据。

        用主成分分析确定权重有:指标权重等于以主成分的方差贡献率为权重,对该指标在各主成分线性组合中的系数的加权平均的归一化。

        因此,要确定指标权重需要知道三点:

        A.指标在各主成分线性组合中的系数

        B.主成分的方差贡献率

        C.指标权重的归一化

        通过前文利用主成分分析对数据降维我们可以得到以下数据:

        A.前p个主成分的特征值以及对应的特征向量

        B.前p个主成分特征值各自的方差贡献率

2.步骤详解

2.1 确定指标在各主成分线性组合中的系数

假设现有一组数据,有n个指标,m条待评价对象。

用主成分分析法可以的到前p个主成分以及其对应的特征值 \alpha 和特征向量 \beta

则每个主成分中对应指标的系数为:

 

 每个主成分都可以用如下的线性组合表示:

2.2 利用主成分的方差贡献率确定综合得分模型系数

        记前p个主成分特征值的方差贡献率为\varphi,综合得分模型系数为\gamma\gamma对应每个指标的综合系数),则:

则,得到综合得分模型为:

2.3 指标权重归一化

3. 案例分析

3.1 数据获取

本文所用数据均为上文数据降维:主成分分析法(PCA)所计算结果:

p1p2p3p4p5p6p7
特征值2045.7371273.595950.6142821.2534361.4991260.859175.7022
贡献率34.43%21.44%16.00%13.82%6.08%4.39%2.96%
特征向量0.414-0.130.0410.193-0.1250.7680.077
-0.282-0.4830.07-0.009-0.733-0.082-0.328
-0.3570.2960.4540.245-0.1090.406-0.181
-0.264-0.08-0.4660.6570.3030.006-0.404
-0.539-0.1890.259-0.0460.22-0.0190.373
0.096-0.012-0.4550.219-0.402-0.0820.46
0.066-0.5710.270.3960.187-0.0580.402
-0.1660.5390.070.369-0.312-0.1310.355
0.4680.0590.4670.358-0.044-0.459-0.228

3.2 确定指标在各主成分线性组合中的系数

	//计算每个指标在不同主成分线性组合中的系数
	public double[][] coefficient(double[][] comp){
		double[][] coeff = new double[comp.length-1][comp[0].length];//每列存储每个主成分对应的系数
		var = new double[comp[0].length];
		
		for(int j=0;j<coeff[0].length ;j++) {
		var[j] = comp[0][j];
			for(int i=1;i<coeff.length ;i++) {
				coeff[i-1][j] = comp[i][j]/Math.sqrt(comp[0][j]);
			}
		}

		return coeff;
	}

 输出:

3.3 利用主成分的方差贡献率确定综合得分模型系数

	public double[] var_cont(double[][] coefficient) {
		double[] cont = new double[var.length];//每个特征值对应的贡献率
		double[] var_cont = new double[coefficient.length];
		double total = 0;
		double sum = 0;
		System.out.println("请按以下特征值顺序依次输入对应的贡献率!");
		for(int i=0;i<var.length ;i++) {
			System.out.print(var[i]+"     ");
		}
		System.out.println();
		for(int i=0;i<var.length ;i++) {
			cont[i] = input.nextDouble();
		}
		
		for(int i=0;i<coefficient.length ;i++) {
			for(int j=0;j<coefficient[0].length ;j++) {
				sum += coefficient[i][j]*cont[j];
				total += cont[j];
			}
			var_cont[i] = sum/total;
		}
		
		return var_cont;
	}

输出:

3.4 指标权重归一化

        在此模块做了一点变动,由于在计算过程中存在负数,导致最后求得的权重也存在负数,所以在此我们找出负数中最小的值,让每一个数都加上该值得绝对值,在进行运算。

	/*归一化权重
	 * varcont:综合得分模型系数
	 */
	
	public double[] unifor(double[] varcont) {
		double sum=0;
		double min=varcont[0];
		for(int i=0;i<varcont.length ;i++) {
			if(varcont[i] < min) {
				min =varcont[i];
			}
		}
		//若果没有负数则不做变动
		if(min >= 0) {
			min = 0;
		}
		for(int i=0;i<varcont.length ;i++) {
			sum += varcont[i]+Math.abs(min);
		}
		for(int i=0;i<varcont.length ;i++) {
			varcont[i] = (varcont[i]+Math.abs(min))/sum;
		}
		
		return varcont;
	}

 输出:

 4. 完整代码(Java)

package pca_weight;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.WriteException;

/*
 * 输入为成分矩阵,即前m个特征值及其对应的特征向量组成的矩阵
 * 其中第一行为特征值,每列除第一行外其余为该特征值对应的特征向量
 */

public class PCA_weight {
	int rows,cols;
	double[] var;//存储特征值
	
	Scanner input = new Scanner(System.in);
	
	//输出一维矩阵
	public void matrixoutput1(double[] x) {
		for(int i=0;i<x.length;i++) {
			System.out.print(String.format("%.3f\t", x[i]));
		}
		System.out.println();
	}
	
	//输出二维矩阵
	public void matrixoutput(double[][] x) {
		for(int i=0;i<x.length;i++) {
			for(int j=0;j<x[0].length;j++) {
				System.out.print(String.format("%.3f\t", x[i][j]));
			}
			System.out.println();
		}
	}
	
	//读取数据
	public double[][] read(String filepath) throws IOException, BiffException,WriteException {
		//创建输入流
		InputStream stream = new FileInputStream(filepath);
		//获取Excel文件对象
		Workbook  rwb = Workbook.getWorkbook(stream);
		//获取文件的指定工作表 默认的第一个
	    Sheet sheet = rwb.getSheet("Sheet1");
	    rows = sheet.getRows();
	    cols = sheet.getColumns();
	    double[][] componentMartix = new double[rows][cols];//成分矩阵
		//row为行
		for(int i=0;i<sheet.getRows();i++) {
			for(int j=0;j<sheet.getColumns();j++) {
				String[] str = new String[sheet.getColumns()];
		        Cell cell = null;
		        cell = sheet.getCell(j,i);    
			    str[j] = cell.getContents();
			    componentMartix[i][j] = Double.valueOf(str[j]);
			}
	    }
		return componentMartix;//返回原始矩阵
	}
	
	//计算每个指标在不同主成分线性组合中的系数
	public double[][] coefficient(double[][] comp){
		double[][] coeff = new double[comp.length-1][comp[0].length];//每列存储每个主成分对应的系数
		var = new double[comp[0].length];
		
		for(int j=0;j<coeff[0].length ;j++) {
		var[j] = comp[0][j];
			for(int i=1;i<coeff.length ;i++) {
				coeff[i-1][j] = comp[i][j]/Math.sqrt(comp[0][j]);
			}
		}

		return coeff;
	}
	
	public double[] var_cont(double[][] coefficient) {
		double[] cont = new double[var.length];//每个特征值对应的贡献率
		double[] var_cont = new double[coefficient.length];
		double total = 0;
		double sum = 0;
		System.out.println("请按以下特征值顺序依次输入对应的贡献率!");
		for(int i=0;i<var.length ;i++) {
			System.out.print(var[i]+"     ");
		}
		System.out.println();
		for(int i=0;i<var.length ;i++) {
			cont[i] = input.nextDouble();
		}
		
		for(int i=0;i<coefficient.length ;i++) {
			for(int j=0;j<coefficient[0].length ;j++) {
				sum += coefficient[i][j]*cont[j];
				total += cont[j];
			}
			var_cont[i] = sum/total;
		}
		
		return var_cont;
	}
	
	/*归一化权重
	 * varcont:综合得分模型系数
	 */
	
	public double[] unifor(double[] varcont) {
		double sum=0;
		double min=varcont[0];
		for(int i=0;i<varcont.length ;i++) {
			if(varcont[i] < min) {
				min =varcont[i];
			}
		}
		//若果没有负数则不做变动
		if(min >= 0) {
			min = 0;
		}
		for(int i=0;i<varcont.length ;i++) {
			sum += varcont[i]+Math.abs(min);
		}
		for(int i=0;i<varcont.length ;i++) {
			varcont[i] = (varcont[i]+Math.abs(min))/sum;
		}
		
		return varcont;
	}
	
	
	public static void main(String[] args) throws IOException, BiffException, WriteException {
		PCA_weight pw = new PCA_weight();
		System.out.println("原始数据为:");
		double[][] comp = pw.read("pca_weight.xls");
		pw.matrixoutput(comp);
		
		System.out.println("指标在不同主成分线性组合中的系数:");
		double[][] coefficient = pw.coefficient(comp);
		pw.matrixoutput(coefficient);
		
		double[] var_cont = pw.var_cont(coefficient);
		System.out.println("综合得分模型系数:");
		pw.matrixoutput1(var_cont);
		
		System.out.println("每个指标的权重依次为:");
		for(int i=0;i<var_cont.length;i++) {
			System.out.println(pw.unifor(var_cont)[i]);
		}
		
		
	}

}

  • 24
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
主成分分析(Principal Component Analysis,简称PCA)是一种常用的多变量数据降维方法,通过将原始变量转换为新的变量,即主成分,来描述数据的变异。在主成分分析中,权重分配指的是各个原始变量对于主成分的贡献程度。权重分配的计算主要通过计算因子载荷矩阵来实现。 在SPSS中进行主成分分析时,可以选择不同的抽取方法,例如主成分、因子等。如果选择主成分作为抽取方法,那么计算得到的就是主成分的得分。在主成分分析中,主成分的得分可以通过因子载荷矩阵与原始变量的值相乘并求和得到。 对于权重分配,一般是根据因子载荷矩阵来确定,即每个原始变量对应的因子载荷值。因子载荷值表示了每个原始变量对于主成分的重要程度,较大的载荷值表示该变量对主成分的贡献较大。一般来说,主成分分析会将载荷值做标准化处理,使得载荷值的平方和为1。 要注意的是,在SPSS中显示的成分矩阵(初始因子载荷矩阵)并不是主成分的系数阵。主成分的权重分配需要通过因子加载矩阵来计算。 至于具体的权重分配方法和表达式,可能需要参考相关研究中的具体方法和公式。在您提到的余凯《基于主成分分析的灰色预测方法的房地产预警体系研究》中,作者可能通过特征值和特征向量来计算综合得分表达式,并进一步得出了各个指标的权重。具体的细节可能需要参考该研究的相关内容。 希望我的回答能对您有所帮助。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离陌lm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值