【版权声明】本文为原创,转载请注明原地址 https://www.jianshu.com/p/5e749795df2e
同步更新在个人网站:http://www.wangpengcufe.com/machinelearning/ml-ml8/
一、概念
主成分分析(Principal Component Analysis)是指将多个变量通过线性变换以选出较少数重要变量的一种多元统计分析方法,又称为主成分分析。在实际应用场合中,为了全面分析问题,往往提出很多与此有关的变量(或因素),因为每个变量都在不同程度上反映这个应用场合的某些信息。
主成分分析是设法将原来众多具有一定相关性(比如N个指标)的指标,重新组合成一组新的相互无关的综合指标来代替原来的指标,从而实现数据降维的目的,这也是MLlib的处理手段之一。
二、代码实现
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.mllib.feature.PCA;
import org.apache.spark.mllib.feature.PCAModel;
import org.apache.spark.mllib.linalg.Matrix;
import org.apache.spark.mllib.linalg.Vector;
import org.apache.spark.mllib.linalg.Vectors;
import org.apache.spark.mllib.linalg.distributed.RowMatrix;
import org.apache.spark.mllib.regression.LabeledPoint;
import org.apache.spark.rdd.RDD;
SparkConf conf = new SparkConf().setAppName("PCA").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
/**
* 使用test.data矩阵
1 2 3 4 5 6 7 8 9
5 6 7 8 9 0 8 6 7
9 0 8 7 1 4 3 2 1
6 4 2 1 3 4 2 1 5
*/
JavaRDD<String> source = sc.textFile("data/mllib/test.data");
JavaRDD<Vector> data = source.map(line->{
String[] parts = line.split(" ");
return Vectors.dense(Double.parseDouble(parts[0]),
Double.parseDouble(parts[1]),
Double.parseDouble(parts[2]),
Double.parseDouble(parts[3]),
Double.parseDouble(parts[4]),
Double.parseDouble(parts[5]),
Double.parseDouble(parts[6]),
Double.parseDouble(parts[7]),
Double.parseDouble(parts[8]));
});
data.foreach(x->{
System.out.println(x);
});
控制台输出结果:
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0]
[5.0,6.0,7.0,8.0,9.0,0.0,8.0,6.0,7.0]
[9.0,0.0,8.0,7.0,1.0,4.0,3.0,2.0,1.0]
[6.0,4.0,2.0,1.0,3.0,4.0,2.0,1.0,5.0]
RowMatrix rm = new RowMatrix(data.rdd());
Matrix pc = rm.computePrincipalComponents(3);
System.out.println(pc);
控制台输出结果:
-0.41267731212833847 -0.3096216957951525 0.1822187433607524
0.22357946922702987 -0.08150768817940773 0.5905947537762997
-0.08813803143909382 -0.5339474873283436 -0.2258410886711858
0.07580492185074224 -0.56869017430423 -0.28981327663106565
0.4399389896865264 -0.23105821586820194 0.3185548657550075
-0.08276152212493619 0.3798283369681188 -0.4216195003799105
0.3952116027336311 -0.19598446496556066 -0.17237034054712738
0.43580231831608096 -0.023441639969444372 -0.4151661847170216
0.468703853681766 0.2288352748369381 0.04103087747663084
可以看到,主成分矩阵是一个尺寸为(9,3)的矩阵,其中每一列代表一个主成分(新坐标轴),每一行代表原有的一个特征,而a.data矩阵可以看成是一个有4个样本,9个特征的数据集,那么,主成分矩阵相当于把原有的9维特征空间投影到一个3维的空间中,从而达到降维的效果。
RowMatrix rm2 = rm.multiply(pc);
RDD<Vector> v = rm2.rows();
JavaRDD<Vector> vector = v.toJavaRDD();
vector.foreach(x->{
System.out.println(x);
});
控制台输出结果:
[12.247647483894383,-2.725468189870252,-5.568954759405281]
[12.284448024169402,-12.510510992280857,-0.16048149283293078]
[-1.2537294080109986,-10.15675264890709,-4.8697886049036025]
[2.8762985358626505,-2.2654415718974685,1.428630138613534]
MLlib提供的PCA变换方法最多只能处理65535维的数据。
参考资料: