算法小白的第一次尝试---PCA(主成分分析)降维【适合各种纬度数据】

浅谈PCA算法 PCA(Principal Component Analysis)是一种数据分析方法,它通过线性变换将原始数据变换为一组各维度线性无关的表示,用于提取数据的主要特征分量,常用于高维数据的降维。降低数据的维度是非常有用的,如我们看到数据的分布仅限于2维或者3维,低维数据可以在数值算法中明显减少运行时间,而且许多统计模型存在协变量的高度相关,PCA就可以产生不相关协变量的线性组合。 PCA的思想是将 阅读详情
-------------------------------------------------------------------------------------
笔者追求算法实现,不喜欢大篇幅叙述原理,有关PCA理论推荐查看该篇博客

http://www.cnblogs.com/pinard/p/6239403.html

特此说明:发现之前写的不是很好,特地从UCI上找了Wine葡萄酒的例子重新写了一次。

LDA降维欢迎前往笔者下一篇博客:https://blog.csdn.net/Java_Man_China/article/details/89504514

KPCA降维欢迎前往笔者下一篇博客:
https://blog.csdn.net/Java_Man_China/article/details/89677371
-------------------------------------------------------------------------------------
import breeze.linalg.{DenseMatrix, eig}
import org.apache.log4j.{Level, Logger}
import org.apache.spark.ml.feature.{LabeledPoint,StandardScaler, VectorAssembler}
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.sql.types.{DoubleType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Row, SparkSession}
import scala.collection.mutable.ArrayBuffer

/** The method attempts to lower the dimensionality based on PCA
  * Data Source:http://archive.ics.uci.edu/ml/datasets/Wine
  * @author XiaoTangBao
  * @date 2019/4/16 9:16
  * @version 1.0
  */
object PCA {
  def main(args: Array[String]): Unit = {
    //屏蔽日志
    Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
    //spark初始化
    val spark = SparkSession.builder().master("local[4]").appName("LDA").getOrCreate()
    //获取数据源   http://archive.ics.uci.edu/ml/datasets/Wine
    val data = spark.sparkContext.textFile("G:\\mldata\\wine.data").map(line => line.split(","))
      .map(arr => arr.map(str => str.toDouble)).map(arr =>Row(arr(0),arr(1),arr(2),arr(3),arr(4),arr(5),
      arr(6),arr(7),arr(8),arr(9),arr(10),arr(11),arr(12),arr(13)))

    //设置featuresArr和schema,便于后期数据转化及生成dataFrame
    val featuresArr = Array("Alcohol","Malic acid","Ash","Alcalinity of ash","Magnesium",
      "Total phenols","Flavanoids","Nonflavanoid phenols","Proanthocyanins","Color intensity",
      "Hue","OD280/OD315 of diluted wines","Proline")
    val schema = StructType(List(StructField("label",DoubleType,true),StructField("Alcohol",DoubleType,true),StructField("Malic acid",DoubleType,true),
      StructField("Ash",DoubleType,true),StructField("Alcalinity of ash",DoubleType,true),StructField("Magnesium",DoubleType,true)
      ,StructField("Total phenols",DoubleType,true),StructField("Flavanoids",DoubleType,true),StructField("Nonflavanoid phenols",DoubleType,true)
      ,StructField("Proanthocyanins",DoubleType,true),StructField("Color intensity",DoubleType,true),StructField("Hue",DoubleType,true)
      ,StructField("OD280/OD315 of diluted wines",DoubleType,true),StructField("Proline",DoubleType,true)))
    val oridf = spark.createDataFrame(data,schema)

    //设置转化器
    val vectorAsb = new VectorAssembler().setInputCols(featuresArr).setOutputCol("features")
    //数据整理后传入run,启动PCA算法
    val newdf = vectorAsb.transform(oridf).select("label","features")
    //标准化处理数据,标准化后不再需要去中心化
    val std = new StandardScaler().setInputCol("features").setOutputCol("Scaledfeatures")
      .setWithMean(true).setWithStd(true).fit(newdf).transform(newdf)
      .select("label","Scaledfeatures")
      .withColumnRenamed("Scaledfeatures","features")

    val result = run(std,2)
    val arr = ArrayBuffer[(Double,Double)]()
    for(i<-0 until result.cols) arr.append((result(0,i),result(1,i)))
    arr.foreach(tp =>println(tp._1))
    println()
    arr.foreach(tp =>println(tp._2))
  }

  /**
    * the method attempts to lower the dimensionality
    * @param data the ioriginal data which in high dimensions, include label and features cols
    * @param k the final dimensions
    */
  def run(df:DataFrame,k:Int)={
    val trainData = df.select("features").rdd.map(row => row.toString())
      .map(str => str.replace('[',' '))
      .map(str => str.replace(']',' '))
      .map(str => str.trim).map(str => str.split(','))
      .map(arr => arr.map(str => str.toDouble)).collect()

    val labels = df.select("label").rdd.map(row => row.toString())
      .map(str => str.replace('[',' '))
      .map(str => str.replace(']',' '))
      .map(str => str.trim).map(str => str.toDouble).collect()

    //特征列数
    val tz = trainData(0).length
    //生成新的带label的数据
    val labArr = ArrayBuffer[LabeledPoint]()
    for(i<-0 until trainData.length) labArr.append(LabeledPoint(labels(i),Vectors.dense(trainData(i))))
    //总样本组成的大型矩阵
    val allData = labArr.map(lab => lab.features).map(vec => vec.toArray).flatMap(x => x).toArray
    val big_Matrx =new DenseMatrix[Double](tz,trainData.length,allData)
    
//    //存放向量各维度的均值
//    val big_mean = sum(big_Matrx,Axis._1).*= (1.0 / big_Matrx.cols)
//    //样本中心化
//    for(i<-0 until big_Matrx.cols) big_Matrx(::,i) := big_Matrx(::,i) - big_mean

    //计算样本的协方差矩阵
    val covMatrix = (big_Matrx * big_Matrx.t) * (1.0 / (big_Matrx.cols-1))
    val eigValues = eig(covMatrix).eigenvalues
    val eigVectors = eig(covMatrix).eigenvectors

    //选取最大的k个特征值对应的特征向量
    val label_eig = DenseMatrix.horzcat(eigVectors.t,eigValues.toDenseMatrix.t)
    var strArr = ArrayBuffer[String]()
    for(i<-0 until label_eig.rows) strArr.append(label_eig.t(::,i).toString)
    for(i<-0 until strArr.length){
       strArr(i) = strArr(i).replace("DenseVector(","").replace(')',' ').trim()
    }
    val da = ArrayBuffer[LabeledPoint]()
    for(str <- strArr){
      val arr = str.split(',').map(string => string.toDouble)
      val lab = arr.takeRight(1)(0)
      val value = arr.take(arr.length -1)
      val labPoint = LabeledPoint(lab,Vectors.dense(value))
      da.append(labPoint)
    }

    val result = da.sortBy(labPoint => labPoint.label).reverse.take(k).map(lab => lab.features).map(vec => vec.toArray)
    var rt = DenseMatrix.zeros[Double](result.length,result(0).length)
    for(i<-0 until rt.rows){
      for(j<-0 until rt.cols){
        rt(i,j) = result(i)(j)
      }
    }

    //降维后的数据集
    val newData = rt * big_Matrx
    newData
  }
}

Wine 葡萄酒原始数据共13个特征,选取其中两列绘制二维图
Java_Man_China
数据未标准化(仅去中心化),采用PCA算法降至二维后的结果如下:
Java_Man_China
此时发现降维后几乎看不到效果,数据依旧混乱(无法区分)

下图为调用Python包实现PCA的结果,依旧没有对数据进行标准化

--------Python调包--------from sklearn.decomposition import PCA------------------

对比上面两幅图发现,似乎降维后两者结果不一样,这是由于Python调包求解的特征向量与笔者自己计算的特征向量不一致导致的,同一矩阵,相同的特征值下有n个不同的特征向量。为了拟合python结果,笔者将求出的某个特征向量乘以-1后,结果显示如图:
Java_Man_China
此时大家应该发现两者是一致的了。

数据标准化后,PCA降至二维的结果如下图所示:(对结果乘以了-1,方便对比Python库)
Java_Man_China
此时发现数据终于可分了。(干一杯葡萄酒)
下图为数据标注化后,调用python库的结果:(毫无意外的一样)
在这里插入图片描述
实验结果表明:笔者的算法是正确的。。。。。。。。。。。

降维算法 | PCA | UMAP | t-SNE 降维是指通过保留一些比较重要的特征,去除一些冗余的特征,减少数据特征的维度。单细胞聚类的一般步骤有:数据质控,基因筛选,PCA降维,以及基于PCA预降维空间的聚类和进一步的降维可视化。 阅读详情

相关推荐

MDS vs PCA:哪种降维方法更适合你的数据?

本文深入对比了多维尺度变换(MDS)与主成分分析(PCA)两种降维方法,从算法原理、适用场景到实战选型进行全面解析。MDS擅长保持数据点间距离关系,适合处理相似性数据;PCA则通过最大化方差实现线性降维,计算效率更高。文章提供了详细的决策指南和参数调优建议,帮助读者根据数据类型和需求选择最佳降维方案。

weixin_30566063的博客 400

主成分分析法(PCA)

主成分分析法(PCA) PCA的实质:就是在尽可能好地代表原始数据的前提下,通过线性变换,将高维样本数据投影到低维空间中。 主成分分析法的适用范围:主要用于高维数据的降维,不适合样本的分类。 1.1 理论推导 基本思想:代表样本的数据应该和所有的样本数据的距离最小。 推导过程: 1)“0维”,即样本数据映射到一个点上。寻找最佳数据点,设其为x0x_{0}x0​,则最佳点到样本数据的距离和为: D(...

weixin_45505744的博客 1729

java版pca降维

两个文件,一个是pca实现类,一个是test运行类

[Machine Learning] 12 降维(Dimensionality Reduction)

点Ta12 Dimensionality Reduction(降维)12.1 Motivation I_ Data Compression 12 Dimensionality Reduction(降维) 12.1 Motivation I_ Data Compression 第二种无监督学习问题,称为降维。使用降维可以实现数据压缩,数据压缩不仅压缩数据,因而使用较少的计算机内存或磁盘空间,但它也让我们加快我们的学习算法。 但首先,让我们谈论降维是什么。作为一种生动的例子,我们收集的数据集,有许多, 许多特征

今天你DEBUG了吗 687

PCA用java实现

我用java实现了PCA算法,其中调用了matlab的函数。

PCA主成分分析java实现

用java实现的主成分分析算法,用了Jama.Matrix,用的是Jama-1.0.2.jar。代码有备注,希望有帮助。

PCA降维算法

PCA主成分分析算法

m0_65981035的博客 818

Java实现pca

Java实现pca,基本全部的函数都是自我实现,代码简单易懂,方便理解pca

SCS【5】单细胞转录组数据可视化分析 (scater)

单细胞转录组数据可视化分析 (scater)

weixin_41368414的博客 1923

JAVA PCA主成分分析

Java实现主成分分析PCA,详细的代码注释

AMCL实战:如何用2D激光雷达在ROS中实现稳定重定位(附参数调优指南)

本文深入解析了在ROS中使用2D激光雷达实现稳定AMCL重定位的实战技巧与参数调优指南。针对粒子发散、位姿跳变等常见问题,文章从算法核心原理出发,系统讲解了初始化、粒子滤波、运动与观测模型等关键参数的分类与调优策略,并提供了一套经过验证的调优框架,帮助开发者提升移动机器人在已知地图环境下的定位鲁棒性和稳定性。

sql99的博客 137

降维算法:主成分分析 VS 自动编码器

降维是一种减少特征空间维度以获得稳定的、统计上可靠的机器学习模型的技术。降维主要有两种途径:特征选择和特征变换。 特征选择通过选择重要程度最高的若干特征,移除共性的或者重要程度较低的特征。 特征转换也称为特征提取,试图将高维数据投影到低维空间。一些特征转换技术有主成分分析(PCA)、矩阵分解、自动编码器(Autoencoders)、t-Sne、UMAP等。 本文主要介绍了主成分分析以及自动编码器两种方法,具体分析两者的优缺点,并且通过一个生动的示例进行详解。 主成分分析 主成分分析是一种无监督技术,将原始数

deephub 1万+

Autosar Os降低CPU负载的方案总结

由于各个项目的实际场景不尽相同,可能需要有针对性的对症优化。如果你还有别的一些优化手段欢迎留言交流。

3679

算法小白的第一次尝试---KPCA(核主成分分析)降维【实例对比分析PCA、LDA和KPCA】

------------------------------------------------------------------------------------- 笔者追求算法实现,不喜欢大篇幅叙述原理,有关KPCA理论推荐查看该篇博客 https://blog.youkuaiyun.com/zjuPeco/article/details/77510981 PCA降维欢迎前往笔者上一篇博客: ht...

Java_Man_China的博客 1万+

Windows服务器渗透必备:5款杀软在线识别平台实测对比(附避坑指南)

本文针对Windows服务器渗透测试中的关键环节,实测对比了五款主流的在线杀软识别平台。文章从实战场景出发,深入分析了各平台在识别准确率、响应速度、隐匿性及使用风险上的差异,并提供了详尽的避坑指南与高级隐匿技巧,旨在帮助安全人员快速、精准地识别目标环境安全防护,为后续行动奠定情报基础。

weixin_29322553的博客 434

从一只龙虾到一支团队:OpenClaw 单 Bot 多 Agent 配置实践

单 Bot 多 Agent只有一个对外的聊天入口(飞书 Bot)内部有多个独立的 AI Agent,各司其职主 Agent(总指挥)负责接收任务并分配给子 Agent子 Agent 完成任务后将结果返回给主 Agent角色Agent ID职责使用场景🎯 总指挥main-agent统筹协调,任务分发接收所有用户请求✍️ 笔杆子内容创作公众号、博客、小红书🔬 参谋canmou深度研究竞品分析、市场调研📋 运营官operations运营管理邮件、日历、社交媒体。

Maynor的博客 1084

PCA 数学原理和代码尝试

PCA算法本身不难,难在了数学原理的推导,需要线代、微积分的基础知识,本身有些忘记了,也可以在学习算法的过程中回忆起来。PCA算法是一个无监督的降维算法,只需要对特征值分解,就能对数据进行压缩、降噪,对解决大量的多维数据有很好的效果。PCA本质上是将方差最大的方向作为主要特征,并且在各个正交方向上将数据“离相关”,也就是让它们在不同正交方向上没有相关性。

請毒藥的博客 1623

构建高效的LLM应用测试框架

《构建高效的LLM应用测试框架》 关键词:LLM,测试框架,应用测试,效率优化,测试原理 摘要:本文将深入探讨构建高效LLM应用测试框架的必要性、方法与步骤,旨在为开发者提供一套系统化、可操作的测试解决方案,从而提升LLM

AI天才研究院 1049

降维算法总结 一

降维之PCA,FA,LLE

zwlq1314521的专栏 2558

Allegro格式PCB转换成Pads操作指导

变量:AEX_BIN_ROOT 值:D: MentorGraphics>PADSVX1.2>SDD_HOME>translators>win32bin (值:软件按装的位置,可以是9.5版本,也可以是VX1.0等不同的版本)。变量:HOME 值:C:Users>win7>AppData>Roaming>SPB_Data (这个值是allegro快捷键存放位置器,也可以随意放置在那个盘,我们可以采用默认的路径)。第4步:打开 PADSLayout软件,然后选择导入文件,选择刚刚处理的 allegro文件。

weixin_54787054的博客 3721

YOLOv9电力巡检实战:绝缘子破裂/鸟巢识别+无人机自动定位

摘要:本文聚焦电力输电线路巡检的效率与安全痛点,提出基于YOLOv9与无人机的智能巡检解决方案。针对绝缘子破裂、鸟巢等高危缺陷,通过“无人机改装-模型训练-缺陷识别-工单生成”四阶段工程落地流程,实现全自动化巡检。系统采用大疆M300无人机搭载RTK模块与Jetson边缘计算盒,结合改进YOLOv9模型实时识别5类缺陷,通过4G传输将GPS定位与缺陷数据同步至工单系统。实测表明,该方案巡检效率达50公里/天(较人工提升10倍),缺陷发现率95%(提升40%),事故预防率98%。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1514

python数据降维

数据为何要降维 数据降维可以降低模型的计算量并减少模型运行时间、降低噪音变量信息对于模型结果的影响、便于通过可视化方式展示归约后的维度信息并减少数据存储空间。因此,大多数情况下,当我们面临高维数据时,都需要对数据做降维处理。 数据降维有两种方式:特征选择,维度转换 特征选择 特征选择指根据一定的规则和经验,直接在原有的维度中挑选一部分参与到计算和建模过程,用选择的特征代替所有特征,不改变原有特征,...

weixin_42617035的博客 1425

微信公众号 - 最新详细实现H5网页接入微信支付功能,开发移动端、PC端网站集成使用微信支付流程及示例代码,公众号网页利用JS-SDK/JSAPI/H5支付授权唤起微信支付,可脱离微信环境支付或内置浏

微信公众号,微信支付,网页,移动端,h5,扫码支付,二维码付款,手机网页,电脑pc网页生成支付二维码,js-sdk,jsapi,外部浏览器调起微信支付,脱离微信环境,在微信内置浏览器如何进行微信支付,前端H5微信支付,web网站,vue2,vue3,nuxt2,nuxt3,jquery,微信公众号h5支付流程,如何实现,怎么做,回调报错,redirect_uri参数错误,必须部署才能调试吗,怎么不打包发布就能在本机测试,微信H5支付能力,uniapp微信支付,h5页面调起支付,支付没反应,无效,失败,H5页

🏆 前端领域优质创作者 6106

canoco5主成分分析步骤_降维算法:主成分分析 VS 自动编码器

降维是一种减少特征空间维度以获得稳定的、统计上可靠的机器学习模型的技术。降维主要有两种途径:特征选择和特征变换。特征选择通过选择重要程度最高的若干特征,移除共性的或者重要程度较低的特征。特征转换也称为特征提取,试图将高维数据投影到低维空间。一些特征转换技术有主成分分析(PCA)、矩阵分解、自动编码器(Autoencoders)、t-Sne、UMAP等。本文主要介绍了主成分分析以及自动编码器两种方法...

weixin_39688875的博客 439

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

机器学习——降维

15 降维 15.1 为什么需要降维? ​ (1)多余的特征会影响或误导学习器 ​ (2)更多特征意味着更多参数需要调整,过拟合风险也越大 ​ (3)数据的维度可能只是虚高,真实维度可能比较小 ​ (4)维度越少意味着训练越快,更多东西可以尝试,能够得到更好的结果 ​ (5)如果我们想要可视化数据,就必须限制在两个或三个维度上 ​ 因此,我们需要通过降维把无关或冗余的特征删掉。 ​ ...

喜欢吃冰棍de谷利文君的博客 894

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

canoco5冗余分析步骤_降维算法:主成分分析 VS 自动编码器

降维是一种减少特征空间维度以获得稳定的、统计上可靠的机器学习模型的技术。降维主要有两种途径:特征选择和特征变换。特征选择通过选择重要程度最高的若干特征,移除共性的或者重要程度较低的特征。特征转换也称为特征提取,试图将高维数据投影到低维空间。一些特征转换技术有主成分分析(PCA)、矩阵分解、自动编码器(Autoencoders)、t-Sne、UMAP等。本文主要介绍了主成分分析以及自动编码器两种方法...

weixin_39712455的博客 1175

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: 算法小白的第一次尝试---DBCSAN实现(手撕)
下一篇: 算法小白的第一次尝试---LDA(线性判别分析)降维 【适用于任何维度】
小糖宝
博客等级 码龄9年 47粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值