Spark - 数据倾斜实战之 skewness 偏度与 kurtosis 峰度 By ChatGPT4
目录
一.引言
二.峰度 Skewness 简介
三.峰度 kurtosis 简介
四.Skewness 偏度与 kurtosis 峰度实现
1.Spark 实现
2.自定义实现
五.偏度、峰度绘图
1.偏度 Hist Plot
2.峰度 Hist Plot
六.总结
一.引言
前面 Flink 数据倾斜实战中我们学习了 Flink keyBy 的 Hash 实现算法并提出了更加广义的倾斜数据校验方法,其中一种是利用原有 Hash 算法进行遍历并得到分区分布,鉴于最近 ChatGPT4 非常火爆,于是我们也尝试学习下 Spark 面对倾斜数据如何统计处理,所以便有了下述结果:
不得不说给出的方法非常全面且靠谱,最后一个方法中给出了 Skewness 算子检测数据倾斜,Skewness 偏度算子和 kurtosis 峰度算子都是 SparkSql 的 Agg 算子,既然 ChatGPT4 建议了,下面我们就学习一下。
二.峰度 Skewness 简介
偏度是统计数据分布倾斜方向和程度的度量,又称偏态、偏态系数。其表征概率分布密度曲线相对于平均值不对称程度的特征数,直观看就是密度函数曲线尾部的相对长度。偏度定义为:
其中 k2、k3 分别代表二阶和三阶中心距。
正态分布的偏度为0,两侧尾部长度对称。以 S 代表偏度,S < 0 代表负偏离,也称左偏态,反之如果 S > 0 则代表正偏态,也称右偏态,如果 S ≈ 0 则可以认为分布是均匀的。由于左右偏态的图形特点和我们的视觉直观不符合,所以经常将左右偏态判断反,这里有一个好的办法区分,即观察分布的尾巴,哪边尾巴长,就是哪边的偏态分布。例如第一个正偏态的偏度 S > 0,我们可以观察到其右边的尾巴长。
Tips:
右偏分布 - 平均数 > 中位数 > 众数
左偏分布 - 众数 > 中位数 > 平均数
三.峰度 kurtosis 简介
本来 GPT 只告诉了 Skewness 偏度查看数据倾斜,但我看 SparkSQL 还有个 kurtosis 算子计算峰度,二者计算方法差别不大,一个三阶矩一个四阶矩所以本文也一并介绍了方便后续使用。风度,泛指一个人的言谈举止和仪态,一般有风度翩翩,哈哈被输入法搞跑题了,峰度又称峰态系数,表征概率密度分布曲线在平均值处峰值高低的特征数。峰度定义为:
其中 m4 是四阶样本中心距,m2 是二阶中心距即样本方差,这里减3是为了让正态分布峰度为0。
峰度值 K 如果大于 0,则称为尖峰态而如果 K 小于 0 则称为低峰态,从图中可以看到 K 越大其均值处的尖度越尖。
四.Skewness 偏度与 kurtosis 峰度实现
1.Spark 实现
- 初始化 SparkSession
val conf = (new SparkConf).setMaster("local[*]").setAppName("SparkSQLAgg")val spark = SparkSession.builder.config(conf).getOrCreate()val sc = spark.sparkContext
- 构建随机数据
使用 random 构建随机数据,这里 0-50 的数据会比 50-100 的数据多,所以 50-100 即后面的尾巴长,所以是右偏分布即正偏态,从而可知 S > 0。
val dataBuffer = new ArrayBuffer[Double]()val random = scala.util.Random(0 to 100000).foreach(num => {if (num < 50000) {dataBuffer.append(100 * random.nextDouble())} else {dataBuffer.append(50 * random.nextDouble())}})
- 计算偏度与峰度
将上面的模拟数据生成 DataFrame,直接 agg 调用聚合函数获取统计值,可以看到偏度 > 0 符合我们上面的预期,大家可以修改上面的自定义数据,查看偏度的变化。
val sqlContext = new SQLContext(sc)import sqlContext.implicits._val skewRDD = sc.parallelize(dataBuffer)val skewDF = skewRDD.toDF("key1")// key1、key2 为计算 Skewness 的列名,Skewness 会返回一个 DataFrame 算子,其中包含各列的 Skewness 的值val skewnessValues = skewDF.agg(avg("key1"), stddev_pop("key1"), var_pop("key1"), skewness("key1"), kurtosis("key1"))skewnessValues.show()
2.自定义实现
基于 spark.sql.functions 和定义公式,我们也可以自己实现偏度和峰度的代码:
- 偏度
/*skewness_pop = E [((X - mu_pop) / stddev_pop) ^ 3]X: the random variablemu_pop: population meanstddev_pop: population standard deviationsqrt(n) * m3 / sqrt(m2 * m2 * m2)where if m refers to (X - mu), then m2 refers to (X - mu)^2 and m3 refers to (X - mu)^3.skewness_samp = SUM(i=1 to n) [(xi - mu_samp) ^ 3] / n--------------------------------------stddev_samp ^ 3*/def calculateSkewness(df: DataFrame, column: String): Double = {val mean = calculateMean(df, column)val stdDev = calculateStdDev(df, column)val totalNum = df.count()val thirdCentralSampleMoment = df.agg(functions.sum(functions.pow(functions.column(column) - mean, 3) / totalNum)).head.getDouble(0)val thirdPowerOfSampleStdDev = scala.math.pow(stdDev, 3)thirdCentralSampleMoment / thirdPowerOfSampleStdDev}
- 峰度
/*kurtosis_pop = E [((X - mu_pop) / stddev_pop) ^ 4]excess_kurtosis_pop = kurtosis_pop - 3.0X: the random variablemu_pop: population_meanstddev_pop: population standard deviationn * m4 / (m2 * m2) - 3.0where if m refers to (X - mu), then m2 refers to (X - mu)^2 and m4 refers to (X - mu)^4.kurtosis_samp = SUM(i=1 to n) [(xi - mu_samp) ^ 4] / n--------------------------------------stddev_samp ^ 4excess_kurtosis_samp = kurtosis_samp - 3.0*/def calculateExcessKurtosis(df: DataFrame, column: String): Double = {val mean = calculateMean(df, column)val stdDev = calculateStdDev(df, column)val totalNum = df.count()val fourthCentralSampleMoment = df.agg(functions.sum(functions.pow(functions.column(column) - mean, 4) / totalNum)).head.getDouble(0)val fourthPowerOfSampleStdDev = scala.math.pow(stdDev, 4)(fourthCentralSampleMoment / fourthPowerOfSampleStdDev) - 3}
- 辅助函数
细心的同学可能会发现有 xxx_pop 和 xxx_samp 这样后缀的 agg 聚合统计函数,这里 pop 的计算基于完整数据,samp 的计算基于采样数据,如果大家数据量且只追求相对准确的结果可以选择 _samp 在损失一些精度的情况下提高速度。
def calculateMean(df: DataFrame, column: String): Double = {df.agg(avg(column)).head.getDouble(0) // 均值}def calculateVar(df: DataFrame, column: String): Double = {df.agg(var_pop(column)).head.getDouble(0) // 方差}def calculateStdDev(df: DataFrame, column: String): Double = {df.agg(stddev_pop(column)).head.getDouble(0) // 标准差}
- 计算测试
val selfSkewness = calculateSkewness(skewDF, "key1")val selfKurtosis = calculateExcessKurtosis(skewDF, "key1")println(s"Skewness: ${selfSkewness} Kurtosis: ${selfKurtosis}")
根据公式自定义的计算结果与官方 API 结果一致:
五.偏度、峰度绘图
上面计算出模拟的数据偏度 S > 0 为右偏态即右边尾巴长,K < 0 为低峰态即尖峰程度小于正态分布,这里懒得把数据带到 python 画图了,所以使用 scala 的统计与画图工具 breeze.plot._,使用前需先引入依赖,这里对应 scala 2.11 版本:
<!-- https://mvnrepository.com/artifact/org.scalanlp/breeze-viz --><dependency><groupId>org.scalanlp</groupId><artifactId>breeze-viz_2.11</artifactId><version>1.0-RC2</version></dependency>
1.偏度 Hist Plot
import breeze.plot._ def plotHistogram(data: Array[Double]): Unit = {val f = Figure()val p = f.subplot(0)// 加入当前数据分布p += hist(data, 100)p.xlabel = "X-Axis"p.ylabel = "Y-Axis"f.saveas("./histogram.png")}
将原始数据 rdd 采样获得数据传入 plotHistogram 即可得到对应数据分布,可以看到右边尾巴长,满足 S > 0 的正偏态即右偏分布。
2.峰度 Hist Plot
def plotHistogram(data: Array[Double]): Unit = {val f = Figure()val p = f.subplot(0)// 加入当前数据分布p += hist(normalization(data), 100)// 加入正态分布val g = breeze.stats.distributions.Gaussian(0, 1)p += hist(g.sample(data.length),100)p.xlabel = "X-Axis"p.ylabel = "Y-Axis"f.saveas("./histogram.png")}
将数据归一化,再加入一部分 N(0, 1) 的正态分布数据,其中蓝色为原始数据归一化后的分布,K < 0,此时状态为低峰态。
六.总结
之前虽然有过 Spark 数据倾斜的实战经验且学习数理统计期间也学到过偏度与峰度的概念,但是没有想过把这些统计概念应用到数据倾斜分析的实战中,也正是在 ChatGPT4 的提示下才回忆起过往的知识,上面一些实现的代码也是 ChatGPT4 给出,不得不感叹现在 AI 技术发展的迅速,作为程序员的大伙还是要努力提升自己呀,成为那个不可替代的角色。
Spark - 数据倾斜实战之 skewness 偏度与 kurtosis 峰度 By ChatGPT4相关推荐
- spark+数据倾斜+解决方案
spark+数据倾斜+解决方案 1.如何判断数据切斜的发生源头? 根据stage划分原理和sparkUI 2.数据倾斜解决方案 解决方案一:使用Hive ETL预处理数据
- Spark数据倾斜的完美解决
数据倾斜解决方案 数据倾斜的解决,跟之前讲解的性能调优,有一点异曲同工之妙. 性能调优中最有效最直接最简单的方式就是加资源加并行度,并注意RDD架构(复用同一个RDD,加上cache缓存).相对于前面 ...
- Spark数据倾斜解决方案(转)
本文转发自技术世界,原文链接 http://www.jasongj.com/spark/skew/ Spark性能优化之道--解决Spark数据倾斜(Data Skew)的N种姿势 发表于 2017 ...
- Spark数据倾斜优化
Spark数据倾斜 就是数据分到各个区的数量不太均匀,可以自定义分区器,想怎么分就怎么分. Spark中的数据倾斜问题主要指shuffle过程中出现的数据倾斜问题,是由于不同的key对应的数据量不同导 ...
- 解决Spark数据倾斜(Data Skew)的 N 种姿势 与 问题定位
Spark性能优化之道--解决Spark数据倾斜(Data Skew)的N种姿势 本文结合实例详细阐明了Spark数据倾斜的问题定位和几种场景以及对应的解决方案,包括避免数据源倾斜,调整并行度,使用自 ...
- Spark 数据倾斜介绍_大数据培训
Spark 数据倾斜 Spark中的数据倾斜问题主要指shuffle过程中出现的数据倾斜问题,是由于不同的key对应的数据量不同导致的不同task所处理的数据量不同的问题. 例如,reduce点一共要 ...
- Spark数据倾斜解决方案(收藏级)
一.数据倾斜表现 数据倾斜就是数据分到各个区的数量不太均匀,可以自定义分区器,想怎么分就怎么分. Spark中的数据倾斜问题主要指shuffle过程中出现的数据倾斜问题,是由于不同的key对应的数据量 ...
- hive解决数据倾斜问题_八种解决 Spark 数据倾斜的方法
有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能. 数 ...
- Spark数据倾斜-采样倾斜key并分拆join操作-详细图解与代码
本文修改自[1]中的方案六. 下面的方案简述来自[1] 方案适用场景:两个RDD/Hive表进行join的时候,如果数据量都比较大,无法采用"解决方案五",那么此时可以看一下两个R ...
最新文章
- 经典大数据面试题及解析
- 网上复制代码需谨慎,莫名其妙报错看这里!
- 双网卡绑定-bond0
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
- DL之yolov3:使用yolov3算法时需要对Ubuntu系统进行配置的简介、过程步骤之详细攻略
- javascript权威指南--学习笔记
- 服务器 ha linux,Linux 高可用(HA)集群之Heartbeat详解
- mysql 异步 同步 不支持_MySQL C#异步方法不起作用?
- 从零开始学习音视频编程技术(四) FFMPEG的使用
- mysql表空间_浅谈mysql中各种表空间(tablespaces)的概念
- 客户引导你,还是你引导客户?
- 机顶盒网络包获取方式
- 2022-08-19 mysql/stonedb-索引优化专利交底书-改进点
- 3.3 RESET and Initialization Procedure
- OpenFOAM多孔介质模型_DarcyForchheimer
- 【Codeforces】 B. Make it Divisible by 25
- 在百度地图上展示dwg/dxf
- 华为云obs上传文件
- 热烈欢迎深创投集团领导莅临联诚发考察指导工作
- 关于在写代码时如何使用绝对路径与相对路径及其简单介绍