在spark mllib 1.1加入版本stat包,其中包括一些统计数据有关的功能。本文分析中卡方检验和实施的主要原则:

一个、根本

  在stat包实现Pierxunka方检验,它包括以下类别

    (1)适配度检验(Goodness of Fit test):验证一组观察值的次数分配是否异于理论上的分配。

    (2)独立性检验(independence test) :验证从两个变量抽出的配对观察值组是否互相独立(比如:每次都从A国和B国各抽一个人,看他们的反应是否与国籍无关)

  计算公式:

    当中O表示观測值,E表示期望值

  具体原理能够參考:http://zh.wikipedia.org/wiki/%E7%9A%AE%E7%88%BE%E6%A3%AE%E5%8D%A1%E6%96%B9%E6%AA%A2%E5%AE%9A

二、java api调用example

  https://github.com/tovin-xu/mllib_example/blob/master/src/main/java/com/mllib/example/stat/ChiSquaredSuite.java

三、源代码分析

  1、外部api

    通过Statistics类提供了4个外部接口  

// Goodness of Fit test
def chiSqTest(observed: Vector, expected: Vector): ChiSqTestResult = {
ChiSqTest.chiSquared(observed, expected)
}
//Goodness of Fit test
def chiSqTest(observed: Vector): ChiSqTestResult = ChiSqTest.chiSquared(observed) //independence test
def chiSqTest(observed: Matrix): ChiSqTestResult = ChiSqTest.chiSquaredMatrix(observed)
//independence test
def chiSqTest(data: RDD[LabeledPoint]): Array[ChiSqTestResult] = {
ChiSqTest.chiSquaredFeatures(data)
}

  2、Goodness of Fit test实现

  这个比較简单。关键是依据(observed-expected)2/expected计算卡方值

 /*
* Pearon's goodness of fit test on the input observed and expected counts/relative frequencies.
* Uniform distribution is assumed when `expected` is not passed in.
*/
def chiSquared(observed: Vector,
expected: Vector = Vectors.dense(Array[Double]()),
methodName: String = PEARSON.name): ChiSqTestResult = { // Validate input arguments
val method = methodFromString(methodName)
if (expected.size != 0 && observed.size != expected.size) {
throw new IllegalArgumentException("observed and expected must be of the same size.")
}
val size = observed.size
if (size > 1000) {
logWarning("Chi-squared approximation may not be accurate due to low expected frequencies "
+ s" as a result of a large number of categories: $size.")
}
val obsArr = observed.toArray
  // 假设expected值没有设置,默认取1.0 / size
val expArr = if (expected.size == 0) Array.tabulate(size)(_ => 1.0 / size) else expected.toArray   / 假设expected、observed值都必需要大于1
if (!obsArr.forall(_ >= 0.0)) {
throw new IllegalArgumentException("Negative entries disallowed in the observed vector.")
}
if (expected.size != 0 && ! expArr.forall(_ >= 0.0)) {
throw new IllegalArgumentException("Negative entries disallowed in the expected vector.")
} // Determine the scaling factor for expected
val obsSum = obsArr.sum
val expSum = if (expected.size == 0.0) 1.0 else expArr.sum
val scale = if (math.abs(obsSum - expSum) < 1e-7) 1.0 else obsSum / expSum // compute chi-squared statistic
val statistic = obsArr.zip(expArr).foldLeft(0.0) { case (stat, (obs, exp)) =>
if (exp == 0.0) {
if (obs == 0.0) {
throw new IllegalArgumentException("Chi-squared statistic undefined for input vectors due"
+ " to 0.0 values in both observed and expected.")
} else {
return new ChiSqTestResult(0.0, size - 1, Double.PositiveInfinity, PEARSON.name,
NullHypothesis.goodnessOfFit.toString)
}
}
  // 计算(observed-expected)2/expected
if (scale == 1.0) {
stat + method.chiSqFunc(obs, exp)
} else {
stat + method.chiSqFunc(obs, exp * scale)
}
}
val df = size - 1
val pValue = chiSquareComplemented(df, statistic)
new ChiSqTestResult(pValue, df, statistic, PEARSON.name, NullHypothesis.goodnessOfFit.toString)
}

  3、independence test实现

    先通过以下的公式计算expected值,矩阵共同拥有 r 行 c 列

     

    然后依据(observed-expected)2/expected计算卡方值

/*
* Pearon's independence test on the input contingency matrix.
* TODO: optimize for SparseMatrix when it becomes supported.
*/
def chiSquaredMatrix(counts: Matrix, methodName:String = PEARSON.name): ChiSqTestResult = {
val method = methodFromString(methodName)
val numRows = counts.numRows
val numCols = counts.numCols // get row and column sums
val colSums = new Array[Double](numCols)
val rowSums = new Array[Double](numRows)
val colMajorArr = counts.toArray
var i = 0
while (i < colMajorArr.size) {
val elem = colMajorArr(i)
if (elem < 0.0) {
throw new IllegalArgumentException("Contingency table cannot contain negative entries.")
}
colSums(i / numRows) += elem
rowSums(i % numRows) += elem
i += 1
}
val total = colSums.sum // second pass to collect statistic
var statistic = 0.0
var j = 0
while (j < colMajorArr.size) {
val col = j / numRows
val colSum = colSums(col)
if (colSum == 0.0) {
throw new IllegalArgumentException("Chi-squared statistic undefined for input matrix due to"
+ s"0 sum in column [$col].")
}
val row = j % numRows
val rowSum = rowSums(row)
if (rowSum == 0.0) {
throw new IllegalArgumentException("Chi-squared statistic undefined for input matrix due to"
+ s"0 sum in row [$row].")
}
val expected = colSum * rowSum / total
statistic += method.chiSqFunc(colMajorArr(j), expected)
j += 1
}
val df = (numCols - 1) * (numRows - 1)
val pValue = chiSquareComplemented(df, statistic)
new ChiSqTestResult(pValue, df, statistic, methodName, NullHypothesis.independence.toString)
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

spark(1.1) mllib 源代码分析的更多相关文章

  1. Spark机器学习之MLlib整理分析

    友情提示: 本文档根据林大贵的<Python+Spark 2.0 + Hadoop机器学习与大数据实战>整理得到,代码均为书中提供的源码(python 2.X版本). 本文的可以利用pan ...

  2. Spark里边:Worker源代码分析和架构

    首先由Spark图表理解Worker于Spark中的作用和地位: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYW56aHNvZnQ=/font/5a6L ...

  3. Spark SQL 源代码分析系列

    从决定写Spark SQL文章的源代码分析,到现在一个月的时间,一个又一个几乎相同的结束很快,在这里也做了一个综合指数,方便阅读,下面是读取顺序 :) 第一章 Spark SQL源代码分析之核心流程 ...

  4. Spark MLlib之线性回归源代码分析

    1.理论基础 线性回归(Linear Regression)问题属于监督学习(Supervised Learning)范畴,又称分类(Classification)或归纳学习(Inductive Le ...

  5. Spark MLlib LDA 基于GraphX实现原理及源代码分析

    LDA背景 LDA(隐含狄利克雷分布)是一个主题聚类模型,是当前主题聚类领域最火.最有力的模型之中的一个,它能通过多轮迭代把特征向量集合按主题分类.眼下,广泛运用在文本主题聚类中. LDA的开源实现有 ...

  6. Spark SQL 源代码分析之 In-Memory Columnar Storage 之 in-memory query

    /** Spark SQL源代码分析系列文章*/ 前面讲到了Spark SQL In-Memory Columnar Storage的存储结构是基于列存储的. 那么基于以上存储结构,我们查询cache ...

  7. Spark SQL Catalyst源代码分析之TreeNode Library

    /** Spark SQL源代码分析系列文章*/ 前几篇文章介绍了Spark SQL的Catalyst的核心执行流程.SqlParser,和Analyzer,本来打算直接写Optimizer的,可是发 ...

  8. Spark SQL Catalyst源代码分析Optimizer

    /** Spark SQL源代码分析系列*/ 前几篇文章介绍了Spark SQL的Catalyst的核心运行流程.SqlParser,和Analyzer 以及核心类库TreeNode,本文将具体解说S ...

  9. Spark SQL源代码分析之核心流程

    /** Spark SQL源代码分析系列文章*/ 自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几 ...

随机推荐

  1. 返璞归真 asp.net mvc (3) - Controller/Action

    原文:返璞归真 asp.net mvc (3) - Controller/Action [索引页] [源码下载] 返璞归真 asp.net mvc (3) - Controller/Action 作者 ...

  2. 深入解析_Android的自定义布局

    前言: 这篇文章是前Firefox Android工程师(现在跳槽去Facebook了) Lucas Rocha所写,文中对Android中常用的四种自定义布局方案进行了很好地分析,并结合这四种And ...

  3. HR筒子说:程序猿面试那点事(转)

    小屁孩曾经有过4年的招聘经验,期间见识了各种类型的程序猿:有大牛.有菜牛:有功成名就,有苦苦挣扎不知方向.等后来做了一枚程序猿之后发现,HR眼中的程序猿和程序猿中的HR都是不一样的.有感与此,从HR的 ...

  4. 安装github for windows问题解决

    到官网下载windows环境下的github,在安装时出现下面问题 An error occurred trying to download 'http://github-windows.s3.ama ...

  5. 【C语言探索之旅】 第二部分第七课:文件读写

    内容简介 1.课程大纲 2.第二部分第七课: 文件读写 3.第二部分第八课预告: 动态分配 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏 ...

  6. 玩转Web之JavaScript(三)-----javaScript语法总结(三) 窗口/滚动条/文本的相关语法

    JS语法集锦(三) 窗口/滚动条/文本 alert("文本")    警告框:警告框经常用于确保用户可以得到某些信息,当警告框出现后,用户需要点击确定按钮才能继续进行操作. con ...

  7. SharePoint使用BCS开发你第一个应用程序(三)

    SharePoint使用BCS开发你第一个应用程序(三) 创建外部内容类型.         创建外部内容类型有三种不同方式: 1. 在记事本上手写XML代码(不推荐). 2. 使用SharePoin ...

  8. SQLServer 扫盲

    原文:SQLServer 扫盲 谨以本文记录本人成长历程,并分享给各位SQL Server数据库管理系统使用者.本系列包含个人认为一个DBA应该具有的各项素质,系列文章将以下面列表展示,将持续更新,敬 ...

  9. FreeBSD包管理

    FreeBSD软件没有安装Ubuntu的apt-get.它也不是Gentoo的portage.有三种方式: package ports 自主进行源代码编译安装 这里简介前两种. FreeBSD 6.0 ...

  10. Javascript入门视频教程

    1,第一节 http://pan.baidu.com/play/video#video/path=%2F%E6%95%99%E5%AD%A61.mov&t=-1 2,第二节 http://pa ...