Spark一些常用的数据处理方法-2.MLlib基础统计方法

本文介绍了Spark MLlib中常用的数据处理方法,包括基础加载包、标准构造、矩阵操作、相关性分析、分层抽样、随机数据生成、核密度估计和假设检验等。相关性分析用于检验变量间的关系,分层抽样提供了精确的数据子集,随机数据适用于测试,而核密度估计则用于数据的概览表示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SparkMLlib中会经常对RDD用到统计方法,其用法如下

2.1 基础加载包


//向量
import org.apache.spark.mllib.linalg.Vector

//向量集
import org.apache.spark.mllib.linalg.Vectors

//稠密向量
import org.apache.spark.mllib.linalg.DenseVector

//实例
import org.apache.spark.mllib.stat.{MultivariateStatisticalSummary, Statistics}

//矩阵
import org.apache.spark.mllib.linalg.{Matrix, Matrices}

//索引矩阵
import org.apache.spark.mllib.linalg.distributed.RowMatrix

//RDD
import org.apache.spark.rdd.RDD

2.2 标准构造


//创建一个RDD[Vector]
val rdd1 = sc.parallelize(Array(Array(1.0, 2.0, 3.0, 4.0), Array(2.0, 3.0, 4.0, 5.0), Array(3.0, 4.0, 5.0, 6.0))).map(f => Vectors.dense(f))
val rows: RDD[Vector] = rdd1

//或者创建一个矩阵将这个矩阵转化
def toRDD(m: Matrix): RDD[Vector] = {
val columns = m.toArray.grouped(m.numRows)
val rows = columns.toSeq.transpose
val vectors = rows.map(row => new DenseVector(row.toArray))
sc.parallelize(vectors)
}

//将这个RDD转变为MultivariateStatisticalSummary实例
val summary:MultivariateStatisticalSummary = Statistics.colStats(rdd1)

//这个实例可以调用以下方法
summary.mean//均值
summary.variance//方差
summary.numNonzeros//非零统计量个数
summary.count//总数
summary.max//最大值
summary.min//最小值
//返回值均为向量
//若为RDD[Double],则可以调用以下统计方法
//统计结果查看doublerdd.stats
//计数doublerdd.count
//平均数doublerdd.mean
//方差doublerdd.variance
//标准差doublerdd.stdev
//最大值doublerdd.max
//最小值doublerdd.min

2.3 标准矩阵


//密集矩阵
val dm:Matrix = Matrices.dense(3,2,Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))
//稀疏矩阵
val sm:Matrix = Matrices.sparse(3,2,Array(0,1,3), Array(0,2,1), Array(9,6,8))

2.4 相关性

相关性是对变量之间相关程度的检验,值介于-1~1之间,越接近-1或1越可以进行线性拟合。

//皮尔森相关系数(默认)检验
//先导包
import org.apache.spark.mllib.stat.Statistics
//矩阵sm见1.3, toRDD方法见1.2
def toRDD(m: Matrix): RDD[Vector] =.......
val dm:Matrix = ......
//构造一个RDD[Vector]
val rdd1 = toRDD(sm)
//检验
val correlMatrix:Matrix = Statistics.corr(rdd1)
//或者
val correlMatrix:Matrix = Statistics.corr(rdd1,"pearson")
//若用斯皮尔曼等级相关系数
val correlMatrix:Matrix = Statistics.corr(rdd1,"spearman")
//以上结果返回的都是一个矩阵,反映数值之间的相关性,如果差别较大可以看的很明显
//若比较两个向量,如
val rdd2 = sc.parallelize(Array(170.0, 150.0, 210.0,180.0,160.0))
val rdd3 = sc.parallelize(Array(180.0, 165.0, 190.0,168.0,172.0))
val correlationPearson = Statistics.corr(rdd2, rdd3)
//则可以得到唯一的一个Double结果,用于判断相关性,往往用于某种行为和某一结果的比较,且数据量需要最起码大于2个才具备意义。由于该系数运算准确度与数据量相关,数据量较少或较多均会造成准确度下降,故而需要选取适当的数据集合进行运算。correlationPearson 的绝对值分类有如下规则。
//0.8-1.0 极强相关
//0.6-0.8 强相关
//0.4-0.6 中等程度相关
//0.2-0.4 弱相关
//0.0-0.2 极弱相关或无相关

2.5 分层抽样

Spark中的分层抽样有两种,一种是掷币抽样sampleByKey,另一种是提供置信度达到99.99%的精确抽样sampleByKeyExact(也就是说样本几乎可以完全代表数据集本身,只是数量少一点而已)。这个方法针对的是键值对RDD,即RDD[(K,V)]

//先导包
import org.apache.spark.rdd.PairRDDFunctions
//创建一个键值对
val data = sc.textFile("path").map(func)
//创建一个储存抽样的Map,并设定取样规则,如二八准则
val fractions: Map[Int, Double] = (List((1, 0.2), (2, 0.8))).toMap
//获取抽样,样本之间是不重复的
val approxSample =data.sampleByKey(withReplacement = false, fractions)
//精确抽样,样本之间是不重复的,时间效率较高,但更具代表性
val exactSample =data.sampleByKeyExact(withReplacement = false, fractions)

2.6 随机数据

随机数据一般用于运算测试,MLlib支持的分布类型包括均匀分布、泊松分布、标准正态分布,结果可以是Double或者Vector。

//先导包
import org.apache.spark.mllib.random.RandomRDDs._
import org.apache.spark.{SparkConf, SparkContext}
//关闭默认sc
sc.stop
//重新构建sc
val conf = new SparkConf().setMaster("local[4]").setAppName(this.getClass().getSimpleName().filter(!_.equals('$')))
val sc = new SparkContext(conf)
//标准正态分布N(0,1) 其中中间的10表示10个,后面的10表示分区数,可以不写
val ndrdd= normalRDD(sc, 10, 10)
//正态分布N(1,4)
val ndrdd2 = ndrdd.map(x => 1.0 + 2.0 * x)
//泊松分布
val psrdd = poissonRDD(sc, 10, 10)
//均匀分布
val ufrdd = uniformRDD(sc, 10, 10)
//指数分布
val eprdd= exponentialRDD(sc,10, 10)
//伽马分布
val gmardd = gammaRDD(sc, 3,3,10)
//对数正态分布
val logrdd = logNormalRDD(sc, 0, 2, 10)

2.7 核密度估计

SparkMLlib中的核密度估计用的是最简单的“高斯核函数”,原理部分不谈了,以后写ML库的时候再说。简单理解这个概念呢,说用一组特征数来表达所有数据,那么这组特征数所能代表的密度,即概率大概是多少。这个在热点图中比较经常用到。

//还是先加载包
import org.apache.spark.mllib.stat.KernelDensity
//加载数据,此处用1.4的rdd2
val rdd2 =......
//加载数据,设置标准差
val kd = new KernelDensity().setSample(rdd2).setBandwidth(rdd2.stdev)
//设置坐标值,求密度
val densities = kd.estimate(Array(140.0, 170.0, 200.0, 230.0))

2.8 假设检验

假设检验一般用于判断一组数据或者向量是否符合假定的分布情况,或者比较两组数据是否具有相同的分布情况,或者数据之间是否具有关联

//先导包,还是统计包
import org.apache.spark.mllib.stat.Statistics
//显著性检验:测试一下两个向量是否同一分布
val land1 = Vectors.dense(1000.0, 1856.0)
val land2 = Vectors.dense(400, 560)
val c1 = Statistics.chiSqTest(land1, land2)
//其结果返回pValue = 5.536682223805656E-13,说明其显著性非常小,分布几乎是相同的,若这个值大于0.05,则说明差异较大。
//独立性检验,先构建两个向量
val v1:Vector = Vectors.dense(1.0, 2.0, 3.0, 4.0, 5.0)
val v2:Vector = Vectors.dense(2.0, 4.0, 6.0, 8.0, 10.0)
//将前者作为样本,后者作为期望,检验
val a =Statistics.chiSqTest(v1, v2)
//得到结果pValue = 1.0,说明几乎无差别。一般p值若非常小,则证明两组数据是相关的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值