降维 — PCA 真的能改善分类结果吗?

news2024/10/3 2:28:31

一、说明

        我遇到了一些关于降维技术的资源。这个主题绝对是最有趣的主题之一,很高兴认为有一些算法能够通过选择仍然代表整个数据集的最重要的特征来减少特征的数量。作者指出的优点之一是这些算法可以改善分类任务的结果。

        在这篇文章中,我将使用主成分分析(PCA)来验证这个陈述,以尝试提高神经网络在数据集上的分类性能。PCA 真的能改善分类结果吗?一起来看看吧。

二、关于降维算法

        在直接开始编写代码之前,让我们先谈谈降维算法。降维有两种主要算法:线性判别分析(LDA)和主成分分析(PCA)。这两者之间的基本区别在于,LDA使用类的信息来查找新特征,以最大化其可分离性,而PCA使用每个特征的方差来做同样的事情。在这种情况下,LDA可以被认为是一种监督算法,而PCA是一种无监督算法。

2.1 谈论PCA

        PCA 背后的想法只是找到一组汇总数据的低维轴。为什么我们需要汇总数据?让我们考虑一下这个例子:我们有一个由一组来自汽车的属性组成的数据集。这些属性通过尺寸、颜色、圆度、紧凑性、半径、座位数、门数、后备箱尺寸等来描述每辆车。但是,其中许多特征将测量相关属性,因此将是多余的。因此,我们应该消除这些冗余,并描述每辆车的属性较少。这正是PCA的目标。例如,将车轮数量视为汽车和公共汽车的一个特征,几乎两个类的每个示例都有四个轮子,因此我们可以说这个特征的方差很小(在一些罕见的公共汽车中从四个到六个轮子或更多),所以这个特征将使公共汽车和汽车看起来一样, 但它们实际上彼此非常不同。现在,将高度视为一个特征,汽车和公共汽车有不同的值,方差的范围很大,从最低的汽车到最高的公共汽车。显然,这些车辆的高度是将它们分开的良好属性。回想一下,PCA不考虑类的信息,它只查看每个特征的方差,因为合理地假设具有高方差的特征更有可能在类之间具有良好的划分。

        通常,人们最终会错误地认为PCA从数据集中选择某些特征并丢弃其他特征。该算法实际上基于旧属性的组合构建新的属性集。从数学上讲,PCA执行线性变换,将原始特征集移动到由主成分组成的新空间。这些新特征对我们来说没有任何真正的意义,只有代数,因此不要认为结合线性特征,你会发现你从未想过它会存在的新功能。许多人仍然相信机器学习算法是神奇的,他们直接将数千个输入输入到算法中,并希望为他们的业务找到所有见解和解决方案。不要被欺骗。数据科学家的工作是通过使用机器学习算法作为一组工具而不是魔杖,通过对数据进行良好的探索性分析来定位对业务的见解。请记住这一点。

2.2 主成分空间是什么样的?

        在新的功能空间中,我们正在寻找一些在类之间差异很大的属性。正如我在前面的例子中所展示的,一些呈现低方差的属性是没有用的,这将使示例看起来相同。另一方面,PCA 查找在类之间显示尽可能多的变化的属性,以构建主组件空间。该算法使用方差矩阵、协方差矩阵、特征向量和特征值对的概念来执行 PCA,从而提供一组特征向量及其各自的特征值。PCA的确切表现是下一篇文章的材料。

        那么,我们应该如何处理特征值和特征向量呢?这很简单,特征向量表示主成分空间的新轴集,特征值携带每个特征向量具有的方差量信息。因此,为了减小数据集的维度,我们将选择那些方差较大的特征向量,并丢弃方差较小的特征向量。当我们浏览下面的示例时,它将越来越清楚它是如何工作的。

2.3 让我们最后看到一些代码。

        现在,我们到达了这篇文章的有趣和有趣的部分。让我们看看 PCA 是否真的改善了分类任务的结果。

        为了证明这一点,我的策略是在数据集上应用神经网络并查看其初始结果。之后,我将在分类之前执行 PCA,并在新数据集上应用相同的神经网络,最后比较两个结果。

        该数据集源自UCI机器学习存储库,称为“Statlog(车辆轮廓)数据集”。此数据集存储了四辆车轮廓的一些度量,用于分类。它由946个示例和18个度量(属性)所有数值组成,您可以在此链接中查看更多详细信息:https://archive.ics.uci.edu/ml/datasets/Statlog+(车辆+轮廓)。神经网络将是一个具有四个隐藏节点和一个输出节点的多层感知器,所有节点都具有sigmoid函数作为激活函数,PCA函数将来自R包。

2.4 准备数据集

        首先,我将为二元分类准备数据集。

        我将仅从两个类中选择示例,以构成二元分类。这些示例将来自“bus”和“saab”类。类“saab”将被类 0 取代,类“总线”将被类 1 取代。下一步包括将数据集分为训练数据集和测试数据集,分别占总类示例的 60% 和 40%。

        在前面的数据集准备之后,让我们一次使用所有特征对神经网络进行建模,然后应用测试数据集。

# Load library
library( dplyr )

# Load dataset
data = read.csv( "../dataset/vehicle.csv", stringsAsFactor = FALSE )

# Transform dataset
dataset = data %>% 
            filter( class == "bus" | class == "saab" ) %>%
            transform( class = ifelse( class == "saab", 0, 1 ) )
dataset = as.data.frame( sapply( dataset, as.numeric ) )

# Spliting training and testing dataset
index = sample( 1:nrow( dataset ), nrow( dataset ) * 0.6, replace = FALSE ) 

trainset = dataset[ index, ]
test = dataset[ -index, ]
testset = test %>% select( -class )

# Building a neural network (NN)
library( neuralnet )
n = names( trainset )
f = as.formula( paste( "class ~", paste( n[!n %in% "class"], collapse = "+" ) ) )
nn = neuralnet( f, trainset, hidden = 4, linear.output = FALSE, threshold = 0.01 )

plot( nn, rep = "best" )
图1.神经网络多层感知器

# Testing the result output
nn.results = compute( nn, testset )

results = data.frame( actual = test$class, prediction = round( nn.results$net.result ) )

# Confusion matrix
library( caret )
t = table( results )
print( confusionMatrix( t ) )
## Confusion Matrix and Statistics
## 
##       prediction
## actual  0  1
##      0 79  0
##      1 79 16
##                                                 
##                Accuracy : 0.545977              
##                  95% CI : (0.4688867, 0.6214742)
##     No Information Rate : 0.908046              
##     P-Value [Acc > NIR] : 1                     
##                                                 
##                   Kappa : 0.1553398             
##  Mcnemar's Test P-Value : <0.0000000000000002   
##                                                 
##             Sensitivity : 0.5000000             
##             Specificity : 1.0000000             
##          Pos Pred Value : 1.0000000             
##          Neg Pred Value : 0.1684211             
##              Prevalence : 0.9080460             
##          Detection Rate : 0.4540230             
##    Detection Prevalence : 0.4540230             
##       Balanced Accuracy : 0.7500000             
##                                                 
##        'Positive' Class : 0                     
##

三、步加入 PCA 的结果

        看来我们得到了一些结果。首先,看一下混淆矩阵。基本上,混淆矩阵表示有多少示例被分类到类中。主对角线显示正确分类的示例,次要对角线显示错误分类。在第一个结果中,分类器表现出非常混乱,因为它正确地分类了几乎所有来自“saab”类的示例,但它也将“bus”类的大多数示例分类为“saab”类。强化这个结果,我们可以看到准确率值在50%左右,对于分类任务来说,这是一个非常糟糕的结果。分类器基本上有 50% 的概率将新示例分类为“汽车”类,50% 的概率分类为“公共汽车”类。类似地,神经网络为每个新示例抛硬币,以选择它应该将其分类为哪个类。

四、让我们看看PCA是否可以帮助我们

        现在,让我们对数据集执行主成分分析,并获取特征值和特征向量。实际上,您将看到 R 包中的 PCA 函数提供了一组已按降序排序的特征值,这意味着第一个分量是方差最高的分量,第二个分量是方差第二高的特征向量,依此类推。下面的代码显示了如何选择特征向量查看特征值。

# PCA
pca_trainset = trainset %>% select( -class )
pca_testset = testset
pca = prcomp( pca_trainset, scale = T )

# variance
pr_var = ( pca$sdev )^2 

# % of variance
prop_varex = pr_var / sum( pr_var )

# Plot
plot( prop_varex, xlab = "Principal Component", 
                  ylab = "Proportion of Variance Explained", type = "b" )
图拉 02.每个主成分的差异百分比

 # Scree Plot 
plot( cumsum( prop_varex ), xlab = "Principal Component", 
                            ylab = "Cumulative Proportion of Variance Explained", type = "b" ) 
图 03.方差的累积总和

        来自统计信息默认包的本机 R 函数“prcomp”执行 PCA,它返回所需的所有特征值和特征向量。第一个图显示每个特征的方差百分比。您可以看到第一个分量的方差最高,值约为 50%,而第 8 个分量约为方差的 0%。因此,它表明我们应该拿起前八个组件。第二个图显示了方差的另一个视角,尽管所有方差的累积总和,您可以看到前八个特征值对应于所有方差的大约 98%。事实上,这是一个相当不错的数字,这意味着只有2%的信息丢失。最大的好处是,我们正在从一个有十八个特征的空间转移到另一个只有八个特征的空间,只丢失2%的信息。这绝对是降维的力量。

        现在我们知道了将构成新空间的特征的数量,让我们创建新数据集,然后再次对神经网络进行建模,并检查我们是否获得了新的更好的结果。

# Creating a new dataset
train = data.frame( class = trainset$class, pca$x )
t = as.data.frame( predict( pca, newdata = pca_testset ) )

new_trainset = train[, 1:9]
new_testset =  t[, 1:8]

# Build the neural network (NN)
library( neuralnet )
n = names( new_trainset )
f = as.formula( paste( "class ~", paste( n[!n %in% "class" ], collapse = "+" ) ) )
nn = neuralnet( f, new_trainset, hidden = 4, linear.output = FALSE, threshold=0.01 )

# Plot the NN
plot( nn, rep = "best" )
图 04.具有新数据集的神经网络
# Test the resulting output
nn.results = compute( nn, new_testset )

# Results
results = data.frame( actual = test$class, 
                      prediction = round( nn.results$net.result ) )

# Confusion Matrix
library( caret )
t = table( results ) 
print( confusionMatrix( t ) )
## Confusion Matrix and Statistics
## 
##       prediction
## actual  0  1
##      0 76  3
##      1  1 94
##                                                 
##                Accuracy : 0.9770115             
##                  95% CI : (0.9421888, 0.9937017)
##     No Information Rate : 0.5574713             
##     P-Value [Acc > NIR] : < 0.00000000000000022 
##                                                 
##                   Kappa : 0.9535318             
##  Mcnemar's Test P-Value : 0.6170751             
##                                                 
##             Sensitivity : 0.9870130             
##             Specificity : 0.9690722             
##          Pos Pred Value : 0.9620253             
##          Neg Pred Value : 0.9894737             
##              Prevalence : 0.4425287             
##          Detection Rate : 0.4367816             
##    Detection Prevalence : 0.4540230             
##       Balanced Accuracy : 0.9780426             
##                                                 
##        'Positive' Class : 0                     
##

        好吧,我想我们现在得到了更好的结果。让我们仔细检查一下。

        这次混淆矩阵显示出非常好的结果,神经网络在两个类中的错误分类较少,可以看出主对角线的值和准确率值在 95% 左右。这意味着分类器有 95% 的机会正确分类一个新的看不见的示例。对于分类问题,这根本不是一个不错的结果。

五、结论

        降维在机器学习中起着非常重要的作用,尤其是当您处理数千个特征时。主成分分析是顶级降维算法之一,在实际项目中不难理解和使用。正如我们在这篇文章中看到的那样,这种技术除了使特征操作的工作更容易之外,它仍然有助于改善分类器的结果。

        最后,初始问题的答案是肯定的,确实主成分分析有助于改善分类器的结果。

六、下一步是什么?

        正如我之前提到的,还有其他降维技术可用,例如线性判别分析、因子分析、等距图及其变体。ideia是探索每个人的优缺点,并单独和组合检查其结果。LDA与PCA相结合会改善分类器的结果吗?好吧,让我们在下一篇文章中调查一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/836069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线免费做分班查询软件:这个制作分班查询系统的平台就可实现

在制作分班查询系统前&#xff0c;作为老师的我们可以先理清制作分班查询系统的意义&#xff01;这几个要点可能很多老师都没有留意过&#xff01; 提高工作效率&#xff1a; 学校每年都需要进行学生的分班工作&#xff0c;如果采用传统的手工方式进行分班查询&#xff0c;会…

防火墙规则分析管理

防火墙规则在高效的网络安全管理中起着至关重要的作用&#xff0c;在添加规则之前&#xff0c;确保提议的新规则不会对网络产生负面影响至关重要。 通过防火墙规则影响分析&#xff0c;安全管理员可以详细了解添加新规则的可能影响&#xff0c;防火墙规则影响分析的一个重要方…

假日购物季已经打响?卖家要提前行动起来啦!

去年&#xff0c;假日购物季比以往任何时候都要早开启&#xff0c;这促使消费者对今年的购物季抱有更多的期待。 根据Optimove最新的消费者调查&#xff0c;有一半的消费者&#xff08;50%&#xff09;计划在11月之前开始他们的假日购物。 当被问及是什么促使他们提前购买时&…

【已解决】安装win7系统,“Windows安装程序无法将Windows配置在此计算机的硬件上运行”

问题&#xff1a; 安装windows7时报错&#xff1a;“Windows安装程序无法将Windows配置在此计算机的硬件上运行” 解决办法&#xff1a; 方法一 shiftF10 调出命令提示行&#xff0c;输入cd oobe 然后再输入msoobe 回车&#xff0c;就可以继续进行下一步了。 如果方法一不…

你知道充电桩控制主板的结构吗?

你知道充电桩控制主板的结构吗? 你是否曾经遇到过电动车行驶途中突然没电的情况?不用担心&#xff0c;解决这个问题的方法之一就是使用充电桩。那么&#xff0c;控制主板是如何控制充电桩的呢?让我们一起来探究一下。 充电桩控制主板由多种元件组成&#xff0c;包括主控芯片…

亚马逊Q2业绩呈井喷式增长,净销售额高达1344亿美元

周四&#xff08;8月3日&#xff09;&#xff0c;亚马逊公布了截至6月30日的2023年第二季度财务业绩。在电商、云和广告销售强劲的推动下&#xff0c;该电商巨头的利润出现井喷式增长。周四盘后交易中&#xff0c;亚马逊股价上涨逾7%。 财报显示&#xff0c;在截至6月30日的这…

linuxARM裸机学习笔记(3)----主频和时钟配置实验

引言&#xff1a;本文主要学习当前linux该如何去配置时钟频率&#xff0c;这也是重中之重。 系统时钟来源&#xff1a; 32.768KHz 晶振是 I.MX6U 的 RTC 时钟源&#xff0c; 24MHz 晶振是 I.MX6U 内核 和其它外设的时钟源 1. 7路PLL时钟源【都是从24MHZ的晶振PLL而来…

LeetCode112. 路径总和

112. 路径总和 文章目录 [112. 路径总和](https://leetcode.cn/problems/path-sum/)一、题目二、题解方法一&#xff1a;递归存储各个路径之和方法二&#xff1a;递归版本2简化版本 一、题目 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 …

回调函数的简单用例

列举项目中一个简单的回调函数用例 ①用MsgInterface_t定义一个结构体s_Lin_MsgInterface&#xff0c;包含两个回调函数成员&#xff1a; ②确定结构体下的回调函数成员的参数&#xff1a; ③传入实参&#xff0c;确定结构体下的回调函数成员的函数名&#xff1a; ④最终回…

docker容器互联详解

目录 docker容器互联详解 一、容器互联概述&#xff1a; 二、案例实验&#xff1a; 1、用户自定义的网络&#xff1a; 2、查看当前的IP信息&#xff1a; 3、启动第三个容器&#xff1a; 4、查看三个容器内部的网络&#xff1a; 5、Ping测试&#xff1a; Ps备注&#x…

CVE-2008-5161

SSH服务器CBC加密模式漏洞 1.描述 一般经过我们的加固&#xff0c;Linux环境中一般都已经采用AES这种算法加密&#xff0c;AES有五种加密模式&#xff08;CBC、ECB、CTR、OCF、CFB&#xff09;&#xff0c;centos7.x系统启动sshd服务后&#xff0c;系统默认选择CBC的机密模式…

div上下左右居中几种方式

div固定宽高 div{width:200px;height:200px;background-color:red; }1、绝对定位&#xff08;常用于登录模块&#xff09; 备注&#xff1a;前提条件div需要有宽高 #html <div class"box"></div> #css .box{ position:absolute/fixed; left:0; right:0…

凯迪正大—SF6泄漏报警装置的主要特点

SF6泄漏报警系统主要特点 ① 系统采用声速原理&#xff0c;可定量、实时在线测量SF6泄漏气体含量&#xff0c;克服了传统测量方法如负电晕放电法和卤素传感器法只能定性判别是否越限的缺陷&#xff0c;能够准确得到气体中SF6含量。 ② 系统采用双差分处理方法&#xff0c;有效…

Linux知识点 -- 进程间通信(一)

Linux知识点 – 进程间通信&#xff08;一&#xff09; 文章目录 Linux知识点 -- 进程间通信&#xff08;一&#xff09;一、了解进程间通信1.进程间通信的必要性2.进程间通信的技术背景3.进程间通信的本质理解4.进程间通信的标准 二、匿名管道1.匿名管道通信的原理2.匿名管道的…

Docker网络模型详解

目录 一、Docker网络基础 1.1、端口映射 1.2、端口暴露 1.3、容器互联 二、Docker网络模式 2.1、Host模式 2.2、container模式 2.3、none模式 2.4、bridge模式 2.5、Overlay模式 网络是激活Docker体系的唯一途径&#xff0c;如果Docker没有比较出色的容器网络&#xff0…

SpringBoot项目-个人博客系统的实现【下】

10.实现强制要求登陆 当用户访问 博客列表页和 博客详情页时, 如果用户当前尚未登陆, 就自动跳转到登陆页面 1.添加拦截器 public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletRespon…

程序员私活渠道揭,探索项目接单秘

对于程序员来说&#xff0c;接私活是很正常的事情&#xff0c;在工作闲暇时间利用业余时间来赚点零花钱还是非常不错的&#xff0c;但是如果能一边接私活一边提高自己的水平那就更好了。 这里给大家的建议就是&#xff0c;可以接一些稍微有难度但是在自己能力范围的项目&#x…

自动化测试:封装入口文件

1自动生成测试报告&#xff0c;start_dir是要找入口文件的相对目录。测试用例有规律的话&#xff0c;pattern可以批量执行&#xff08;通过相同的开头*&#xff09; start_dir 是要执行的测试文件所在的目录&#xff0c;pattern可以理解为具体的执行测试的文件 2所有的底层操…

C++stack_queue

stack_queue 容器适配器stack详解栈适配器栈模拟实现 队列详解队列适配器queue模拟实现 容器适配器 除了顺序容器外&#xff0c;标准库还定义了三个顺序容器适配器:stack(栈),queue(队列),priority_queue(优先队列)。适配器是标准库中的一个通用概念。容器&#xff0c;迭代器和…

Android Jetpack

Jetpack 是一个由多个库组成的套件&#xff0c;可帮助开发者遵循最佳实践、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码&#xff0c;让开发者可将精力集中于真正重要的编码工作。 1.基础组件 &#xff08;1&#xff09;AppCompat&#xff1a;使得支持较低…