java做主成分分析_主成分分析(PCA) Java

导入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 principalMap = new HashMap();// key=主成分特征值,value=该特征值对应的特征向量

TreeMap eigenMap = new TreeMap(

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 plist = new ArrayList();// 主成分特征值

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> 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);

}

}

直接可运行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/564267.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idl文件生成java_IDL和生成代码分析

IDL:接口描述语言这里使用thrift-0.8.0-xsb这个版本来介绍IDL的定义以及简单实例分析。1. namespace 定义包名2.struct 结构体&#xff0c;定义服务接口的参数和返回值用到的类结构。基本类型不需要使用struct.3.service 定义接口&#xff1a;demo.thrift1 namespace java com.…

java从控制台读取数据_Java不同版本从控制台读取数据方法及优缺点分析

从JDK 5.0版本开始&#xff0c;能从控制台中输入数据的方法每增加一个版本号&#xff0c;就有一种新增的方法&#xff0c;这也增加了选择的种类&#xff0c;可以依据不同的要求来进行选择。下面和绿茶小编一起来了解一下各个版本从控制台中读取数据的方法以及各自的优缺点。1、…

java类和对象程序_Java类与对象程序设计基础

Java类与对象程序设计基础一、实验目的&#xff1a;通过编制一个独立应用程序&#xff0c;使得学生掌握Java的系统所提供类的引用方法&#xff1b;通过编制一个完整的应用程序&#xff0c;使得学生对Java的应用程序的基本构成和基本算法熟练掌握&#xff0c;同时熟悉Java开发环…

MySQL 修改和删除索引

MySQL 中修改索引可以通过删除原索引&#xff0c;再根据需要创建一个同名的索引&#xff0c;从而实现修改索引的操作。 基本语法 当不再需要索引时&#xff0c;可以使用 DROP INDEX 语句或 ALTER TABLE 语句来对索引进行删除。 1 使用 DROP INDEX 语句 语法格式&#xff1a;…

java记事本保存_JAVA记事本关于保存

为什么运行这个程序后点击保存&#xff0c;然后打开时不是按行输出的啊?哪里有问题&#xff1f;publicclassJSBJSB{publicstaticvoidmain(String[]args){FirstWindowwinnewFirstWindow("记事本");}}classF...为什么运行这个程序后点击保存&#xff0c;然后打开时不是…

MySQL 创建用户

在对 MySQL 的日常管理和实际操作中&#xff0c;为了避免用户恶意冒名使用 root 账号控制数据库&#xff0c;通常需要创建一系列具备适当权限的账号&#xff0c;应该尽可能地不用或少用 root 账号登录系统&#xff0c;以此来确保数据的安全访问。 创建用户 可以使用 CREATE U…

acm用java怎么写_用java来写ACM

前言从去年10月份开始就一直都在九度oj平台写acm&#xff0c;到今天在九度oj的总排名已经到了第6名&#xff0c;收获很多特别是算法和数据结构方面的提高&#xff0c;这种提高直接反映在我找工作的顺利中但是人总要学会拥抱变化&#xff0c;特别是我即将加入阿里系&#xff0c;…

MySQL 修改用户

修改用户账号 可以使用 RENAME USER 语句修改一个或多个已经存在的 MySQL 用户账号。 语法格式&#xff1a; RENAME USER <旧用户> TO <新用户>语法说明如下&#xff1a; <旧用户>&#xff1a;系统中已经存在的 MySQL 用户账号。<新用户>&#xff1…

MySQL 删除用户

MySQL 数据库中可以使用 DROP USER 语句来删除一个或多个用户账号以及相关的权限。 语法格式&#xff1a; DROP USER <用户名1> [ , <用户名2> ]…使用 DROP USER 语句应该注意以下几点&#xff1a; DROP USER 语句可用于删除一个或多个 MySQL 账户&#xff0c;并…

python模块使用相对路径还是绝对路径、哪种更好_python学习的第十八天模块之包、相对搜索路径和绝对搜索路径...

一、包1、什么是包包是一种通过使用‘.模块名’来组织python模块名称空间的方式。具体就是一个包含有__init__.py文件的文件夹&#xff0c;所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来PS&#xff1a;(1)在pyhton3中没有__init__不会报错&#xff0c;但在pyth…

python的pygame库使用方法_[宜配屋]听图阁

使用python pygame库实现一个双人弹球小游戏&#xff0c;两人分别控制一个左右移动的挡板用来拦截小球&#xff0c;小球会在两板间不停弹跳&#xff0c;拦截失败的一方输掉游戏&#xff0c;规则类似于简化版的乒乓球。因为是第一次用pygame写python小游戏并且只用了两三个小时&…

MySQL 删除用户权限

MySQL 数据库中可以使用 REVOKE 语句删除一个用户的权限&#xff0c;此用户不会被删除。 语法格式有两种形式&#xff0c;如下所示&#xff1a; 1 第一种&#xff1a; REVOKE <权限类型> [ ( <列名> ) ] [ , <权限类型> [ ( <列名> ) ] ]… ON <对…

java jdbc 多数据源_Jdbctemplate多数据源配置方法详解

1.数据源配置spring:# jdbctemplate 连接多数据源配置db1:datasource:jdbcurl: jdbc:mysql://127.0.0.1:3306/cloud-main1?useUnicodetrue&characterEncodingutf8&useSSLfalse&allowMultiQueriestrueusername: rootpassword: 123456driver-class-name: com.mysql.…

java 语法 泛型_java-解密泛型语法

我正在阅读一个问题,下面给出了方法的签名public static List super E> doIt(List nums)我无法解码语法.我对仿制药很陌生,无法理解这部分.第一部分< E扩展了CharSequence>都告诉E应该是什么作为参数和返回类型.但我确实看到列表了吗&#xff1f;超级E&gt ;,这定义…

MySQL 数据库恢复

数据库恢复是指以备份为基础&#xff0c;与备份相对应的系统维护和管理操作。 系统进行恢复操作时&#xff0c;先执行一些系统安全性的检查&#xff0c;包括检查所要恢复的数据库是否存在、数据库是否变化及数据库文件是否兼容等&#xff0c;然后根据所采用的数据库备份类型采…

java位逻辑运算符_详述:Java逻辑运算符与位运算

Java中逻辑运算符总共有分为三种“ ”&#xff0c;“ll”&#xff0c;“!”运算符、此为逻辑运算符&#xff0c;只有当给定的两个条件都为真时&#xff0c;返回结果为true&#xff0c;否则都为false&#xff01;、此为逻辑非运算符&#xff0c;用来反转操作的true或者false&…

C++ 三种继承方式

C继承的一般语法为&#xff1a; class 派生类名:&#xff3b;继承方式&#xff3d; 基类名{派生类新增加的成员 };继承方式限定了基类成员在派生类中的访问权限&#xff0c;包括 public&#xff08;公有的&#xff09;、private&#xff08;私有的&#xff09;和 protected&am…

mapdb java_MapDB使用入门

背景MapDB官网&#xff1a;http://www.mapdb.org官方翻译之后的话&#xff1a;MapDB基于堆外存储、磁盘存储提供了Java的Maps、Sets、Lists、Queues等功能。它混合了Java集合框架和数据库引擎。它是基于Apache许可的免费的、开源的。个人觉得&#xff1a;MapDB是一个轻量级的本…

C++继承时名字的遮蔽

如果派生类中的成员&#xff08;包括成员变量和成员函数&#xff09;和基类中的成员重名&#xff0c;那么就会遮蔽从基类继承过来的成员。所谓遮蔽&#xff0c;就是在派生类中使用该成员&#xff08;包括在定义派生类时使用&#xff0c;也包括通过派生类对象访问该成员&#xf…

java项目 异常如何解决_Java项目中常见的异常处理

发生异常的情况有很多&#xff0c;其中包括以下几大类&#xff1a;1. 空指针异常&#xff1b;2. 用户输入异常&#xff1b;3. 多层异常捕获&#xff1b;想要知道Java是如何处理异常的&#xff0c;就需要掌握以下这三种异常的处理&#xff1a;1.检查性异常&#xff1a;最具代表的…