神经网络可以像经典主成分分析一样执行降维吗?
bigegpt 2024-11-10 08:26 35 浏览
介绍
主成分分析(PCA)是最流行的降维算法之一。PCA的工作原理是找出在数据中相互正交的方差很大的轴。在我??轴被称为我??主成分(PC)。执行PCA的步骤是:
- 标准化数据。
- 从协方差矩阵或相关矩阵中获取特征向量和特征值,或执行奇异值分解。
我们将通过实现sklearn来执行PCA:它使用scipy(scipy.linalg)中的奇异值分解(SVD )。SVD是2D矩阵A的分解。它写为:
S是一维数组瓦特? ICH中包含的奇异值阿; ü和V 2 H是酉(? ? ? = UU ?= I)。大多数PCA实现都执行SVD,以提高计算效率。
另一方面,自动编码器(AE)是一种特殊的神经网络,经过训练可将其输入复制到其输出。首先,它将输入映射到一个尺寸减小的潜在空间,然后将潜在表示编码回输出。AE学习通过减少重构误差来压缩数据。
稍后我们将看到如何实现和比较PCA和自动编码器的结果。
我们将使用sklearn的make_classification生成数据,这还将为我们提供一些标签。我们将使用这些标签在我们的方法之间的聚类效率之间进行比较。
将分为三个部分。
在第一个中,我们将实现一个简单的不完全线性自动编码器:即,具有单层的自动编码器,其尺寸小于其输入。第二部分将介绍堆叠线性自动编码器。
在第三部分中,我们将尝试修改激活功能以解决更多的复杂性。
将结果与PCA进行图形比较,最后,我们将尝试使用带有交叉验证的简单随机森林分类算法来预测类别。
资料准备
在下面的代码中,您具有所有用于设置数据的代码:首先,我们导入必要的库,然后使用scikit-learn的“ make分类”方法生成数据。在50个功能中,我们将指定仅15个具有信息性,并且将约束我们的约简算法以仅选择5个潜在变量。
有了数据后,我们将其分为训练验证测试。我们将使用神经网络(NN)的验证数据,而测试集将最终用于检查某些分类性能。
最后,我们将数据标准化:请注意,我们将缩放器安装在训练数据集上,然后转换成验证和测试集。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow import keras
# generate data
X, y = datasets.make_classification(n_samples=10000, n_features=50, n_redundant=10, n_informative=10,
random_state=1, n_clusters_per_class=2,n_classes=3, class_sep=2)
# divide data in Train - Validation - Test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
X_tr, X_valid, y_tr, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=42)
# Standardize Data
sc = StandardScaler()
X_tr_std = sc.fit_transform(X_tr)
X_valid_std = sc.transform(X_valid)
X_test_std = sc.transform(X_test)
左侧的数据相关热图显示了一些相关特征,但大多数没有。在右侧,我们绘制了特征的方差,从中可以推断出只有10-15个变量对我们的数据集有用。
不完整的线性自动编码器
在本节中,如果执行以下操作,我们将看到数据发生了什么变化:
- 将数据压缩到5个潜在维度
- 使用线性激活功能
- 使用“ MSE”作为损耗指标
让我们设置这个AE:
encoder = keras.models.Sequential([
keras.layers.Dense(5, input_shape=[50]),
])
decoder = keras.models.Sequential([
keras.layers.Dense(50, input_shape=[5]),
])
autoencoder = keras.models.Sequential([encoder, decoder])
autoencoder.compile(loss='mse', optimizer = keras.optimizers.SGD(lr=0.1))
history = autoencoder.fit(X_tr_std,X_tr_std, epochs=100,validation_data=(X_valid_std,X_valid_std),
callbacks=[keras.callbacks.EarlyStopping(patience=10)])
codings = encoder.predict(X_tr_std)
首先,我们定义编码器模型:请注意,将输入形状硬编码为数据集的维数,并且将潜在空间固定为5个维。解码器模型是对称的:在这种情况下,我们指定输入形状为5(潜在尺寸),其输出将为原始空间尺寸。最终模型“自动编码器”将两者结合在一起。
然后,我们使用随机梯度下降SGD优化器以均方误差度量编译自动编码器,固定学习率为0.1
在拟合步骤中,我们仅指定验证数据,如果验证损失没有改善,则使用提早停止的回调来停止训练。
最后,我们只能使用模型的第一部分“ encoder.predict(X_tr_std) ”来计算编码。该模型非常简单:
从学习曲线可以看出,拟合在60个周期后停止,损失约为0.7。结果显示的前两个编码如下所示:
PCA实施:使用sklearn可以轻松实现。
from sklearn.decomposition import PCA
pca = PCA(n_components=5,svd_solver='auto')
scores = pca.fit_transform(X_tr_std) # u
下面,我们为前三个组件绘制了PCA(左图)和Encoder(右图)的聚类训练数据。
从上面的图中可以看出,两种算法都以相似的方式执行了降维。推断哪个表现更好并不容易。让我们看看这些编码的一些属性。
下面我们绘制了PCA(上)和Autoencoder(下)组件的标准偏差。
从这些图表中,我们可以看到,对于PCA而言,我们具有主成分的标准偏差,正如预期的那样,每个主成分的标准偏差都会减小。另一方面,所有编码的标准偏差几乎相等。
下面,我们绘制了PCA(上)和Encoder(下)的组件的相关图。
从该图中还可以看到,尽管PC彼此正交:它们没有相关性,但对于编码而言却并非如此。它们之间显示出一些相关性。实际上,我们的神经网络模型并未对此行为施加任何限制。网络找到了在潜在空间中映射原始输入的最佳方法。
从原始空间到两个不同的潜在空间的分类性能如何?有什么区别吗?
我们可以使用交叉验证使用RandomForestClassifier并查看结果。这是代码:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
rfc = RandomForestClassifier(n_estimators=200, max_depth=5)
labels = ['Original', 'PCA','AE']
scores = pd.DataFrame(columns=labels)
scores['PCA'] = cross_val_score(rfc, scores_train, y_tr, cv=5)
scores['AE'] = cross_val_score(rfc, codings_train, y_tr, cv=5)
scores['Original'] = cross_val_score(rfc, X_tr_std, y_tr, cv=5)
sns.barplot(x='dataset', y='score', data = scores.melt(value_name='score', var_name='dataset'))
plt.ylim(0.9,1)
从上面的小节中我们可以看到,除去5以外的所有元素,都降低了预期的预测精度。尽管如此,PCA和AE数据还原的性能还是相当的,但AE的性能比PCA差一些。
现在,我们将尝试了解更复杂的AE堆叠是否会带来更好的结果。
线性堆叠式编解码器
在这里,我们像以前一样实现了编解码器网络结构,但是在这种情况下,我们将堆叠更多的隐藏层。这应该使网络具有更大的灵活性来学习不同的,最有用的功能。
编码器层为:50(输入)— 20–15–5。损失与以前的不良事件相当。解码器只是对称的。组件显示在下面。
在分类性能方面的结果是:
显然,堆叠隐藏层比简单AE具有更好的效果。但是,可以针对特定问题对底层的确切配置进行微调。
非线性堆叠式编解码器
非线性堆叠AE将很容易实现为堆叠AE,但具有激活功能。我们还通过SGD优化器引入了衰减常数,因此学习率将随着时间的推移而降低。我们选择“ selu”作为所有层的激活层。请注意,这里我们进一步增加了复杂性:针对特定问题,我们可以尝试找到最佳的隐藏层数,最佳的激活函数和每一层的形状。
nl_st_encoder = keras.models.Sequential([
keras.layers.Dense(20, input_shape=[50], activation='relu'),
keras.layers.Dense(15, activation='selu'),
keras.layers.Dense(5, activation='selu'),
])
nl_st_decoder = keras.models.Sequential([
keras.layers.Dense(15, input_shape=[5], activation='selu'),
keras.layers.Dense(20, activation='selu'),
keras.layers.Dense(50, activation='relu'),
])
nl_st_autoencoder = keras.models.Sequential([nl_st_encoder, nl_st_decoder])
nl_st_autoencoder.compile(loss='mse', optimizer = keras.optimizers.SGD(lr=1, decay=1e-4))
nl_st_autoencoder.summary()
history = nl_st_autoencoder.fit(X_tr_std,X_tr_std, epochs=500,validation_data=(X_valid_std,X_valid_std),
callbacks=[keras.callbacks.EarlyStopping(patience=10)],verbose=1)
nl_st_codings_train = nl_st_encoder.predict(X_tr_std)
nl_st_codings_test = nl_st_encoder.predict(X_test_std)
以下是前三个组件:
至于分类性能,允许网络学习非线性特征有助于提高整体性能,这似乎比PCA更好,但在误差范围内。
结论
我们使用sklearn的make_classification建立了一个玩具数据集,用于分类练习,具有50个功能。我们的目的是比较PCA和AutoEncoder神经网络,以查看降维是否具有可比性。
我们查看了得分/编码的属性,我们发现来自AE的编码具有一定的相关性(协变矩阵不像PCA中那样是对角线的),并且它们的标准偏差也相似。
从只有一层的简单线性不完全AE开始,我们看到,随着分类准确度的提高,复杂性的提高帮助模型达到了更好的性能。
最后,我们看到非线性模型仍然可以比其他两个模型(一层AE和堆叠式AE)更好,但是在该数据集中,其性能仍可与PCA媲美。
现在我们可以回答最初的问题:神经网络是否可以像经典成分分析一样执行降维?
答案是肯定的,它可以像PCA一样执行降维,从某种意义上说,网络将找到在潜在空间中编码原始矢量的最佳方法。但是不,潜在向量的属性是不同的,并且网络本身可能需要针对特定?任务进行调整,以便像我们对更多隐藏层所做的那样表现更好。
相关推荐
- 悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)
-
新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...
- 高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源
-
凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...
- 微服务架构实战:商家管理后台与sso设计,SSO客户端设计
-
SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...
- 还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑
-
在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...
- Seata源码—6.Seata AT模式的数据源代理二
-
大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...
- 30分钟了解K8S(30分钟了解微积分)
-
微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...
- SpringBoot条件化配置(@Conditional)全面解析与实战指南
-
一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...
- 一招解决所有依赖冲突(克服依赖)
-
背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...
- 你读过Mybatis的源码?说说它用到了几种设计模式
-
学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...
- golang对接阿里云私有Bucket上传图片、授权访问图片
-
1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...
- spring中的资源的加载(spring加载原理)
-
最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...
- Android资源使用(android资源文件)
-
Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...
- 如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)
-
深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...
- @Autowired与@Resource原理知识点详解
-
springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...
- java的redis连接工具篇(java redis client)
-
在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)