主成分回归分析实战教程

article/2025/5/11 6:56:21

本文介绍主成分回归分析(Principal Components Regression),并通过示例展示其实现过程。

给定p个预测变量和响应变量,多元线性回归使用如最小二乘法获得最小误差平方和(RSS):

RSS = Σ ( y i – y ^ i ) 2 {Σ(y_i – ŷ_i)^2} Σ(yiy^i)2

-Σ: 求和符号
- y i {y_i} yi: 第i个观测的实际响应值
- y ^ i {ŷ_i} y^i: 基于多重线性回归模型获得预测值

然而,当预测变量高度相关时,会产生多重共线问题,导致模型系数估计不可靠、高方差。避免该问题的一个方法是使用主成分回归分析 ———— 从p个预测变量中发现M个线性组合(主成分),然后把主成分作为预测变量使用最小二乘法拟合线性回归模型。下面通过示例带你实现主成分回归分析。

加载必要工具包

最简单方式执行主成分回归分析是使用pls包:

# 安装包
install.packages("pls")# 加载包
library(pls)

拟合模型

为了简单方便,我们使用内置的mtcars数据集,包括不同品牌汽车的数据:

head(mtcars)#                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
# Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
# Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
# Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

本例主成分回归分析使用hp作为响应变量,下面变量作为预测变量:

  • mpg (Miles/(US) gallon)
  • disp (Displacement)
  • drat (Rear axle ratio)
  • wt (Weight)
  • qsec (1/4 mile time)

下面代码利用上述数据拟合模型,其中两个参数解释如下:

  • scale = TRUE 每个预测变量都被标准为均值为0,标准差为1,这避免了模型中预测变量使用不同度量单位而产生的影响。

  • validation = “CV”: 使用K折交叉验证评估模型表现,默认K为10。也可以使用LOOCV参数。


# 是的示例可重现
set.seed(1)#fit PCR model
model <- pcr(hp~mpg+disp+drat+wt+qsec, data=mtcars, scale=TRUE, validation="CV")

选择主成分数

我们依据获得模型,现在需要决定保留主成分数量。下面代码是通过k次交叉验证计算的检验均方根误差(RMSE):

summary(model)# Data: 	X dimension: 25 5 
# 	Y dimension: 25 1
# Fit method: svdpc
# Number of components considered: 5
# 
# VALIDATION: RMSEP
# Cross-validated using 10 random segments.
#        (Intercept)  1 comps  2 comps  3 comps  4 comps  5 comps
# CV           59.98    26.51    26.53    25.91    27.35    30.49
# adjCV        59.98    26.44    26.25    25.59    26.91    29.82
# 
# TRAINING: % variance explained
#     1 comps  2 comps  3 comps  4 comps  5 comps
# X     73.45    89.53    95.68    99.04   100.00
# hp    81.11    85.56    87.53    87.65    88.25

我们解释输出中的两个表格:

  1. VALIDATION: RMSEP

这个表告诉我们k折交叉检验的检验RMSE,解雇哦如下:

  • 模型中仅用截距项, 检验RMSE为 69.66.
  • 如果增加第一主成分,检验RMSE减少到 44.56.
  • 如果增加第二主成分,检验RMSE减少到 35.64.

我们看到继续增加主成分会导致RMSE增加,似乎表示仅使用两个主成分为最优模型。

  1. TRAINING: % variance explained

这个表结果表示响应变量中能主成分被解释方差的百分比:

  • 通过只使用第一个主成分,响应变量中被解释方差为69.83%。
  • 通过加入第二个主成分,响应变量中被解释方差为89.35%。

通过使用更多的主成分总是可以解释更多的方差,但我们看到添加两个以上的主成分被解释方差比例实际上增加不明显。使用validationplot()函数能够以可视化方式展示RMSE,从而更直观决定选择主成分数量。

# 2,3 两个图在第一行,1图在第二行占两列(共2行2列)
layout(matrix(c(2,3,1,1),2,2, byrow = TRUE))validationplot(model, val.type="R2")
validationplot(model, val.type="MSEP")
validationplot(model)

在这里插入图片描述

在上图中我们可以看到,添加两个主成分时模型的拟合度在提高,但当更多主成分加入时却更差。因此最优模型只包括前两个主成分。

使用最终模型进行预测

我们使用两个主成分模型测试新的观测数据。下面代码把原始数据分为训练集和测试集,使用PCR模型在测试集上预测:

# 定义训练集和测试集
train <- mtcars[1:25, c("hp", "mpg", "disp", "drat", "wt", "qsec")]
y_test <- mtcars[26:nrow(mtcars), c("hp")]
test <- mtcars[26:nrow(mtcars), c("mpg", "disp", "drat", "wt", "qsec")]# 在测试集上进行检验
model <- pcr(hp~mpg+disp+drat+wt+qsec, data=train, scale=TRUE, validation="CV")
pcr_pred <- predict(model, test, ncomp=2)# 计算RMSE
sqrt(mean((pcr_pred - y_test)^2))# [1] 56.86549

我们看到测试RMSE为56.86549,这是测试集中变量hp的预测值与观察值之间的平均偏差。


http://chatgpt.dhexx.cn/article/Q6sWloAD.shtml

相关文章

机器学习——数据的共线性问题(岭回归、LASSO回归、逐步回归、主成分回归)

一、如何检验共线性 容忍度&#xff08;Trlerance&#xff09;&#xff1a;容忍度是每个自变量作为因变量对其他自变量进行回归建模时得到的残差比例&#xff0c;大小用1减得到的决定系数来表示。容忍度的值介于0和1之间&#xff0c;如果值越小&#xff0c;说明这个自变量与其…

TI的CC2530单片机检测不同类型的方波

之前仅检测过一个引脚上一种方波信号&#xff0c;现在要再引脚上区分三种不同的波形。着实头大了好一会儿。 要检测的三种波形如下图所示&#xff1a; 每种波形的持续长度为500us,时间间隔为10ms. 比如我们在P0_2上检测这个波形&#xff0c;首先要对P0_2进行初始化操作&#…

单片机|CC2530实验入门

本教程为实验入门&#xff0c;手把手教你编译一个工程 一、USB驱动 仿真器设备的连接 【说明】USB接口不够可以使用USB集线器扩展&#xff0c;且互相不会干扰&#xff0c;非常方便。 由于用到了CC仿真器&#xff08;smart RF04EB&#xff09;&#xff0c;需要相关驱动。连接…

CC2530单片机延时函数实际测试

因为要检测不同的波形&#xff0c;所以对时间要求很高&#xff0c;但是发现Zstack本身提供的微秒级的延时其实有误差。 因此特地写了测试函数&#xff0c;然后用示波器观察了时间。详细如下&#xff1a; 先说CC2530与普通8051单片机时钟的不同&#xff0c;CC2530的每个指令是一…

ZigBee无线传感——CC2530单片机定时器1PWM输出

定时器1&#xff08;16位&#xff09; 时器1是一个独立的16位定时器&#xff0c;支持典型的定时/计数功能&#xff0c;比如输入捕获&#xff0c;输出比较和PWM功能。 定时器有五个独立的捕获/比较通道。每个通道定时器使用一个I/O引脚。定时器用于范围广泛的控制和测量应用&am…

基于ZigBee cc2530单片机多传感器的智能阳台仿真设计与实现

文章目录 摘 要&#xff1a;关键词&#xff1a;ZigBee 、语音识别、智能家居、传感器 0.引言1.概述2&#xff0e;系统总体设计2.1系统组成2、系统使用流程3、开发环境 2.2系统传感器构成2.3系统数据库设计 3&#xff0e;系统详细设计与实现4&#xff0e;系统测试结果5&#xff…

CC2530单片机精确延时的时间分析

CC2530单片机精确延时的时间分析 IAR 仿真时如何得知运行周期for循环的时间计算使用反汇编工具计算延时时间验证讨论CC2530与普通8051单片机时钟的不同 IAR 仿真时如何得知运行周期 关于这个问题&#xff0c;网上有很多好文章&#xff0c;讲得很清楚。IAR的操作很简单&#xf…

嵌入式cc2530单片机ZigBee-流水灯的实验

嵌入式cc2530单片机ZigBee 单片机是一种集成电路芯片&#xff0c;包含中央处理器CPU、随机存储器RAM、只读存储器ROM、输入输出I/O接口、中断控制系统、定时/计数器和通信等多种功能部件 其针脚定义如下&#xff1a; 1.0 --P0、P1各8个针脚&#xff08;1字节8位&#xff0c;…

快速学会CC2530单片机基础点灯

使用的软件是IAR 使用的板是经常提到的小黑板 上面四个灯分别是 D3 ---> P1_0 D4 ---> P1_1 D5 ---> P1_3 D6 ---> P1_4 #include <ioCC2530.h>//引用CC2530头文件 #define D3 P1_0 #define D4 P1_1 #define D5 P1_3 #define D6 P1_4//为了方便使用&…

CC2530单片机开发--串口

题目 源码下载链接https://download.csdn.net/download/czx20020728/85975522?spm1001.2014.3001.5503

【CC2530入门教程-06】CC2530的ADC工作原理与应用

【CC2530入门教程-06】CC2530的ADC工作原理与应用 【CC2530入门教程-05】CC2530的串行接口原理与应用 【CC2530入门教程-04】CC2530的定时/计数器原理与应用 【CC2530入门教程-03】CC2530的中断系统及外部中断应用 【CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制…

【CC2530入门教程-01】CC2530微控制器开发入门基础

【CC2530入门教程-06】CC2530的ADC工作原理与应用 【CC2530入门教程-05】CC2530的串行接口原理与应用 【CC2530入门教程-04】CC2530的定时/计数器原理与应用 【CC2530入门教程-03】CC2530的中断系统及外部中断应用 【CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制…

CC2530概述(简单了解)

CC2530概述简单版 CC2530是由TI公司生产&#xff08;德州仪器&#xff09;用于 2.4Ghz IEEE 802.15.4、ZigBee 和RF4CE 的片上系统&#xff08;SOC&#xff09;&#xff0c;经济实惠功耗低。 CC2530F256 结合了ZigBee 协议栈&#xff08;Z-Stack&#xff09;。 什么是片上系统…

单片机CC2530学习笔记

文章目录&#xff1a; 一&#xff1a;与或操作 二&#xff1a;CC2530的通用 IO及相关寄存器 1.与通用I/O端口相关常用的4个寄存器 2.PxSEL寄存器与PxDIR寄存器 3.P0INP寄存器与P1INP寄存器与P2INP 三&#xff1a;按键的工作原理与程序设计思路 四&#xff1a;CC2530的中…

c语言长空格的代码是什么,c语言中表示空格的是什么代码?

分析如下&#xff1a; 不是所有字符都需要转义的&#xff0c;空格直接就敲空格&#xff0c;或者使用ASCII码值赋值为32。 空格没有转义字符。合法转义字符如下&#xff1a; \a 响铃(BEL) 、\b 退格(BS)、\f 换页(FF)、\n 换行(LF)、\r 回车(CR)、\t 水平制表(HT)、\v 垂直制表(…

读入带空格的字符串 C语言

如何输出带空格的字符串 C语言默认是遇到空格&#xff0c;即代表输入的字符串的结束处 那么该如何读入带空格的字符串呢&#xff1f; scanf("%[^\n]", buf); //回车结束 这样的话就可以读入空格啦 表达式的意思为遇到’\n’才读取结束 请看演示代码 #include <…

C语言去除一段字符串中的空格

函数说明 将字符串中的所有空格都去掉。该函数简单但实用性强&#xff0c;可以作为字符串过滤器使用&#xff0c;随便改一下就可以实现去掉任意字符的功能&#xff0c;建议程序员的代码库里可以收藏一段该类型代码&#xff0c;用取方便。 函数实现 #include <stdio.h>…

C语言删除字符串中的空格

实现思路&#xff1a;分别定义2个指针&#xff0c;一个快指针s1, 一个慢指针s2,s1负责快速移动&#xff0c;遍历我们的的字符串&#xff0c;遇到空格就跳过&#xff0c;不是空格&#xff0c;就赋值给我们的s2,我们s2再往后移动&#xff0c;这样就把空格挤掉了。 最后别忘记s2 …

c语言空格符 r t,c语言中、\t \r \n 和空格什么意思

具体意思&#xff1a; 都是转义字符&#xff0c;空格就是单纯的空格&#xff0c;输入时可以输入空格 \t 跳格 \r 回车 \n 换行 \\ 反斜杠 \a 警告 \b 退格 \f 换页 \v 垂直跳格 \ddd ddd 是 1、2 或 3 位八进制数字。 转义字符串(E…

c++之静态数据成员与静态成员函数

什么是静态数据成员&#xff1f; 数据成员我们之前学过&#xff0c;是对象的属性。 同一个类&#xff0c;不同的对象&#xff0c;可能拥有不同的属性 例如一个车行&#xff0c;不同的车有不同的颜色&#xff0c;不同的耗油量。。。等等属性 但是当我们统计一个公有的数据&am…