文档章节

主成分分析(PCA) Java

Harry_sir
 Harry_sir
发布于 2017/08/28 16:25
字数 1160
阅读 1.4K
收藏 0

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

导入jar包:Jama-1.0.2.jar

//========计算类===========

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import Jama.Matrix;

/*
 * 算法步骤:
 * 1)将原始数据按列组成n行m列矩阵X
 * 2)特征中心化。即每一维的数据都减去该维的均值,使每一维的均值都为0
 * 3)求出协方差矩阵
 * 4)求出协方差矩阵的特征值及对应的特征向量
 * 5)将特征向量按对应的特征值大小从上往下按行排列成矩阵,取前k行组成矩阵p
 * 6)Y=PX 即为降维到k维后的数据
 */
public class PCA {

    private static final double threshold = 0.95;// 特征值阈值

    /**
     * 
     * 使每个样本的均值为0
     * 
     * @param primary
     *            原始二维数组矩阵
     * @return averageArray 中心化后的矩阵
     */
    public double[][] changeAverageToZero(double[][] primary) {
        int n = primary.length;
        int m = primary[0].length;
        double[] sum = new double[m];
        double[] average = new double[m];
        double[][] averageArray = new double[n][m];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                sum[i] += primary[j][i];
            }
            average[i] = sum[i] / n;
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                averageArray[j][i] = primary[j][i] - average[i];
            }
        }
        return averageArray;
    }

    /**
     * 
     * 计算协方差矩阵
     * 
     * @param matrix
     *            中心化后的矩阵
     * @return result 协方差矩阵
     */
    public double[][] getVarianceMatrix(double[][] matrix) {
        int n = matrix.length;// 行数
        int m = matrix[0].length;// 列数
        double[][] result = new double[m][m];// 协方差矩阵
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < m; j++) {
                double temp = 0;
                for (int k = 0; k < n; k++) {
                    temp += matrix[k][i] * matrix[k][j];
                }
                result[i][j] = temp / (n - 1);
            }
        }
        return result;
    }

    /**
     * 求特征值矩阵
     * 
     * @param matrix
     *            协方差矩阵
     * @return result 向量的特征值二维数组矩阵
     */
    public double[][] getEigenvalueMatrix(double[][] matrix) {
        Matrix A = new Matrix(matrix);
        // 由特征值组成的对角矩阵,eig()获取特征值
        A.eig().getD().print(10, 6);
        double[][] result = A.eig().getD().getArray();
        return result;
    }

    /**
     * 标准化矩阵(特征向量矩阵)
     * 
     * @param matrix
     *            特征值矩阵
     * @return result 标准化后的二维数组矩阵
     */
    public double[][] getEigenVectorMatrix(double[][] matrix) {
        Matrix A = new Matrix(matrix);
        A.eig().getV().print(6, 2);
        double[][] result = A.eig().getV().getArray();
        return result;
    }

    /**
     * 寻找主成分
     * 
     * @param prinmaryArray
     *            原始二维数组数组
     * @param eigenvalue
     *            特征值二维数组
     * @param eigenVectors
     *            特征向量二维数组
     * @return principalMatrix 主成分矩阵
     */
    public Matrix getPrincipalComponent(double[][] primaryArray,
            double[][] eigenvalue, double[][] eigenVectors) {
        Matrix A = new Matrix(eigenVectors);// 定义一个特征向量矩阵
        double[][] tEigenVectors = A.transpose().getArray();// 特征向量转置
        Map<Integer, double[]> principalMap = new HashMap<Integer, double[]>();// key=主成分特征值,value=该特征值对应的特征向量
        TreeMap<Double, double[]> eigenMap = new TreeMap<Double, double[]>(
                Collections.reverseOrder());// key=特征值,value=对应的特征向量;初始化为翻转排序,使map按key值降序排列
        double total = 0;// 存储特征值总和
        int index = 0, n = eigenvalue.length;
        double[] eigenvalueArray = new double[n];// 把特征值矩阵对角线上的元素放到数组eigenvalueArray里
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j)
                    eigenvalueArray[index] = eigenvalue[i][j];
            }
            index++;
        }

        for (int i = 0; i < tEigenVectors.length; i++) {
            double[] value = new double[tEigenVectors[0].length];
            value = tEigenVectors[i];
            eigenMap.put(eigenvalueArray[i], value);
        }

        // 求特征总和
        for (int i = 0; i < n; i++) {
            total += eigenvalueArray[i];
        }
        // 选出前几个主成分
        double temp = 0;
        int principalComponentNum = 0;// 主成分数
        List<Double> plist = new ArrayList<Double>();// 主成分特征值
        for (double key : eigenMap.keySet()) {
            if (temp / total <= threshold) {
                temp += key;
                plist.add(key);
                principalComponentNum++;
            }
        }
        System.out.println("\n" + "当前阈值: " + threshold);
        System.out.println("取得的主成分数: " + principalComponentNum + "\n");

        // 往主成分map里输入数据
        for (int i = 0; i < plist.size(); i++) {
            if (eigenMap.containsKey(plist.get(i))) {
                principalMap.put(i, eigenMap.get(plist.get(i)));
            }
        }

        // 把map里的值存到二维数组里
        double[][] principalArray = new double[principalMap.size()][];
        Iterator<Entry<Integer, double[]>> it = principalMap.entrySet()
                .iterator();
        for (int i = 0; it.hasNext(); i++) {
            principalArray[i] = it.next().getValue();
        }

        Matrix principalMatrix = new Matrix(principalArray);

        return principalMatrix;
    }

    /**
     * 矩阵相乘
     * 
     * @param primary
     *            原始二维数组
     * 
     * @param matrix
     *            主成分矩阵
     * 
     * @return result 结果矩阵
     */
    public Matrix getResult(double[][] primary, Matrix matrix) {
        Matrix primaryMatrix = new Matrix(primary);
        Matrix result = primaryMatrix.times(matrix.transpose());
        return result;
    }
}
 

//==================MainClass========================

import Jama.Matrix;

public class PCAMain {
    public static void main(String[] args) {
        PCA pca = new PCA();
        double[][] primaryArray = { { 100, 2, 3, 4, 1, 2, 32, 2 }, { 1, 2, 31, 52, 1, 2, 32, 2 },
                { 1, 2, 32, 2, 1, 2, 31, 52 }, { 1, 2, 32, 2, 1, 2, 30, 52 } };
        System.out.println("--------------------------------------------");
        System.out.println("原始数据: ");
        System.out.println(primaryArray.length + "行," + primaryArray[0].length + "列");
        for (int i = 0; i < primaryArray.length; i++) {
            for (int j = 0; j < primaryArray[0].length; j++) {
                System.out.print(+primaryArray[i][j] + " \t");
            }
            System.out.println();
        }

        // 均值中心化后的矩阵
        double[][] averageArray = pca.changeAverageToZero(primaryArray);
        System.out.println("--------------------------------------------");
        System.out.println("均值0化后的数据: ");
        System.out.println(averageArray.length + "行," + averageArray[0].length + "列");
        for (int i = 0; i < averageArray.length; i++) {
            for (int j = 0; j < averageArray[0].length; j++) {
                System.out.print((float) averageArray[i][j] + " \t");
            }
            System.out.println();
        }
        // 协方差矩阵
        double[][] varMatrix = pca.getVarianceMatrix(averageArray);
        System.out.println("---------------------------------------------");
        System.out.println("协方差矩阵: ");
        for (int i = 0; i < varMatrix.length; i++) {
            for (int j = 0; j < varMatrix[0].length; j++) {
                System.out.print((float) varMatrix[i][j] + "\t");
            }
            System.out.println();
        }
        // 特征值矩阵
        System.out.println("--------------------------------------------");
        System.out.println("特征值矩阵: ");
        double[][] eigenvalueMatrix = pca.getEigenvalueMatrix(varMatrix);

        // 特征向量矩阵
        System.out.println("--------------------------------------------");
        System.out.println("特征向量矩阵: ");
        double[][] eigenVectorMatrix = pca.getEigenVectorMatrix(varMatrix);

        // 主成分矩阵
        System.out.println("--------------------------------------------");
        Matrix principalMatrix = pca.getPrincipalComponent(primaryArray, eigenvalueMatrix, eigenVectorMatrix);
        System.out.println("主成分矩阵: ");
        principalMatrix.print(6, 2);

        // 降维后的矩阵
        System.out.println("--------------------------------------------");
        System.out.println("降维后的矩阵: ");
        Matrix resultMatrix = pca.getResult(primaryArray, principalMatrix);
        resultMatrix.print(10, 2);

    }
}
 

 

直接可运行

© 著作权归作者所有

上一篇: 特征工程
Harry_sir
粉丝 16
博文 80
码字总数 48004
作品 0
朝阳
其他
私信 提问
加载中

评论(0)

论文[基于WiFi信号的人体行为感知技术研究综述]阅读-知识补充

非视距 非视距最直接的解释是,通信的两点视线受阻,彼此看不到对方,菲涅尔区大于50%的范围被阻挡 。 在有障碍物的情况下,无线信号只能通过反射,散射和衍射方式到达接收端,我们称之为非视...

散人lins
2018/04/13
0
0
JAVA字节码文件之第一篇(结构)

开发工具:IEDA、JDK1.8、WinHex 一、字节码文件结构 .Class 字节码中有两种数据类型: 字节数据直接量:这是基本的数据类型。共细分为 u1 、 uZ 、 u4 、 u8 四种,分别代表连续的 1 个字节...

osc_7g5sy6xk
01/05
2
0
大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明
2018/06/23
28
0
Java学习第二天之Java程序的基本规则

一、Java程序的组织形式   Java程序是一种纯粹的面向对象的程序设计语言,因此Java程序必须以类(即class)的形式存在,类(class)是Java程序的最小程序单位。Java程序不允许可执行性语句...

osc_j6se59id
2019/10/29
6
0
Java文件的命名,Java主类,Java中的public类

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/darlingwood2013/article/details/96105142 编译和运行 Java 程序 He...

叶晚林
2019/07/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

QT 执行shell命令

(1)首先包含头文件: #include <QProcess> (2)执行shell命令: QProcess::execute("ls");

悲催的古灵武士
24分钟前
22
0
osgEarth使用笔记3——加载倾斜摄影数据

目录 1. 概述 2. 详论 2.1. 位置 2.2. 着色 2.3. 其他 3. 结果 4. 参考 1. 概述 我在《OSG加载倾斜摄影数据》这篇博文中论述了如何通过OSG生成一个整体的索引文件,通过这个索引文件来正确显...

osc_7oc4d1en
25分钟前
19
0
cesium加载gltf模型点击以及列表点击定位弹窗

前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材。 之前有部分订阅者咨询我,...

osc_cx8uhydz
26分钟前
14
0
思维导图软件如何插入图片?具体步骤?

学习思维导图制作的过程中,会遇到很多没有学过的知识,需要我们不断地去改进和学习,这样增强自己的学习能力,才能更好地掌握制图软件。以后帮助我们快速方便地完成制图,今天我们就要来看看...

深蓝月上
26分钟前
25
0
Notepad++ 列块模式编辑,替换换行符

一、列块模式编辑: 1、数据准备 2、按住 “Alt + 鼠标左键” 选择需要列块模式编辑的区域,可以看到多了一条竖线 3、之后批量可以添加,修改内容 二、替换换行符 上面说了列块模式的编辑,后...

osc_itgved4p
27分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部