算法小白的第一次尝试---LDA(线性判别分析)降维 【适用于任何维度】

线性判别分析(LDA)实战:从原理到sklearn降维应用 本文详细介绍了线性判别分析(LDA)的原理及其在sklearn中的实战应用,涵盖从基础概念到高级技巧的全流程。通过对比PCA等降维方法,突出LDA在有监督分类任务中的优势,并提供代码示例和常见问题解决方案,帮助读者快速掌握这一机器学习工具。 阅读详情
-------------------------------------------------------------------------------------
笔者追求算法实现,不喜欢大篇幅叙述原理,有关LDA(线性判别分析)理论推荐查看该篇博客

https://www.cnblogs.com/pinard/p/6244265.html
-------------------------------------------------------------------------------------

import breeze.linalg.DenseMatrix
import org.apache.log4j.{Level, Logger}
import org.apache.spark.ml.feature.{LabeledPoint,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 is Linear discriminant analysis  which can be used to
  * lower the dimension of linear dataset
  *  Data Source :http://archive.ics.uci.edu/ml/datasets/Wine
  * @author XiaoTangBao
  * @date 2019/4/24 10:32
  * @version 1.0
  */
object LDA {
  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,启动LDA算法
    val newdf = vectorAsb.transform(oridf).select("label","features")
    val rpg = run(newdf,2)
    val arr = ArrayBuffer[(Double,Double)]()
    for(i<-0 until rpg.cols) arr.append((rpg(0,i),rpg(1,i)))
    arr.foreach(tp =>println(tp._1))
    println()
    arr.foreach(tp =>println(tp._2))
  }

  /**
    * Entrance of modeltraining
    * @param df trainData with only two columns such as label and features
    * @param nb the dimensions of the traindata after
    */
 def run(df:DataFrame,nb:Int)={
    //数据标准化处理
	//   val stdf = new StandardScaler().setInputCol("features").setOutputCol("Scaledfeatures")
	//     .setWithMean(true).setWithStd(true).fit(df).transform(df)
	//     .select("label","Scaledfeatures")
	//     .withColumnRenamed("Scaledfeatures","features")
     
   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)
   import breeze.linalg._
   //存放向量各维度的均值
   val big_mean = sum(big_Matrx,Axis._1).*= (1.0 / big_Matrx.cols)
   //总的类别
   val allLabel = labels.distinct
   //类内散度矩阵
   val Sw_Arr = ArrayBuffer[DenseMatrix[Double]]()
   //类间散度矩阵
   val Sb_Arr = ArrayBuffer[DenseMatrix[Double]]()
   for(i<-0 until allLabel.length){
     //该类别下的总记录数
     val record = labArr.filter(lab => lab.label == allLabel(i)).size
     val sk = labArr.filter(lab => lab.label == allLabel(i)).map(lab => lab.features)
       .map(vec => vec.toArray).flatMap(x => x).toArray
     var d1 = new DenseMatrix[Double](tz,record,sk)
     //存放向量各维度的均值
     val cols_mean = sum(d1,Axis._1).*= (1.0 / d1.cols)
     //样本去中心化
     for(i<-0 until d1.cols){
        d1(::,i) := d1(::,i) - cols_mean
     }
     //类内散度矩阵
     val sw = d1 * (d1.t)
      Sw_Arr.append(sw)
     //类间散度矩阵
     val zf = (cols_mean - big_mean).toDenseMatrix.t
     val sb = record.toDouble * zf * zf.t
     Sb_Arr.append(sb)
   }
   //总类内散度矩阵
   var total_Sw = DenseMatrix.zeros[Double](tz,tz)
   for(i<-0 until Sw_Arr.length) total_Sw = total_Sw + Sw_Arr(i)
   //总类间散度矩阵
   var total_Sb = DenseMatrix.zeros[Double](tz,tz)
   for(i<-0 until Sb_Arr.length) total_Sb = total_Sb + Sb_Arr(i)

   //计算类内散度和类间散度矩阵乘积
   val Sw_Sb = inv(total_Sw) * total_Sb
   //计算Sw_Sb矩阵特征值及特征向量
   val eigValues = eig(Sw_Sb).eigenvalues
   val eigVectors = eig(Sw_Sb).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)
   }
  //rt表示最终选取的特征向量矩阵
   val result = da.sortBy(labPoint => labPoint.label).reverse.take(nb).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 lastData = rt * big_Matrx
   lastData
 }
}

根据实验结果数据绘制图像如下图所示:
Java_Man_China
该结果与Python 直接调取LDA方法结果相差较大(横纵坐标不一致):

数据标准化处理后,发现两者结果(横纵坐标 + 形状)完全一致。
Java_Man_China
实验结果表明,笔者的算法完全正确。

dimensionality_reduction_alo,PCA、LDA、MDS、LLE、TSNE等降维算法的python实现 PCA、LDA、MDS、LLE、TSNE等降维算法的python实现 立即下载

相关推荐

Binary Fisher LDA:这个包在 Matlab 和 Java 中实现了二元 Fisher 线性判别分析-matlab开发

该软件包包括 Fisher LDA 的培训、测试和演示。 测试代码还评估精度、召回率、准确度和 F1 度量。

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

import breeze.linalg.{Axis, DenseMatrix, eigSym, sum} import org.apache.log4j.{Level, Logger} ...

Java_Man_China的博客 1万+

LDA的JAVA版本

这是采用吉布斯采用的LDA,是Java语言实现的LDA,里面含有测试数据,对初学者有一定的帮助。

主题模型LDA浅析:入门、Java实现以及测试案例

一、什么是主题模型 假如有一篇文章text,通过里面的词,来确定他是什么类型的文章,如果文章中出现很多算法类的词,比如,“SVM”、“贝叶斯分类”之类的,那么主题模型就会把它划分为算法类的文章。 假如该文章的主题并不单一,文中80%在讲算法,20%稍微讲了下在分词中的应用。因为涉及到中文分词,又被归入了分词类的文章。 传统的文本分类器,比如贝叶斯、kNN和SVM,只能将其分到一个确定的类别中。假设给出3个分类“算法”“分词”“文学”让其判断,如果某个分类器将该文归入算法类,结果还算说得过去,.

熬过万丈孤独,藏下星辰大海 5933

JAVA版LDA主题模型

自然语言处理经典算法主题模型的JAVA版本,内含语料,可直接运行。

LDA主题发现java源码

原作者分析的是英文,我只是在此基础上添加了IK分词,使其能够实现中文主题发现,原作者有详细介绍理论和源码(http://blog.youkuaiyun.com/yangliuy/article/details/8457329),具体相关的文档请到原版作者查阅。谢谢!

基于sparkMLlib的机器学习_[1]_基本数据类型[2]向量标签LabeledPoint

向量标签作用:标识不同值 1:直接静态生成向量标签 标记点 内容 2:文件API生成 loadLibSVMFile 格式:(标签,稀疏向量) 1)索引要从1开始,从0开始的时候生成的内部索引时从-1开始,而且数据长度会比实际少1; 2)数据的长度是以最大列数为准的,因此最好是要保持数据列数一致; 3)标签列可以重复 相关资料: 生成libSVM的数据格式及使用方法总结:点

hjw199089的博客 6622

Vivado实战:AXI转PCIe IP核配置全流程(含性能优化技巧)

本文详细介绍了在Vivado环境中配置AXI转PCIe IP核的全流程,包括工程准备、IP核参数设置、BAR空间配置、中断系统优化以及TLP传输效率提升等关键步骤。特别分享了经过验证的性能优化技巧,帮助开发者显著提升PCIe链路的吞吐量和稳定性,适用于视频采集、高速数据记录等应用场景。

weixin_30892037的博客 552

java lda主题模型_主题模型LDA:从入门到放弃

宏观理解LDA有两种含义线性判别器(Linear Discriminant Analysis)隐含狄利克雷分布(Latent Dirichlet Allocation,简称LDA)本文讲解的是后者,它常常用于浅层语义分析,在文本语义分析中是一个很有用的模型。LDA模型是一种主题模型,它可以将文档集中的每篇文档的主题以概率分布的形式给出,从而通过分析一些文档抽取出它们的主题(分布)出来后,便可以根据...

weixin_30941657的博客 501

棋牌App逆向工程实战:透视风险分析与反作弊加固思路

在移动应用安全领域,逆向工程是一项关键的攻防技术,它通过静态分析、动态调试与协议抓包等手段,深入还原客户端真实逻辑。这项技术的核心原理,是从已编译的安装包中提取数据流,验证服务端下发的信息是否超出了客户端应有的可见范围。从技术价值看,安全测试人员可以借此定位协议层、内存层与缓存层的潜在风险,为反作弊体系提供精准的加固建议。在棋牌类App等实时对局场景中,逆向工程常被用于排查牌局信息泄露类隐患,而合规授权与测试环境是开展此类研究的必要前提。本文结合一次棋牌App的安全评估实践,梳理了从环境准备到数据流还原的完

weixin_29326909的博客 176

BIOS更新后PIN不可用怎么办?从原理到实操的完整修复指南

在计算机维护中,BIOS更新是常见的固件升级操作,但其引发的登录异常却常让用户措手不及。Windows Hello PIN并非传统密码,它通过TPM芯片与设备启动环境(PCR状态)强绑定,一旦主板固件或安全启动配置改变,TPM便会拒绝释放密钥,导致“由于此设备上的更改,你的PIN不再可用”。理解这一原理后,恢复路径清晰可控:优先尝试密码登录,或通过WinRE替换utilman.exe创建临时管理员,必要时还需处理BitLocker恢复密钥。本文面向系统维护与数据安全场景,系统梳理PIN失效的恢复流程与避坑方

weixin_31364787的博客 384

Spark2.0机器学习系列之9: 聚类算法(LDA)

聚类算法 LDA Spark2.0代码

qq_34531825的博客 2万+

从AXI到CHI:深入解析基于Credit的流量控制如何优化NoC设计

本文深入解析了从AXI握手式流控到CHI基于Credit的流量控制机制的演进。通过对比传统流控的瓶颈,详细阐述了Credit机制如何通过信用预分配和记账系统,有效解决FIFO气泡、时序收敛等难题,从而优化NoC设计的带宽利用率、降低延迟并提升系统可扩展性。

weixin_29227585的博客 522

【机器学习】降维系列算法(PCA、LDA、NMF、LLE)

降维(Dimensionality Reduction)是机器学习中用来减少数据集特征数量的技术,其目的是在尽可能保留原始数据信息的同时降低数据的复杂度。降维不仅可以加速模型训练、减少计算资源消耗,还能帮助消除噪声、提高模型性能,并且有助于可视化高维数据。PCA 是一种线性降维方法,它通过找到一组新的正交基(主成分),将原始数据投影到这些新轴上。新的坐标系中的每个维度都是原始变量的线性组合,且各维度之间相互独立。PCA的目标是在尽可能少的维度上保留尽可能多的数据方差。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

Unity ProBuilder(自己创建斜面、拐角)

ProBuilder基础实例

weixin_56537692的博客 1551

数据治理路径之辩:从“先治后用”到“边用边治”,企业如何选择最优路径?

数据治理是企业在数智化建设中的核心挑战,主要涉及三种时序策略:先治理后使用、先用后治理和边用边治。先治理后使用强调在数据应用前建立完整的治理框架,适合高合规要求的行业,但可能响应滞后。先用后治理则优先释放数据价值,适合快速变化的业务环境,但可能累积数据质量问题。边用边治寻求动态平衡,通过持续改进实现治理与应用的同步迭代,适合复杂数据环境。技术选型决策矩阵和实施方法论提供了具体的操作指南,建议根据组织特性和业务需求选择适配方案,并通过渐进式演进路径实现治理与业务的共生演进。

石榴姐yyds 409

线性降维:PCA、LDA、MDS

降维1. KNN 1. KNN 为什么要在介绍降维之前学习KNN呢?因为通过对KNN的了解,可知,以KNN为代表的一类算法,由于本身为非参数化模型,无法使用例如在损失函数中加入正则表达式的之类的方法对某些维度信息进行约束,极易造成过拟合。 KNN是惰性学习算法的典型例子。惰性是指它仅仅对训练数据集有记忆功能,而不会从训练集中通过学习得到一个判别函数。惰性学习算法一般思想简单,且没有训练过程。相对应的则是急切学习, ...

WEILING123的博客 3081

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

XiaoqiangClub的博客 1万+

维度规约(PCA和LDA)

线性判别分析是一种基于有监督学习的降维方式, 将数据集在低维度的空间进行投影,要使得投影后的同类别的数据点间的距离尽可能的靠近,而不同类别间的数据点的距离尽可能的远。主成分分析是一种线性降维技术(以列来看),它将一组相关的 p 维变量转换为一组称为主成分的维度较低(如 k 维, k < p )的不相关变量,同时尽可能多地保留原始数据集中的变化。‌PCA的数学原理是基于最大投影方差法‌:通过正交变换将线性相关的特征转换为线性无关的特征,使得投影后的数据方差最大,从而保留更多的原始数据信息‌。

2301_79574624的博客 1063

“华为杯”研究生数学建模竞赛2020年-【华为杯】D题:无人机集群协同对抗(附获奖论文和MATLAB代码实现)

1.问题重述摘 要:本文针对非线性约束条件下红蓝双方无人机集群协同对抗的最优规划问题,结合贪婪队形、非线性规划、内点法、蒙特卡洛方法和全联立正交配置有限元法,构建了无人机集群协同对抗推演模型。,构建了。我们综合考虑了,和。首先分析红方在集群约束下的贪婪队形和拦截策略,然后我们基于内点法联合MATLAB和AMPL编程求解蓝方突防的非线性规划解,最后基于蒙特卡洛法对整个蓝方突防过程进行推演,得到突防概率图。通过推演,我们提出了两块的区域作为所求区域,并对蓝方的最优突防策略进行分析。

getusushu的博客 1553

Camera2Demo

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

降维算法(PCA/LDA/LLE/LEP/FA)总结

目录 1PCA/LDA 2Factor Analysis 3 LLE 4 LEP Reference 1PCA/LDA 参考我的这篇博文主成分分析(PCA)/线性判别分析(LDA)总结 2Factor Analysis FA 的思想与 PCA 其实很相似,假设高维度上的观测结果 X 其实是由低维 度上的 factors 来支配的。打个比方,笔者身边有一大群妹子,每...

J~的博客 2176

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

深度神经网络——什么是降维?

什么是降维?降维是用于降低数据集维度的过程,采用许多特征并将它们表示为更少的特征。例如,降维可用于将二十个特征的数据集减少到仅有几个特征。降维通常用于无监督学习任务降维是一个用于降低数据集维度的过程,采用许多特征并将它们表示为更少的特征。例如,降维可用于将二十个特征的数据集减少到仅有几个特征。降维常用于从许多功能中自动创建类的任务。为了更好地理解,我们将了解与高维数据相关的问题以及最流行的降维方法。

知来者逆的博客 3208

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

DAY21 常见的降维算法

​:t-SNE 是一种强大的非线性降维技术,主要用于高维数据的可视化。它通过在低维空间中保持高维空间中数据点之间的局部相似性(邻域关系)来工作。与PCA关注全局方差不同,t-SNE 更关注局部细节。理解它的超参数(尤其是困惑度)和结果的正确解读方式非常重要。

Soyonagsaki_的博客 1133

【降维方法】- 线性判别分析(LDA)

参考:refenrence 简介 线性判别分析(Linear Discriminant Analysis)作为一种监督式的降维方法,同时也用作分类器,它主要思想是:使得对原空间进行投影运算后,类间的样本点数据分布间隔大,而类内样本点数据分布方差小。 原理 有了上述思想后,我们尝试着自己一步步把这个思想具体化。最近在看《数据之旅》,王教授提到学习数学需要重要培养的一个能力:抽象能力。 数学...

Step by step 1422

维度诅咒和降维(curse of dimension and dimension rduction)

常见的数据降维方法实现及可视化。在很多领域中,如采样、组合数学、机器学习和数据挖掘都有提及到这个名字的现象。这些问题的共同特色是当维数提高时,空间的体积提高太快,因而可用数据变得很稀疏。稀疏性对于任何要求有统计学意义的方法而言都是一个问题,为了获得在统计学上正确并且有可靠的结果,用来支撑这一结果所需要的数据量通常随着维数的提高而呈指数级增长。而且,在组织和搜索数据时也有赖于检测对象区域,这些区域中的对象通过相似度属性而形成分组。然而在高维空间中,所有的数据都很稀疏。

张哥频道:电生理信号和磁共振成像 2681

Day 21: 常见的降维算法

t-SNE 是一种强大的非线性降维技术,主要用于高维数据的可视化。它通过在低维空间中保持高维空间中数据点之间的局部相似性(邻域关系)来工作。与PCA关注全局方差不同,t-SNE 更关注局部细节。理解它的超参数(尤其是困惑度)和结果的正确解读方式非常重要。

lF1024的博客 854
上一篇: 算法小白的第一次尝试---PCA(主成分分析)降维【适合各种纬度数据】
下一篇: 算法小白的第一次尝试---KPCA(核主成分分析)降维【实例对比分析PCA、LDA和KPCA】
小糖宝
博客等级 码龄9年 47粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值