2017-05-29 121 views
2

我正在開發一個項目,我必須用Spark的MLlib進行K-means聚類。問題是我的數據有744個功能。我做了一些研究,發現PCA是我需要的。最好的部分是Spark PCA的實現,所以我決定這麼做。Spark主成分分析(PCA)預期結果

double[][] array=new double[381][744]; 
     int contor=0; 
     for (Vector vectorData : parsedTrainingData.collect()) { 
      contor++; 
      array[contor]=vectorData.toArray(); 
     } 

     LinkedList<Vector> rowsList = new LinkedList<>(); 
     for (int i = 0; i < array.length; i++) { 
      Vector currentRow = Vectors.dense(array[i]); 
      rowsList.add(currentRow); 
     } 
     JavaRDD<Vector> rows = jsc.parallelize(rowsList); 

     // Create a RowMatrix from JavaRDD<Vector>. 
     RowMatrix mat = new RowMatrix(rows.rdd()); 

     // Compute the top 3 principal components. 
     Tuple2<Matrix, Vector> pc = mat.computePrincipalComponentsAndExplainedVariance(*param*); 

     RowMatrix projected = mat.multiply(pc._1); 
     // $example off$ 
     Vector[] collectPartitions = (Vector[]) projected.rows().collect(); 
     System.out.println("Projected vector of principal component:"); 
     for (Vector vector : collectPartitions) { 
      System.out.println("\t" + vector); 
     } 
     System.out.println("\n Explanend Variance:"); 
     System.out.println(pc._2); 
     double sum = 0; 

     for (Double val : pc._2.toArray()) { 
      sum += val; 

     } 
     System.out.println("\n the sum is: " + (double) sum); 

關於我想申請PCA數據我有744層的功能誰代表值,通過傳感器上每隔一小時一個家庭收集(活動時間總秒數),所以它有點像(31個傳感器* 24 (s(sensorNumber)(hour):s10,s11 ..... s123,s20,s21 .... 223,..... s3123。

從我理解的一個減少不失去大部分信息的標準是解釋方差的總和大於0.9(90%)。經過一些測試,我得到了以下結果:

*pram* sum 
    100 0.91 
    150 0.97 
    200 0.98 
    250 0.99 
    350 1 

因此,據我所知,將我的744特徵矢量減少到100特徵矢量將是安全的。我的問題是這個結果看起來很好是真的。我尋找一些例子來獲得指導,但我仍然不確定我做的是否正確。那麼這個結果是否合理呢?

回答

0

由於PCA是降維算法,所以情況似乎是合理的。這是非常符合你想要預測的,以及你必須訓練哪些數據。

PCA常用於人臉識別,因爲您只需要幾個特徵值來區分新面孔。在一個人臉識別程序中,我使用了50個選擇的4個特徵向量來對所有者進行精確分類。

有些人使用10%,其他人選擇具有一定值的所有值,關於另一線程上的特徵選擇有一個很好的討論here