Spark-特徵選擇(scala)
spark特徵選擇,基於scala語言編寫
ChiSqSelector
特徵選擇試圖識別用來構建模型的相關特徵,它減少了特徵空間的大小,既可以提高速度又可以提高統計學習行為的結果。
ChiSqSelector實現了卡方特徵選擇。它能夠操作帶有不同種類特徵的標籤資料。ChiSqSelector利用了卡方獨立性檢驗來決定應該選取哪些特徵。它支援三種特徵選擇模型:
(1)numTopFeatures:根據卡方校驗選取前n數量個特徵(top features),這類似於用最具有預測能力的特徵。
(2)percentile:類似於numTopFeatures,但選擇一部分的特徵,而不是一個固定的數字。
(3)fpr:選擇所有的p值低於閾值非得特徵,從而控制選擇的假陽性率。
預設情況下,對於numTopFeatures方法,一般設定(top features=50)前50個特徵,使用者還可以通過setSelectorType來設定選擇模型。
Model Fitting
特徵選擇模型中的fit方法,可以接受含有特徵的RDD[LabeledPoint]資料格式,使用簡單的統計學習並返回一個特徵選擇模型(ChiSqSelectorModel),它能夠將輸入含有特徵的資料轉變成含有少量特徵空間的資料。也可以應用於向量(Vector)。
值得注意的是,使用者也可以手動建立一個ChiSqSelectorModel,需要提供選擇的特徵索引陣列(必須以升序排序)。
Example
接下來,會用scala編寫一個簡單特徵選擇例子。
目前,特徵選擇,官網API只顯示支援scala和java,沒有python的
package com
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
import org.apache.spark.{SparkConf, SparkContext}
/**
* Created by xudong-HFUTec on 2017/5/13.
* 基於卡方校驗的特徵選擇
* 卡方校驗:
* 在分類資料統計中推斷中一般用於檢驗一個樣本是否符合預期的一個分佈
* 是統計樣本的實際值與理論推斷值之間的偏離程式
* 卡防值越小,越趨於符合
*/
class ChiSqSelectorExample {
def main(args: Array[String]){
//設定本程式的名稱和啟動本地化計算
val conf=new SparkConf().setAppName("ChiSqSelector").setMaster("Local")
//spark程式的編寫從SparkContext開始的
val sc=new SparkContext(conf)
//通過MLUtils載入資料,這裡的路徑在本地執行指的是本地的路徑,如果在叢集上,指的hdfs的路徑
//另外需要注意的是:這裡的data檔案裡面的格式如果不符合libsvm的格式會讀取報錯,比如特徵的索引不是升序排序
val data=MLUtils.loadLibSVMFile(sc,"e:/data/sample_libsvm_data.txt")
//這裡面是資料處理空間,一般是用不到的,可以直接使用data檔案
val discretizedData=data.map{lp =>
LabeledPoint(lp.label,Vectors.dense(lp.features.toArray.map{x => (x/16).floor}))
}
//設定選取的特徵數量
val features_num=50
val selector=new ChiSqSelector(features_num)
//建立一個特徵選擇模型
val transformer=selector.fit(data)
//選取top 50的特徵
val filteredData=data.map{lp =>
LabeledPoint(lp.label,transformer.transform(lp.features))
}
//打印出被選特徵的index,counting from 0
print("===================")
print(transformer.selectedFeatures.mkString("~"))
print("===================")
//通過MLUtils儲存過濾後的資料
//這裡面還有個問題,如果是在本地執行,這行程式碼執行會報錯,但是在叢集上會正常(至少在我的電腦上是這樣。)
MLUtils.saveAsLibSVMFile(filteredData,"e:/data/model")
}
}
注意:在本地測試的時候,可以把MLUtils.saveAsLibSVMFile(filteredData,”e:/data/model”)註釋掉,然後執行程式並檢查程式執行結果是否正確