系列Sparkml学习(1)—基础统计部分
系列Sparkml学习(1)—Basic Statistics
文章目录
一、Correlation(相关性计算)
作用:用于计算不同列之间的相似度(前提是每列是一个完整的向量),也就是计算向量之间的相关性;
1.官网scala代码(scala版本)
import org.apache.spark.ml.linalg.{Matrix, Vectors}
import org.apache.spark.ml.stat.Correlation
import org.apache.spark.sql.Row
val data = Seq(
Vectors.sparse(4, Seq((0, 1.0), (3, -2.0))),
Vectors.dense(4.0, 5.0, 0.0, 3.0),
Vectors.dense(6.0, 7.0, 0.0, 8.0),
Vectors.sparse(4, Seq((0, 9.0), (3, 1.0)))
)
val df = data.map(Tuple1.apply).toDF("features")
val Row(coeff1: Matrix) = Correlation.corr(df, "features").head
println(s"Pearson correlation matrix:\n $coeff1")
val Row(coeff2: Matrix) = Correlation.corr(df, "features", "spearman").head
println(s"Spearman correlation matrix:\n $coeff2")
2.官网scala代码解读
(1) ml的linalg及所属的Matrix和Vectors
spark.ml.linalg,顾名思义,数值计算库,除此之外,数值计算库好像还有breeze.linalg,com.github.fommil.netlib,为什么这个库里面会有Vector,Vectors,SparseVector以及DenseVector之类的类,个人理解,熟悉Tensorflow这些深度框架的朋友应该了解,有个很重要的名次——张量,统一数据格式是一件肯定要做的事情,就好比spark后续只会维护以Dataframe为Input的ml库而逐渐放弃维护以RDD为Input的mllib库,虽然说不管是spark sql还是dataframe,低层还是转化成RDD进行操作,
但是统一数据格式用起来方便啊;
(2) ml.stat库及主人公Correlation
stat(Statistics的缩写),说白了就是spark的统计库,计算向量相关性,属于统计范畴嘛,这个很好理解;
(3) spark.sql.Row
前文中有提到RDD和Dataframe之间的关系,sparksql查询得到的数据为Dataframe类型,需要映射为RDD[Row]格式进行复杂操作,我们是不是可以理解为,Row代表数据中的每一条(行)数据,我们经常要将Dataframe转化为RDD进行map操作,那map就是基于Row的,其本身继承自Serializable,可以get,getInt,getDouble等等;
(4) Seq
scala集合三大类之一,其余两个为Map和Set,熟悉Python的朋友可以结合list,tuple和set来理解;
(5) dense和sparse
dense好理解,稠密特征,每个维度基本上都有值,官网demo也是四条(列)数据都敲出来了,0.0也给了,关键是sparse也就是离散特征,什么鬼,怎么还得分别得指定num为4,Seq集合里面又是什么,相当于说,有4个值,第0个值为1.0,第3个值为-2.0,其他的全部为0.0,这样理解,稀疏特征,本来就很多0嘛,数量多的情况下,指定不为0的几个位置的值,剩下的全都是0;
(6) Correlation.corr
计算任意两列之间的关联性,默认使用皮尔逊相关系数算,也可以指定用spearman,结果是一个N*N维的矩阵(Matrix类型),这里的N是
列数,结果是一个对角矩阵,对角线元素全部为1,自己跟自己的相关系数均为1;
(7) toDF()
初始化spark——>val spark = SparkSession.builder().getOrCreate(),然后import spark.implicits._启用隐式转换就可以用啦;
二、Hypothesis testing(假设检验)
作用:用于根据有标签的多条数据看各个维度特征的重要性,也就是独立性测试;
1.官网scala代码(scala版本)
import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.ml.stat.ChiSquareTest
val data = Seq(
(0.0, Vectors.dense(0.5, 10.0)),
(0.0, Vectors.dense(1.5, 20.0)),
(1.0, Vectors.dense(1.5, 30.0)),
(0.0, Vectors.dense(3.5, 30.0)),
(0.0, Vectors.dense(3.5, 40.0)),
(1.0, Vectors.dense(3.5, 40.0))
)
val df = data.toDF("label", "features")
val chi = ChiSquareTest.test(df, "features", "label").head
println(s"pValues = ${chi.getAs[Vector](0)}")
println(s"degreesOfFreedom ${chi.getSeq[Int](1).mkString("[", ",", "]")}")
println(s"statistics ${chi.getAs[Vector](2)}")
2.官网scala代码解读
(1) ChiSquareTest.test
指定哪一列是标签哪一列是特征就好了,其他的看Correlation部分的代码解读就OK啦;
(2) 结果含义分析
pValues = [0.6872892787909721,0.6822703303362126]
degreesOfFreedom [2,3]
statistics [0.75,1.5]
分别打印了pValues(评测值),degreesOfFreedom(*度)和statistics,其中评测值越小对标签的区分作用越大,*度+1等于该特征有多少个不同的值,statistics处理逻辑比较复杂,反正值越小分类价值越低;
三、Summarizer
这应该是3.X版本加的吧,小编本人所在公司目前用的大数据平台是阿里云的ODPS,Spark版本为2.3.0,这里就不介绍了,感兴趣的同学自己上官网看一下吧—Spark3.1.2-Basic Statistics
参考
Spark ML基本算法【ChiSquareTest卡方检验】
pyspark.ml.linalg模块之Vector,Vectors,SparseVector,DenseVector详细解析
总结
取人之长,补己之短,每天进步一点点!