Spark 1.1.0于2014年9月11日发布,此次的版本将mllib完善了不少,如添加了Basic Statistics、添加了决策树的Java实现等等。现对1.1.0的新功能进行一次初步探索。
Summary statistics
Summary statistics主要提供基于列的统计信息,包括6个统计量:均值、方差、非零统计量个数、总数、最小值、最大值。
测试数据
1 2 3 |
1 2 3 2 3 4 5 61 0 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public static void main(String[] args) { SparkConf sparkConf = new SparkConf().setAppName("Statistics").setMaster("local[2]"); JavaSparkContext sc = new JavaSparkContext(sparkConf); JavaRDD<String> data = sc.textFile("/home/yurnom/data/statistics.txt"); JavaRDD<Vector> parsedData = data.map(s -> { double[] values = Arrays.asList(SPACE.split(s)) .stream() .mapToDouble(Double::parseDouble) .toArray(); return Vectors.dense(values); }); MultivariateStatisticalSummary summary = Statistics.colStats(parsedData.rdd()); System.out.println("均值:"+summary.mean()); System.out.println("方差:"+summary.variance()); System.out.println("非零统计量个数:"+summary.numNonzeros()); System.out.println("总数:"+summary.count()); System.out.println("最大值:"+summary.max()); System.out.println("最小值:"+summary.min()); } |
运行结果
1 2 3 4 5 6 |
均值:[2.6666666666666665,22.0,2.333333333333333] 方差:[4.333333333333333,1141.0,4.333333333333333] 非零统计量个数:[3.0,3.0,2.0] 总数:3 最大值:[5.0,61.0,4.0] 最小值:[1.0,2.0,0.0] |
其它
运行结果的含义对照测试数据来看是一目了然的,值得一提的是方差的计算方式为:
\(s^2={\sum_{i=1}^n(x_i-\overline x)^2\over {n-1}}\)
记得当年教科书上也没解释为何要除以(n-1),好像是和自由度有关,有兴趣的可以自行google。
Correlations
Correlations,相关度量,目前Spark支持两种相关性系数:皮尔逊相关系数(pearson)和斯皮尔曼等级相关系数(spearman)。相关系数是用以反映变量之间相关关系密切程度的统计指标。简单的来说就是相关系数绝对值越大(值越接近1或者-1)则表示数据越可进行线性拟合。如下图所示:
测试数据
同上,采用第一列和第二列来进行相关度量计算。
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public static void main(String[] args) { SparkConf sparkConf = new SparkConf().setAppName("Statistics").setMaster("local[2]"); JavaSparkContext sc = new JavaSparkContext(sparkConf); JavaRDD<String> data = sc.textFile("/home/yurnom/data/statistics.txt"); JavaRDD<Vector> parsedData = data.map(s -> { double[] values = Arrays.asList(SPACE.split(s)) .stream() .mapToDouble(Double::parseDouble) .toArray(); return Vectors.dense(values); }); JavaDoubleRDD seriesX = parsedData.mapToDouble(vector -> vector.apply(0)); JavaDoubleRDD seriesY = parsedData.mapToDouble(vector -> vector.apply(1)); System.out.println(Statistics.corr(seriesX.srdd(), seriesY.srdd(), "pearson")); System.out.println(Statistics.corr(seriesX.srdd(), seriesY.srdd(), "spearman")); System.out.println("------------"); System.out.println(Statistics.corr(parsedData.rdd(), "pearson")); System.out.println("------------"); System.out.println(Statistics.corr(parsedData.rdd(), "spearman")); } |
运行结果
1 2 3 4 5 6 7 8 9 10 |
0.9741743725936144 1.0 ------------ 1.0 0.9741743725936144 -0.8846153846153846 0.9741743725936144 1.0 -0.9670636107498656 -0.8846153846153846 -0.9670636107498656 1.0 ------------ 1.0 1.0 -0.5 1.0 1.0 -0.5 -0.5 -0.5 1.0 |
皮尔逊相关系数
计算公式
\(r={{n\sum{xy}-\sum x\sum y}\over {\sqrt{n\sum x^2-(\sum x)^2}\sqrt{n\sum y^2-(\sum y)^2}}}\)
计算示例
采用代码中所用数据
序号 | x | y | x^2 | y^2 | xy |
---|---|---|---|---|---|
1 | 1 | 2 | 1 | 4 | 2 |
2 | 2 | 3 | 4 | 9 | 6 |
3 | 5 | 61 | 25 | 3721 | 305 |
合计 | 8 | 66 | 30 | 3734 | 313 |
\(r={{3*313-8*66}\over {\sqrt{3*30-8^2}\sqrt{3*3734-66^2}}}=0.9741743725936144\)
表明两组数据具有高度的线性正相关关系。
斯皮尔曼等级相关系数
计算公式
\(\rho=1-{6\sum d_i^2\over {n(n^2-1)}}\)
其中 \(d_i=x_i-y_i\) ,具体含义结合下面的计算过程来看。
计算示例
采用代码中所用数据
序号 | x | y | 等级x | 等级y | \(d_i\) | \(d_i^2\) |
---|---|---|---|---|---|---|
1 | 1 | 2 | 1 | 1 | 0 | 0 |
2 | 2 | 3 | 2 | 2 | 0 | 0 |
3 | 5 | 61 | 3 | 3 | 0 | 0 |
\(\rho=1-{6*\sum 0^2\over {3*(3^2-1)}}=1\)
其中等级x表示当前列的x在所有数据中的排序位置,上述中x=1最小,所以其等级x为1;x=5最大,排第三,所以其等级x为3。同理对等级y。
Stratified sampling
一个根据Key来抽样的功能,可以为每个key设置其被选中的概率。具体见代码以及注释。
测试数据
1 2 3 4 5 6 7 8 9 |
man 16 woman 14 woman 19 child 6 baby 1 child 3 woman 26 man 23 man 35 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public static void main(String[] args) { SparkConf sparkConf = new SparkConf().setAppName("Statistics").setMaster("local[2]"); JavaSparkContext sc = new JavaSparkContext(sparkConf); JavaRDD<String> data = sc.textFile("/home/yurnom/data/sampling.txt"); JavaPairRDD<String, Integer> parsedData = data.mapToPair(s -> { String[] values = s.split("\t"); return new Tuple2<>(values[0], Integer.parseInt(values[1])); }); Map<String, Object> fractions = new HashMap<>();//map的value为double类型,但是不能显示的写为Double fractions.put("man", 0.5); //为每个key设置一个double值,表示数据被选中的概率 fractions.put("woman", 0.5); fractions.put("child", 0.5); fractions.put("baby", 0.3); //每个数据集中有的key都必须设置相应的概率,否则会报错 JavaPairRDD<String, Integer> approxSample = parsedData.sampleByKey(false, fractions); JavaPairRDD<String, Integer> exactSample = parsedData.sampleByKeyExact(false, fractions); print(approxSample.collect()); print(exactSample.collect()); } public static void print(List list) { for(Object o : list) { Tuple2<String, Integer> t = (Tuple2<String, Integer>)o; System.out.println(t._1()+":"+t._2()); } } |
后记
后续内容将在Spark 1.1.0 Basic Statistics(下)中记录。
参考文档
- MLlib - Basic Statistics
- Spearman's rank correlation coefficient
- Pearson product-moment correlation coefficient
你好,我想问一下java要怎么使用spark mllib呢?我试了试,不太会用,希望能教我一下