第二次作业:主成分分析:步骤、应用及代码实现。代码可以用任何你熟悉的编程语言。
主成分分析:
一、基本概念和相关理解:
1.基本概念
在用统计方法研究多变量的课题时,变量个数太多就会增加课题的复杂性。所以我们为了使变量个数少且获得的信息量大,要采用主成分分析。
在很多情况下,变量之间是有一定的相关关系的,当两个变量之间有一定相关关系时,可以解释为这两个变量反应此课题的信息有一定的重叠。
主成分分析对于原先提出的所有变量,将重复的变量删去多余,建立尽可能少的新变量,且这些新变量两两不相关的,同时这些新变量在反映课题的信息方面尽可能保持原有的信息。
而主成分分析,便是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量就被称之为主成分。
2.具体理解
以实际应用为例,比如我们在描述物体的性质时,当我们观察的物体只需要用少数几个性质来区分的时候,例如只有他的温度,体积,质量,表面积时,那么我们可以很容易的根据这几个性质来区分,来对物体进行分析。但如果,我们所需要观察的性质增加时,如果不对这些性质进行归类化进行分析,则会大大增加复杂度。所以在这种情况下,我们便需要将复杂的数据降维,使得降维之后的变量减少,并尽量保证互不相关。
从线性代数的角度来看,PCA的目标就是使用另一组基去重新描述得到的数据空间。
二、主成分分析的步骤:
1.数据矩阵化:
首先,我们假设我们要分析的样本有n个特质,而同时该样本共有k个,则我们可以不妨可以用如下的一个矩阵来进行表示,有多少行就有多少个样本,有多少列就有多少个特质:

而由于,我们分析的对象是其特质,故可以将矩阵简化,即将每一列均用一个列向量来表示,这样我们就可以具体的来分析其成分了。
2.对每个特征求均值,并进行去均值处理,即用原来的数据减去均值,得出来的新数据们得出一个新的矩阵:

3.计算得出来的新矩阵的协方差矩阵,并由其协方差矩阵计算其特征值和特征向量。(如下图所示:)4.对特征值进行排序:即根据特征值的大小进行降序排序,此时我们便可以选取主成分分析之后样本的维数了。即若我们原本是一个有十个特征的样本,在进行了特征值排序之后,我们就可以根据特征值的大小和特征值所对应的特征来进行选取2或3(举个栗子),从而实现降维操作:
如图所述:若我们想利用PCA将其将为一个维度为b的样本进行分析,那么我们便可以对特征向量矩阵先取其前b行,再令其与原始数据矩阵Z相乘,便得到了一个新的矩阵Y,也就得出了降维之后的数据。
5.步骤总结:从线性代数的角度来理解PCA就是利用线性变换,使得利用另一组基来重新描述数据空间。通过降维的操作,提取出新的互不相关的主成分,来使数据的分析更为简洁。

而PCA从图形角度来思考(如上图所示),如果我们把所有的样点全部绘制在坐标轴内,坐标轴代表物体的一个特质,而图内的每一个点在坐标轴上的投影就代表了其在该特性上的程度大小。(本图以三位坐标系为例,实际操作中会有更多的维度,所以甚至并不能画出,但是思想是这个意思)
我们进行PCA操作的时候,其实就是一个对数据坐标轴进行旋转的操作,将新生成的坐标轴(们)旋转到数据角度上那些最重要的方向,进而通过特征值分析,确定出需要保留的主成分个数,舍弃其他主成分,实现数据的降维。
三、主成分分析的应用:
就我的理解而言,主成分分析可以应用于大多数的数据分析当中,尤其是当数据量极为庞大的时候,我们可以利用主成分分析的方法来对数据进行降维,从而降低数据分析的工作量,节约进行数据分析的时间。对于本专业领域而言,在图像处理,视频处理等方面均有所应用。
四、主成分分析的C++实现:(代码略长,因为在前面附上了好多网上找的用来算特征值和特征向量的函数,从加粗的int main开始起是我写的主函数。
目测matlab确实要好整的多,用C++应该也可以是有一个Eigen的数据库应该可以简便运算,不过最后还是硬算得,所以就很长。。)
#include
#include <math.h>
#include
#include
#include
using namespace std;
#define N 10
int n=10,flag;

void power();
void matrixFact();
void Findmax();
void newZ();
void printResult();
double m,next_m,eclipse,sum,A[N][N],z[N],y[N],next_z[N];
void reckonResidue()
{
float sum=0;
for (int i=1;i<=n;i++)
{
sum+=abs(z[i]-next_z[i]);
}
if (sum<0.001)
{
flag=1;
}
return ;
}

void readData()
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
cin>>A[i][j];
}
}
return ;
}

void power()
{
m=next_m;
flag=0;
eclipse=1e-5;
for (int i=1;i<=n;i++)
{
z[i]=1;
next_z[i]=1;
}
do
{
sum=0;
for (int i=1;i<=n;i++)
z[i]=next_z[i];
matrixFact();
Findmax();
newZ();
reckonResidue();
}while (!flag);
printResult();
return ;
}

void matrixFact()
{
for (int i=1;i<=n;i++)
{
sum=0;
for (int j=1;j<=n;j++)
{
sum+=A[i][j]*z[j];
}
y[i]=sum;
}
for (int i=1;i<=n;i++)
{
cout<<y[i]<<" ";
}
cout<<endl;
return ;
}

void Findmax()
{
m=0;
for (int i=1;i<=n;i++)
{
if (abs(m)<abs(y[i]))
{
m=y[i];
}
}
cout<<“m:”<<m<<endl;
return ;
}

void newZ()
{
for (int i=1;i<=n;i++)
{
next_z[i]=y[i]/m;
}
return ;
}

void printResult()
{
cout<<“矩阵A的最大特征值为:”<<m<<endl;
cout<<“其对应的特征向量为:(”;
for (int i=1;i<=n;i++)
{
cout<<next_z[i];
if (i!=n)
{
cout<<",";
}
}
cout<<")"<<endl;
return ;
}

void matrixx(double A[N][N],double x[N],double v[N])
{
for(int i=0;i<N;i++)
{
v[i]=0;
for(int j=0;j<N;j++)
v[i]+=A[i][j]*x[j];
}

}

double slove(double v[N])
{
double max;
for(int i=0;i<N-1;i++) max=v[i]>v[i+1]?v[i]:v[i+1];
return max;
}

int main()
{
int item = 5;//假设一共要检测5个样品
int catagory = 10;//这五个样品都有十个参数
double a[5][10]={{1,2,3,4,5,6,7,8,9,10},
{1,3,5,7,9,11,13,15,17,19},
{2,3,5,7,11,13,19,17,23,29},
{31,37,41,43,47,53,59,61,67,71},
{49,39,2,45,45,6,67,45,66,89}};//这是列出来的矩阵(按这样列出来方便看列向量)

double average[10];//设置一个数组,代表每一种参数的五种样品平均值
for(int i=0;i<10;i++)
{
average[i]=(a[0][i]+a[1][i]+a[2][i]+a[3][i]+a[4][i])/5;//计算平均值
cout<<average[i]<<" "<<endl;//输出平均值数组(便与调试需要)
}

for(int i=0;i<10;i++)
{
for(int j=0;j<5;j++)
{
a[j][i]=a[j][i]-average[i];//将原来的数组减去平均值数组,从而便于计算协方差矩阵
}
}

for ( int i = 0; i < 5; i++ )
{
for ( int j = 0; j < 10; j++ )
{
cout <<a[i][j]<<" ";
}
cout<<endl;
}//用于调试

double conv[10][10]={{1,2,3,4,5,6,7,8,9,10},
{1,3,5,7,9,11,13,15,17,19},
{2,3,5,7,11,13,19,17,23,29},
{31,37,41,43,47,53,59,61,67,71},
{1,2,3,4,5,6,7,8,9,10},
{1,3,5,7,9,11,13,15,17,19},
{2,3,5,7,11,13,19,17,23,29},
{31,37,41,43,47,53,59,61,67,71},
{31,37,41,43,47,53,59,61,67,71},
{42,33,32,45,45,56,67,45,66,89}};//设置一个10*10的矩阵作为协方差矩阵(初始化的值是随便写的)
for (int i=0;i<10;i++) //协方差矩阵计算
{
for (int j=0;j<10;j++)
{
for (int k=0;k<5;k++)
{
conv[i][j] += a[k][i]*a[k][j];
}
}
}

for ( int i = 0; i < 10; i++ )
{
for ( int j = 0; j < 10; j++ )
{
cout <<conv[i][j]<<" ";
}
cout<<endl;
}//用于调试

for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
A[i][j]=conv[i][j];
}
}
power();//此处调用了上面的部分函数,函数来源CSDN,用于求解矩阵特征值和特征向量
double p[10]={0,0,0,0,0,0,0,0,0,0};//若我们在实际应用中,主成分分析将原来的十个特征化为一个特征,则我们使其用特征向量p来表示(此处直接取了特征向量矩阵的第一行)
for (int i=1;i<=n;i++)
{
p[i]=next_z[i];
}
double Y[5]={1,1,1,1,1};//这就是最终得出来的那个矩阵
for(int i=0;i<5;i++)
{
for(int j=0;j<10;j++)
{
Y[i]+=p[i]*a[i][j];
}
}//计算Y的每一个值,即求出降维之后的数据
cout<<“降维之后的数据:”<<endl;
cout<<"(";
for(int i=0;i<4;i++)
{
cout<<Y[i]<<",";
}
cout<<Y[4]<<")";
return 0;
}
程序运行结果:

假期作业二:主成分分析:步骤、应用及代码实现。代码可以用任何你熟悉的编程语言。相关推荐

  1. 嵌入式Linux作业二分析u-boot-1.1.6在smdk2410开发板上的启动代码

    嵌入式Linux实验 嵌入式Linux作业二 文章目录 嵌入式Linux实验 作业要求 一.作业分析 二.实验步骤 1.下载并解压uboot1.1.6源码 2. 分析该版本下开发板smdk2410的相 ...

  2. 数学建模笔记(十五):多元统计分析及R语言建模(判别分析、聚类分析、主成分分析、因子分析,含数据代码注释,均可供运行)

    文章目录 一.多元数据的数学表达 1.多元分析资料的一般格式与矩阵化表示 2.数据特征(一元数据与多元数据的均值和方差) 二.R软件基本使用 1.向量创建(c函数) 2.行列合并(rbind,cbin ...

  3. 推荐系统入门(二):协同过滤(附代码)

    推荐系统入门(二):协同过滤(附代码) 目录 推荐系统入门(二):协同过滤(附代码) 引言 1. 相似性度量方法 1.1 杰卡德(Jaccard)相似系数 1.2 余弦相似度 1.3 皮尔逊相关系数 ...

  4. 计算机在线作业office,16春地大《计算机级等级考试Office》在线作业二.doc

    16春地大<计算机级等级考试Office>在线作业二 谋学网 HYPERLINK "" 地大<计算机一级等级考试Offi>在线作业二 一.单选题(共 17 ...

  5. day1 作业二:多级菜单操作

    作业二:多级菜单 (1)三级菜单 (2)可以次选择进入各子菜单 (3)所需新知识点:列表.字典 要求:输入b返回上一层,输入q退出整个程序 思路:三级菜单第一级别是省,第二级别是市,第三级别是县,用户 ...

  6. 下列哪些是java语言的条件执行语句_13春福师《JAVA程序设计》在线作业二

    13春福师<JAVA程序设计>在线作业二 试卷总分:100 测试时间:-- 单选题 多选题 判断题 一.单选题(共 30 道试题,共 60 分.) 1. 设有定义 int i = 6 ;, ...

  7. 18春《c语言》在线作业3,18春福师《C++语言程序设计》在线作业二【参考答案】...

    福师<C  语言程序设计>在线作业二-0005 试卷总分:100    得分:0 一. 单选题 (共 20 道试题,共 40 分) 1.如果类A被说明成类B的友元,则(). A.类A的成员 ...

  8. 计算机语言有许多种其中与硬件直接相关的是,16春季福师《计算机原理与接口技术》在线作业二...

    福师<计算机原理与接口技术>在线作业二 一.单选题(共 30 道试题,共 60 分.) 1. M数据传送控制的周期挪用方式主要适用的情况是( ) . I/O设备周期大于内存存储周期 . I ...

  9. day1作业二:多级菜单操作

    作业二:多级菜单 (1)三级菜单 (2)可以次选择进入各子菜单 (3)所需新知识点:列表.字典 要求:输入back返回上一层,输入quit退出整个程序 思路: (1)首先定义好三级菜单字典: (2)提 ...

最新文章

  1. js实现元素水平垂直居中
  2. python itertool_函数式编程的Python实践(2):Itertool
  3. 学院后勤报修系统php_如何有效提升医院医疗设备故障报修问题?
  4. python实现的json数据以HTTP GET,POST,PUT,DELETE方式页面请求
  5. Network | DNS
  6. Windows下安装MySQL5.7流程
  7. CentOS下安装Tomcat并配置JRE
  8. java实验类与对象_【实验课件】上机实践2  类与对象
  9. Go(4 [Map])
  10. 怎么样把c语言和单片机融合,求助怎么把两个单片机c语言程序结合在一起?大一期末实验...
  11. PHP程序员必须收藏的资源大全
  12. 从APP到API:金融科技C端到B端的思考
  13. Docker 开启镜像加速 (网易和阿里)
  14. 怎么看rx580是不是470刷的_【BIOS】网上都没有的教程 RX470 RX480 RX570 RX580显卡BIOS刷黑了怎么办?自救方法...
  15. JavaScript刷新当前页面的五种方式
  16. 连获国际大奖创下史上第一,这家耳机品牌凭什么与众不同?
  17. 家用路由器AP模式设置
  18. 2020年高教社杯全国大学生数学建模竞赛C题 第一问详细解答+代码
  19. 【ARM】仅用三个GPIO口实现串行SSI信号读取
  20. Summit Wireless科技有限公司推出首款支持无线多通道音频的低成本物联网模块

热门文章

  1. 从linux启动到rootfs的挂载分析 https://blog.csdn.net/kevin_hcy/article/details/17663341
  2. 开源真的在蚕食整个世界吗
  3. DCDC知识总结整理
  4. WebSocket+SockJs+STMOP
  5. eclipse官方网址、各个版本的下载
  6. flex于java实现增删改查
  7. IP地址(简单模拟)
  8. 天九共享:企业成功的重要元素是责任感
  9. 小米3解锁移动版(2013061)解账号锁刷机包
  10. 电视服务器绑上电池信号强吗,路由器上面绑电池,可以增加WiFi信号,真的有作用吗?...