会粗略讲一下原理,主要在代码以及之后的实践上。主要用scala代码为例。
一,卡方检验的步骤
第一步确认“无关性假设”
给出“原假设”和“备择假设”。通常卡方中的原假设是两个变量是独立没关系的。
给出统计表:
第二步,根据无关性假设生成新的理论值四格表
显然,若是两个变量是独立无关的,那么四格表中的理论值与实际值的差别会很是小。
第三步,计算X^2的值
第四步根据自由度查表来判断是否相关。
这里须要用到一个自由度的概念,自由度等于V = (行数 - 1) * (列数 - 1),对四格表,自由度V = 1。
目前spark官网上关于卡方检测的包有两个分别是
org.apache.spark.mllib.feature.ChiSqSelector 和 org.apache.spark.ml.feature.ChiSqSelector
区别主要是输入数据。前面一个主要支持RDD的数据,后面一个主要支持DataFrame的数据
另外一个区别就是前面的包处于维护状态,后面的包是主要更新状态。
二,代码实现
1,官网上的代码样例。讲真的官网上的样例根本跑不通,不知道是不是样例的代码太老了。查了查资料终于跑通了。
基于DataFrame数据的ChiSq:
卡方检验官网样例
package com.---------.training
// $example on$
import org.apache.spark.ml.feature.ChiSqSelector
import org.apache.spark.ml.linalg.Vectors
// $example off$
import org.apache.spark.sql.SparkSession
object testFile33 {
def main(args: Array[String]) {
val spark = SparkSession
.builder
.appName("ChiSqSelectorExample")
.master("local")
.getOrCreate()
import spark.implicits._
// $example on$
val data = Seq(
(7, Vectors.dense(0.0, 0.0, 18.0, 1.0), 1.0),
(8, Vectors.dense(0.0, 1.0, 12.0, 0.0), 0.0),
(9, Vectors.dense(1.0, 0.0, 15.0, 0.1), 0.0)
)
val df = spark.createDataset(data).toDF("id", "features", "clicked")
val selector = new ChiSqSelector()
.setNumTopFeatures(1)
.setFeaturesCol("features")
.setLabelCol("clicked")
.setOutputCol("selectedFeatures")
val result = selector.fit(df).transform(df)
println(s"ChiSqSelector output with top ${selector.getNumTopFeatures} features selected")
result.show()
// $example off$
spark.stop()
}
}
基于RDD数据格式:
ml的卡方检验官网样例
官网的样例直接跑肯定不行,一番修改之后是这样的。
package com.----------.training
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
// $example on$
import org.apache.spark.mllib.feature.ChiSqSelector
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
// $example off$
object ThetestRddChiSqSelector {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("ChiSqSelectorExample").setMaster("local")
val sc = new SparkContext(conf)
// $example on$
// Load some data in libsvm format
val data = MLUtils.loadLibSVMFile(sc, "./sample_libsvm_data_head.txt")
// Discretize data in 16 equal bins since ChiSqSelector requires categorical features
// Even though features are doubles, the ChiSqSelector treats each unique value as a category
val discretizedData = data.map { lp =>
LabeledPoint(lp.label, Vectors.dense(lp.features.toArray.map { x => (x / 16).floor }))
}
// Create ChiSqSelector that will select top 50 of 692 features
val selector = new ChiSqSelector(5)
// Create ChiSqSelector model (selecting features)
val transformer = selector.fit(discretizedData)
// Filter the top 50 features from each feature vector
val filteredData = discretizedData.map { lp =>
LabeledPoint(lp.label, transformer.transform(lp.features))
}
// $example off$
println("filtered data: ")
filteredData.foreach(x => println(x))
sc.stop()
}
}
2,还要进一步探索
白话卡方检验
http://www.javashuo.com/article/p-mizvutbn-b.html
更加白话
http://www.javashuo.com/article/p-fquulgxw-b.html