这是第二部分求最佳的预测系数B的代码
#encoding:utf-8
# 导入numpy包
import numpy as np
#定义一个PLS的类
class PLS(object):
def comput(self,pc,x,y):
#最初始 的X,Y
self.X = x
self.Y = y
# 获取数据X的样本数和纬度
m, n = self.X.shape
self.T = np.zeros((m, pc))#生成一个存放T的矩阵,后面用来存放数据
self.W = np.zeros((n, pc))#生成一个存放W的矩阵
self.P = np.zeros((n, pc))#生成一个存放P的矩阵
self.Q = np.zeros((self.Y.shape[1], pc))#生成一个存放Q的矩阵
self.U = np.zeros((m, pc))#生成一个存放U的矩阵
B = np.zeros((n, pc))#生成一个存放B的矩阵
for i in range(pc): # 控制循环次数,选取几个主成分,循环几次
# u=np.array(np.mat(self.Y[:, [0]]))
if i==0:
u=np.mat(self.Y[:, 0]).T# 将y的一列给u
else:
u=np.mat(self.Y[:, 0])
mz=True
while mz:
#进行六步骤的迭代,一般的PLS论文上写的很清楚,这就不重复了
w=np.dot(self.X.T,u)
w=np.true_divide(w,np.sqrt(np.dot(w.T,w)))
t=np.dot(self.X,w)
q=np.true_divide(np.dot(self.Y.T,t),np.dot(t.T,t))
unew=np.true_divide(np.dot(self.Y,q),np.sqrt(q.T*q))
diff =np.dot((u-unew).T,(u-unew))
if diff<2.2204*10**(-16):# 训练到一个合适的精度
mz=False
else:
u=unew
p=np.true_divide(np.dot(self.X.T,t),np.dot(t.T,t))
self.X=self.X-np.dot(t,p.T) # 将X, Y的残差作为 X, Y继续提取潜在变量
self.Y=self.Y-np.dot(t,q.T)
self.W[:, i] = w.T.ravel()# 将前面提取的成分存储到前面定义的矩阵当中
self.T[:, i] = t.T.ravel()
self.P[:, i] = p.T.ravel()
self.U[:, i] = unew.T.ravel()
self.Q[:, i] = q.T.ravel()
b1=self.W[:,0:i+1] # 后面的几部是求得B的值
b2=np.linalg.inv(np.dot(self.P[:,0:i+1].T,self.W[:,0:i+1]))
b3=self.Q[:,0:i+1].T
b = np.dot(np.dot(b1,b2),b3)
B[:, i] = b.ravel()
return B