文章目录
PCA原理
pca主要是通过计算矩阵的特征向量,利用累计贡献率大于指定数量级时(本文里取95%)对应的特征值构成的矩阵,与原矩阵做矩阵乘法,达到降维的目的。
代码实现(python)
下面额我针对一组17*8的数据集进行的pca代码实现,数据集稍后会上传,可以自行下载。
#coding:UTF-8
import numpy as np
import csv
#加载数据
#从给定的csv文件加载数据
data = []
with open("data.csv","r") as csvfile:
csv_reader = csv.reader(csvfile) # 使用csv.reader读取csvfile中的文件
h = next(csv_reader) # 读取第一行每一列的标题
#print("this is:",h)
for row in csv_reader: # 将csv 文件中的数据保存到birth_data中
data.append(row[1:])
X = [[float(x) for x in row] for row in data] #将字符串转成float类型
X = np.array(X)
#print("this is x,",X)
w,h = X.shape
print("w*h=",w,"*",h)
std_2 = np.zeros((h))
#print("this is std_2",std_2)
#1.归一化
#添加自己代码实现
#测试tt=0
#测试for i in range(w*h):
#测试tt=tt+1
#测试print("this is tt",tt)
#测试print("this is max",X.max())
#测试print("this is min",X.min())
#测试print("this is average:",X[0].mean())
for i in range(w):
print("this is the true matrix:",i,X[i])
print("this is test1",X[1])
print("this is test2",X[2][1])
X_max=X.max()
X_min=X.min()
for i in range(w):
#print("this is i:",i)
for j in range(h):
X[i][j]=(X[i][j]-X_min)/(X_max-X_min)
print("归一化矩阵如下:",X)
#2.计算协方差
#用自己方法替换
Y=X.T
k=np.zeros((8,8))
m=np.zeros((8,8))
n=np.zeros((8,8))
p=np.zeros((8,8))
for i in range(8):
#print("这是i:",i)
for j in range(8):
# print("这是j:",j)
for z in range(8):
# print("这是z:",z)
k[i][j]=k[i][j]+(Y[z][i]-Y[i].mean())*(Y[z][j]-Y[j].mean())
for i in range(8):
for j in range(8):
for z in range(8):
m[i][j]=m[i][j]+(Y[z][i]-Y[i].mean())*(Y[z][i]-Y[i].mean())
for i in range(8):
for j in range(8):
for z in range(8):
n[i][j]=n[i][j]+(Y[z][j]-Y[j].mean())*(Y[z][j]-Y[j].mean())
for i in range(8):
for j in range(8):
p[i][j]=(m[i][j]*n[i][j])**(0.5)
#corr = np.corrcoef(X.T)
#q,w=corr.shape
corr=np.zeros((8,8))
for i in range(8):
for j in range(8):
corr[i][j]=k[i][j]/p[i][j]
a,b=corr.shape
#print("q,w=",q,w)
print("相关系数矩阵:",a,b)
print(corr)
#3.计算机特征值和特征根
eigenvalue,featurevector=np.linalg.eig(corr)
print("原始矩阵的特征值")
print("eigenvalue=",eigenvalue)
print("原始矩阵的特征向量")
print("featurevector=",featurevector)
#4.计算主成分贡献率
#添加自己代码实现
sum=0
for i in range(8):
sum=sum+eigenvalue[i]
contribute=np.zeros(8)
#for i in range(8):
# contribute[i]=eigenvalue[i]/sum
#print("这是主成分贡献率:",contribute)
contribute_a=np.zeros(8)
for i in range(8):
for k in range(i+1):
contribute_a[i]=eigenvalue[k]+contribute_a[i]
print("this is contribute_a",contribute_a)
contribute_b=np.zeros(8)
for i in range(8):
contribute_b[i]=contribute_a[i]/sum
print("this is contribute_b",contribute_b)
#5.确定主成分
#添加自己代码实现
len=0
for i in range(8):
if(contribute_b[i]>=0.95):
len=len+1
print("this is len",len)
contribute_X=np.zeros(len)
j=0
for i in range(8):
if(contribute_b[i]>=0.95):
contribute_X[j]=i
# print("this is a ring",contribute_X[j],contribute_b[i])
j=j+1
#print("this is contribute_X",contribute_X)
print("this is contribute_X",contribute_X)
c=0
key=np.zeros((7,8))
for i in range(7):
c=contribute_X[i]
c=int(c)
# print("c=",c)
for j in range(8):
key[i][j]=featurevector[c][j]
print(key)
a1=np.mat(key)
a2=np.mat(X.T)
A3=a1*a2
print(A3)
#6.可视化
#根据实际情况适当可视化