java代码----实现因子分析算法

许久没有管自己的博客了,问我要源码的亲们,现在可以看了,希望可以帮到你们。

代码如下:

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import Jama.Matrix;
import Util.DBConnection;

//因子分析
public class FactorAnalyse {
	// 从数据库中获取数据
	public double[][] getHseData(){
		List<Double> list = new ArrayList<Double>();
		double[][] result = new double[24][26];
		double[] temp = new double[24*26];
		
		String sql = "select score from HseScore";
		ResultSet rs = DBConnection.executeQuery(sql);
		try{
			while(rs.next()){
				list.add(rs.getDouble(1));
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		for(int i=0;i<list.size();i++){
			temp[i] = list.get(i);
		}
		for (int i = 0; i < 24; i++) {
			for (int j = 0; j < 26; j++) {
				result[i][j] = temp[26*i+j];
			}
		}
		Matrix m = new Matrix(result);
		m.print(3, 2);
		return result;
	}
	// 计算均值
	public double[] getAverage(double[][] array) {
		int h = array.length; // 行号--h
		int l = array[0].length;// 列号--l
		double[] average = new double[l];// 每个变量的均值
		for (int i = 0; i < l; i++) {
			double temp = 0.0;
			for (int j = 0; j < h; j++) {
				temp += array[j][i];
			}
			average[i] = temp / h;
			// System.out.printf("average[%d] = %.5f\n", i, average[i]);
		}
		return average;
	}

	// 计算方差
	public double[] getVariance(double[][] array) {
		int h = array.length; // 行号--h
		int l = array[0].length;// 列号--l
		double[] average = getAverage(array);
		double[] var = new double[l];

		for (int i = 0; i < l; i++) {
			double temp = 0.0;
			for (int j = 0; j < h; j++) {
				temp += Math.pow((array[j][i] - average[i]), 2);
			}
			var[i] = temp / (h - 1);
			// System.out.printf("var[%d] = %.5f\n", i, var[i]);
		}
		return var;
	}

	// 计算标准差
	public double[] getStandardDevition(double[] var) {
		double[] sd = new double[var.length];

		for (int i = 0; i < var.length; i++) {
			sd[i] = Math.sqrt(var[i]);
			// System.out.printf("sd[%d] = %.5f\n", i, sd[i]);
		}
		return sd;
	}

	// 标准化数据
	public double[][] getStandard(double[][] array, double[] sd) {
		int h = array.length; // 行号--h
		int l = array[0].length;// 列号--l
		double[][] result = new double[h][l];// 标准化
		double[] average = getAverage(array);

		for (int i = 0; i < h; i++) {
			for (int j = 0; j < l; j++) {
				result[i][j] = (array[i][j] - average[j]) / sd[j];
			}
		}
		Matrix m = new Matrix(result);
		m.print(5, 3);
		
		return result;
	}

	// 计算协方差矩阵--方阵
	public double[][] getCovMatrix(double[][] array) {
		int h = array.length;
		int l = array[0].length;
		double[][] temp = new double[h][l];// 保存计算协方差的中间矩阵
		double[][] result = new double[l][l];
		double[] average = getAverage(array); // 标准化后的矩阵求均值

		for (int i = 0; i < h; i++) {
			for (int j = 0; j < l; j++) {
				temp[i][j] = array[i][j] - average[j];
			}
		}
		for (int i = 0; i < l; i++) {
			for (int j = 0; j < l; j++) {
				double t = 0;
				for (int k = 0; k < h; k++) {
					t += temp[k][i] * temp[k][j];
				}
				result[i][j] = t / (h - 1);
			}
		}
		Matrix m = new Matrix(result);
		m.print(5, 3);
		
		return result;
	}

	// 计算相关矩阵---方阵
	public double[][] getCorrelationMatrix(double[][] cov, double[] sd) {
		int l = cov.length;
		double[][] result = new double[l][l];

		for (int i = 0; i < l; i++) {
			for (int j = 0; j < l; j++) {
				result[i][j] = cov[i][j] / (sd[i] * sd[j]);
			}
		}
		Matrix m = new Matrix(result);
		m.print(5, 3);
		return result;
	}

	// 求矩阵特征值
	public double[][] getEigenvalue(double[][] array) {
		int h = array.length;// 行号等于列号
		double[][] result = new double[h][h];

		Matrix m = new Matrix(array);
		Matrix m1 = m.eig().getD(); // 由特征值组成的对角矩阵
		System.out.println("由特征值组成的对角矩阵:");
		m1.print(5, 3);
		result = m1.getArray();
		
		return result;
	}

	// 求矩阵的特征向量
	public double[][] getEigenvector(double[][] array) {
		int h = array.length;// 行号等于列号
		double[][] result = new double[h][h];

		Matrix m = new Matrix(array);
		Matrix m1 = m.eig().getV(); // 该矩阵的每一列对应的是一个单位正交特征向量
		System.out.println("\n特征向量矩阵:");
		m1.print(5, 3);
		result = m1.getArray();
		
		return result;
	}

	// 特征值从大到小排序并保存成键值对形式
	public TreeMap<Integer, Double> getMap(double[][] array) {
		int h = array.length;
		Map<Integer, Double> map = new HashMap<Integer, Double>();
		ValueComparator bvc = new ValueComparator(map);
		TreeMap<Integer, Double> sorted_map = new TreeMap<Integer, Double>(bvc);
		double[] temp = new double[h]; // 存储特征值
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < h; j++) {
				if (i == j)
					temp[i] = array[i][j];
			}
		}
		for (int i = 0; i < temp.length; i++) {
			map.put(i, temp[i]);
		}
		System.out.println("\n排序前键值对:\n" + map);
		sorted_map.putAll(map);
		System.out.println("\n排序后的键值对:\n" + sorted_map);

		return sorted_map;
	}

	// 计算方差贡献率
	public double[] getContibutionRatio(TreeMap<Integer, Double> tm) {
		int h = tm.size();
		double[] percent = new double[h];
		Iterator titer = tm.entrySet().iterator();
		int count = 0;
		
		while (titer.hasNext()) {
			Map.Entry ent = (Map.Entry) titer.next();
			int keyt = (Integer) ent.getKey();
			double valuet = (Double) ent.getValue();
			percent[count] = valuet / h;
			System.out.printf("\n键%d 对应的特征值 %.3f所占的比例为  %.3f \n",keyt,valuet,percent[count]);
			count++;
		}
		return percent;
	}

	// 计算方差累积贡献率
	public double[] getCumuContributionRatio(double[] array) {
		double[] result = new double[array.length];
		double temp = 0.0;
		for (int i = 0; i < array.length; i++) {
			temp += array[i];
			result[i] = temp;
			System.out.printf("\n累积贡献率:%.3f \n", result[i]);
		}
		return result;
	}

	// 确定公共因子的个数
	public int getNum(double[] array) {
		int number = 1;// 公因子个数
		double t = 0.0;
		for (int i = 0; i < array.length; i++) {
			t = array[i];
			if (t < 0.75)
				number++;
		}
		System.out.println("\n公共因子个数:" + number);
		return number;
	}

	// 获取特征值对应的特征向量
	public double[][] getVVector(TreeMap<Integer, Double> tm, double[][] array) {
		int h = array.length;
		double[][] result = new double[h][h];
		int[] temp = new int[h];
		Iterator titer = tm.entrySet().iterator();
		int count = 0;
		while (titer.hasNext()) {
			Map.Entry ent = (Map.Entry) titer.next();
			int keyt = (Integer) ent.getKey();
			temp[count] = keyt;
			// System.out.println("temp["+count+"] = "+temp[count]);
			count++;
		}
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < h; j++) {
				result[i][j] = array[i][temp[j]];
			}
		}
		System.out.println("特征值对应的特征向量组成的矩阵:");
		Matrix m = new Matrix(result);
		m.print(5, 3);
		return result;
	}

	// 获取因子载荷矩阵
	public double[][] getMatrixA(TreeMap<Integer, Double> tm, double[][] array,
			int num) {
		int h = array.length;
		double[][] A = new double[h][num];
		double[] temp = new double[h];
		Iterator titer = tm.entrySet().iterator();
		int count = 0;
		while (titer.hasNext()) {
			Map.Entry ent = (Map.Entry) titer.next();
			double valuet = (Double) ent.getValue();
			temp[count] = Math.sqrt(valuet);
			// System.out.printf("特征值开平方根:%.5f\n", temp[count]);
			count++;
		}
		System.out.println("因子载荷矩阵 A = ");
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < num; j++) {
				A[i][j] = temp[j] * array[i][j];
			}
		}
		Matrix m = new Matrix(A);
		m.print(5, 3);
		return A;
	}

	// 获取特殊因子矩阵
	public double[][] getMatrixD(TreeMap<Integer, Double> tm, double[][] array,
			int num) {
		int h = array.length;
		double[][] B = new double[h][h - num];
		double[][] C = new double[h][h];
		double[][] D = new double[h][h];
		double[] temp = new double[h];
		Iterator titer = tm.entrySet().iterator();
		int count = 0;
		while (titer.hasNext()) {
			Map.Entry ent = (Map.Entry) titer.next();
			double valuet = (Double) ent.getValue();
			temp[count] = Math.sqrt(valuet);
			count++;
		}
		for (int i = 0; i < h; i++) {
			for (int j = num; j < h; j++) {
				B[i][j - num] = temp[j] * array[i][j];
			}
		}
		Matrix m = new Matrix(B);
		Matrix m1 = m.times(m.transpose());
		C = m1.getArray();
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < h; j++) {
				if (i == j)
					D[i][j] = C[i][j];
			}
		}
		System.out.println("特殊因子矩阵 D = ");
		Matrix m2 = new Matrix(D);
		m2.print(5, 3);
		return D;
	}	
	
	// 进行因子旋转--方差最大正交旋转
	public double[][] getVarimax(double[][] array, int num) {
		int h = array.length;
		int l = array[0].length;
		double[] hi = new double[h]; // 变量共同度
		double[][] standardA = new double[h][l];//标准化处理因子载荷阵
		double[][] result = new double[h][l];// 旋转后的因子载荷矩阵
		double[] u = new double[h];
		double[] v = new double[h];
		double A = 0.0;
		double B = 0.0;
		double C = 0.0;
		double D = 0.0;
		double E = 0.0;
		//标准化处理A
		for (int i = 0; i < h; i++) {
			double temp = 0.0;
			for (int j = 0; j < l; j++) {
				temp += Math.pow(array[i][j], 2);
			}
			hi[i] = temp;
			//System.out.printf("变量共同度:%.5f\n", hi[i]);
		}
		for(int i = 0; i < h; i++){
			for(int j = 0; j < l; j++){
				standardA[i][j] = Math.pow(array[i][j],2) / hi[i];
			}
		}
	
		double[][] P = new double[l][l]; // 构造正交矩阵
		Matrix m = new Matrix(standardA);
		for (int k = 0; k < num-1; k++) {
			for (int p = k+1; p < num; p++) {
				for (int i = 0; i < h; i++) {
					u[i] = (Math.pow(array[i][k], 2) - Math.pow(array[i][p], 2)) / hi[i];
				}
				for (int i = 0; i < h; i++) {
					v[i] = (2 * array[i][k] * array[i][p]) / hi[i];
				}
				for (int i = 0; i < h; i++) {
					A += u[i];
					B += v[i];
					C += (u[i] * u[i]) - (v[i] * v[i]);
					D += 2 * u[i] * v[i];
				}
				E = (Math.atan((D - (2 * A * B) / h) / (C - (A * A - B * B) / h))) / 4.0;
				//System.out.printf("\n旋转角度 E = %.5f\n", E);
				for (int i = 0; i < l; i++) {
					for (int j = 0; j < l; j++) {
						if (i == j)
							P[i][j] = 1;
						else
							P[i][j] = 0;
					}
				}
				double[][] T = P;
				T[k][k] = Math.cos(E);
				T[k][p] = -Math.sin(E);
				T[p][k] = Math.sin(E);
				T[p][p] = Math.cos(E);
				Matrix m1 = new Matrix(T);//正交矩阵
				m = m.times(m1);
			}
		}
		m.print(5, 3);
		result = m.getArray();
		return result;
	}
	// 计算旋转后的方差贡献率
		public double[] getContibutionRatio1(double[][] array) {
			int h = array.length;
			int l = array[0].length;
			double[] percent = new double[h];
			double sum = 0.0;
			for(int i = 0; i < l;i++){
				double temp = 0.0;
				for(int j = 0; j < h;j++){
					temp += Math.pow(array[j][i],2);
				}
				percent[i] = temp / h; 
				//System.out.printf("\n旋转后的方差贡献率--F["+(i+1)+"]: %.3f\n",percent[i]);
				sum += percent[i];
			}
			//System.out.printf("\n方差累积贡献率::%.3f\n",sum);
			return percent;
		}
	// 计算因子载荷的方差
		public double getA_Var(double[][] array) {
			int h = array.length;
			int l = array[0].length;
			double[] var = new double[l];// 每一列的方差
			double v = 0.0;// 总方差
			double[][] B = new double[h][l];
			
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < l; j++) {
					B[i][j] = Math.pow(array[i][j],2);
				}
			}
			double[] ad = getAverage(B);
			for (int i = 0; i < l; i++) {
				double temp = 0.0;
				for (int j = 0; j < h; j++) {
					temp += Math.pow(B[j][i] - ad[i], 2);
				}
				var[i] = temp / h;
				//System.out.printf("每一列的方差:%.5f\n", var[i]);
				v += var[i];
			}
			System.out.printf("总方差:%.3f\n", v);
			return v;
		}
		
	// 计算因子得分
	public double[][] getScore(double[][] R, double[][] A,double[][] array) {
		int h = A.length;
		int l = R[0].length;
		double[][] F = new double[h][l];

		Matrix m = new Matrix(A);
		Matrix m1 = new Matrix(R);
		Matrix m2 = (m.transpose()).times(m1.inverse());
		Matrix m3 = new Matrix(array);
		Matrix m4 = (m2).times(m3.transpose());
		System.out.println("因子得分:");
		m4.transpose().print(5, 3);
		F = m4.transpose().getArray();
		return F;
	}
	//计算因子综合得分
	public double[] getScores(double[][] array,double[] percent){
		int h = array.length;
		int l = array[0].length;
		double[] result = new double[h];
		double temp = 0.0;
		
		for(int i = 0; i < l; i++){
			temp +=percent[i];
		}
		for(int i = 0; i < h; i++){
			double t = 0.0;
			for(int j = 0; j < l; j++){
				t += array[i][j] * percent[j];
			}
			result[i] = t / temp;
			System.out.printf("综合得分:%.3f\n",result[i]);
		}
		return result;
	}
}
// map按值进行排序
class ValueComparator implements Comparator<Integer> {

	Map<Integer, Double> base;

	public ValueComparator(Map<Integer, Double> base) {
		this.base = base;
	}

	public int compare(Integer a, Integer b) {
		if (base.get(a) >= base.get(b)) {
			return -1;
		} else {
			return 1;
		}
	}
}

完整代码已贴出,有需要的朋友请查看,转载请注明出处,谢谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值