偏最小二乘回归及python代码

原理

偏最小二乘回归的思想是将 Y = [ y1, y2, ... , yn ] ,X = [ x1, x2, ... , xn ]


进行线性表示 Y = XBpls + F

步骤

1. 将 X 和 Y 进行标准化

设 X 标准化后的矩阵为 E0, Y 标准化后的矩阵为 F0

2. 求解第一个成分

设 E0 和 F0 的第一成分为 t1u1。这一步的目的是使得 E0 和 F0 的第一成分之间的相关性达到最大,方便用 E0 的第一成分 t1 线性表示 F0



其中式子 5-9 是典型的特征值分解式,因此可求得权重向量 w1,c1

那么 E0 和 F0 的第一个成分 t1,u1 定义如下:


因此

3. 建立第一个成分与 E0 和 F0 之间的关系


根据最小二乘法原理求解系数得:


4. 计算残差矩阵

由式子 5-11 有:


如果残差矩阵 E1F1 没有满足阈值范围,则利用 E1F1 代替 E0F0 继续进行分解,重复步骤 2 - 4
因此有( E1F1E2F2 的关系):

继续对残差矩阵 E1F1 进行分解,进一步降低残差

一般地有


其中:

  1. E0 代表决策变量 X 标准化后的矩阵,F0 代表响应变量 F 标准化后的矩阵
  2. E1-i,F1-i 代表残差矩阵,参考式子 5-13 到 5-16

5. 重构 X,Y 和成分 t 的关系

以下的 X,Y 原始数据矩阵默认为标准化后的:
因此经过多次分解以后:

6. 重构 X 与 Y 之间的关系

以下的 X,Y 原始数据矩阵默认为标准化后的:
首先理解偏最小二乘的外部结构和内部结构:


联立以上各式有:

假设每个成分 t 与 X 的关系为:



即:


整理得到 X 与 Y 之间的关系



得证

理解 t 与 u 之间的关系

t 与 u 之间满足相关性最大,这样可以用 t 替代 u 来线性表示 Y

代码

import numpy as np

# 设决策变量 X = { x1, x2, x3 },响应变量 Y = { y1, y2, y3 }
x1=[191,189,193,162,189,182,211,167,176,154,169,166,154,247,193,202,176,157,156,138]
x2=[36,37,38,35,35,36,38,34,31,33,34,33,34,46,36,37,37,32,33,33]
x3=[50,52,58,62,46,56,56,60,74,56,50,52,64,50,46,62,54,52,54,68]
y1=[5,2,12,12,13,4,8,6,15,17,17,13,14,1,6,12,4,11,15,2]
y2=[162,110,101,105,155,101,101,125,200,251,120,210,215,50,70,210,60,230,225,110]
y3=[60,60,101,37,58,42,38,40,40,250,38,115,105,50,31,120,25,80,73,43]


data_raw=np.array([x1,x2,x3,y1,y2,y3])
data_raw=data_raw.T # 输入原始数据,行数为样本数,列数为特征数
# 数据标准化
num=np.size(data_raw,0) # 样本个数
mu=np.mean(data_raw,axis=0) # 按列求均值
sig=(np.std(data_raw,axis=0)) # 按列求标准差
data=(data_raw-mu)/sig # 标准化,按列减去均值除以标准差
# 提取自变量和因变量数据

n=3 # 自变量个数
m=3 # 因变量个数
x0=data_raw[:,0:n] # 原始的自变量数据
y0=data_raw[:,n:n+m] # 原始的变量数据
e0=data[:,0:n] # 标准化后的自变量数据
f0=data[:,n:n+m] # 标准化后的因变量数据

chg=np.eye(n) # w 到 w* 变换矩阵的初始化

w=np.empty((n,0)) # 初始化投影轴矩阵
w_star=np.empty((n, 0)) # w* 矩阵初始化
t=np.empty((num, 0)) # 得分矩阵初始化
ss=np.empty(0) # 或者ss=[],误差平方和初始化
press=[] # 预测误差平方和初始化
Q_h2=np.zeros(n) # 有效性判断条件值初始化
print(Q_h2)

for i in range(n):
    matrix=e0.T@f0@f0.T@e0 # 构造矩阵E'FF'E
    val,vec=np.linalg.eig(matrix) # 计算特征值和特征向量
    index=np.argsort(val)[::-1] # 获取特征值从大到小排序前的索引
    val_sort=val[index] # 特征值由大到小排序
    vec_sort=vec[:,index] # 特征向量按照特征值的顺序排列
    w=np.append(w,vec_sort[:,0][:,np.newaxis],axis=1) # 储存最大特征向量
    w_star=np.append(w_star,chg@w[:,i][:,np.newaxis],axis=1) # 计算 w* 的取值
    t=np.append(t,e0@w[:,i][:,np.newaxis],axis=1) # 计算投影
    alpha=e0.T@t[:,i][:,np.newaxis]/(t[:,i]@t[:,i]) # 计算自变量和主成分之间的回归系数
    chg=chg@(np.eye(n)-(w[:,i][:,np.newaxis]@alpha.T)) # 计算 w 到 w*的变换矩阵
    e1=e0-t[:,i][:,np.newaxis]@alpha.T # 计算残差矩阵
    e0=e1 # 更新残差矩阵


    beta=np.linalg.pinv(t)@f0 #求回归方程的系数,数据标准化,没有常数项
    res=np.array(f0-t@beta) #求残差
    ss=np.append(ss,np.sum(res**2))#残差平方和
    #-----求解残差平方和press
    press_i=[] #初始化误差平方和矩阵
    for j in range(num):
        t_inter=t[:,0:i+1]
        f_inter=f0
        t_inter_del=t_inter[j,:] #把舍去的第 j 个样本点保存起来,自变量
        f_inter_del=f_inter[j,:] #把舍去的第 j 个样本点保存起来,因变量
        t_inter= np.delete(t_inter,j,axis=0) #删除自变量第 j 个观测值
        f_inter= np.delete(f_inter,j,axis=0) #删除因变量第 j 个观测值
        t_inter=np.append(t_inter,np.ones((num-1,1)),axis=1)
        beta1=np.linalg.pinv(t_inter)@f_inter # 求回归分析的系数,这里带有常数项
        res=f_inter_del-t_inter_del[:,np.newaxis].T@beta1[0:len(beta1)-1,:]-beta1[len(beta1)-1,:] #计算残差
        res=np.array(res)
        press_i.append(np.sum(res**2)) #残差平方和,并存储
    press.append(np.sum(press_i)) #预测误差平方和

    Q_h2[0]=1
    if i>0:
        Q_h2[i]=1-press[i]/ss[i-1]
    if Q_h2[i]<0.0975:
        print('提出的成分个数 r=',i+1)
        break


beta_Y_t=np.linalg.pinv(t)@f0 #求Y*关于t的回归系数
beta_Y_X=w_star@beta_Y_t#求Y*关于X*的回归系数
mu_x=mu[0:n] #提取自变量的均值
mu_y=mu[n:n+m] #提取因变量的均值
sig_x=sig[0:n] #提取自变量的标准差
sig_y=sig[n:n+m] #提取因变量的标准差
ch0=mu_y-mu_x[:,np.newaxis].T/sig_x[:,np.newaxis].T@beta_Y_X*sig_y[:,np.newaxis].T#算原始数据回归方程的常数项
beta_target=np.empty((n,0)) #回归方程的系数矩阵初始化

for i in range(m):
    a=beta_Y_X[:,i][:,np.newaxis]/sig_x[:,np.newaxis]*sig_y[i]#计算原始数据回归方程的系数
    beta_target=np.append(beta_target,a,axis=1)
target=np.concatenate([ch0,beta_target],axis=0) #回归方程的系数,每一列是一个方程,每一列的第一个数是常数项

print(target)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容