1. 程式人生 > >SparkML中三種特徵選擇演算法(VectorSlicer/RFormula/ChiSqSelector)

SparkML中三種特徵選擇演算法(VectorSlicer/RFormula/ChiSqSelector)

        在SparkML中關於特徵的演算法可分為Extractors(特徵提取)、Transformers(特徵轉換)、Selectors(特徵選擇)三部分:

        上一章理解了基於SparkML的文字特徵提取(Feature Extractors)演算法,這裡再針對特徵選擇(Feature Selectors)的三個演算法(VectorSlicer、RFormula以及ChiSqSelector)結合Demo進行一下理解

VectorSlicer演算法介紹:

         VectorSlicer是一個轉換器輸入特徵向量,輸出原始特徵向量子集。VectorSlicer接收帶有特定索引的向量列,通過對這些索引的值進行篩選得到新的向量集。可接受如下兩種索引:

1、整數索引---代表向量中特徵的的索引,setIndices()

2、字串索引---代表向量中特徵的名字,這要求向量列有AttributeGroup,因為這根據Attribute來匹配名字欄位

        指定整數或者字串型別都是可以的。另外,同時使用整數索引和字串名字也是可以的。同時注意,至少選擇一個特徵,不能重複選擇同一特徵(整數索引和名字索引對應的特徵不能疊)。注意如果使用名字特徵,當遇到空值的時候將會報錯。
        輸出向量將會首先按照所選的數字索引排序(按輸入順序),其次按名字排序(按輸入順序)。

        示例:輸入一個包含列名為userFeatures的DataFrame:

 userFeatures
------------------
 [0.0, 10.0, 0.5]

        userFeatures是一個向量列包含3個使用者特徵。假設userFeatures的第一列全為0,我們希望刪除它並且只選擇後兩項。我們可以通過索引setIndices(1,2)來選擇後兩項併產生一個新的features列:

 userFeatures     | features
------------------|-----------------------------
 [0.0, 10.0, 0.5] | [10.0, 0.5]
       假設我們還有如同["f1","f2", "f3"]的屬性,那可以通過名字setNames("f2","f3")的形式來選擇:
 userFeatures     | features
------------------|-----------------------------
 [0.0, 10.0, 0.5] | [10.0, 0.5]
 ["f1", "f2", "f3"] | ["f2", "f3"]
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.ml.attribute.Attribute;
import org.apache.spark.ml.attribute.AttributeGroup;
import org.apache.spark.ml.attribute.NumericAttribute;
import org.apache.spark.ml.feature.VectorSlicer;
import org.apache.spark.ml.linalg.Vectors;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.StructType;

import java.util.Arrays;
import java.util.List;

public class VectorSlicerDemo {
    public static void main(String[] args){
        SparkConf conf = new SparkConf().setAppName("VectorSlicer").setMaster("local");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);

        Attribute[] attributes = new Attribute[]{
                NumericAttribute.defaultAttr().withName("f1"),
                NumericAttribute.defaultAttr().withName("f2"),
                NumericAttribute.defaultAttr().withName("f3")
        };
        AttributeGroup group = new AttributeGroup("userFeatures", attributes);

        List<Row> data = Arrays.asList(
                RowFactory.create(Vectors.sparse(3, new int[]{0, 1}, new double[]{-2.0, 2.3})),
                RowFactory.create(Vectors.dense(-2.0, 2.3, 0.0))
        );

        Dataset<Row> dataset = sqlContext
                .createDataFrame(data, (new StructType())
                .add(group.toStructField()));

        VectorSlicer vectorSlicer = new VectorSlicer()
                .setInputCol("userFeatures")
                .setOutputCol("features");

        vectorSlicer.setIndices(new int[]{1}).setNames(new String[]{"f3"});
        // or slicer.setIndices(new int[]{1, 2}), or slicer.setNames(new String[]{"f2", "f3"})

        Dataset<Row> output = vectorSlicer.transform(dataset);
        output.show(false);

//        +--------------------+-------------+
//        |userFeatures        |features     |
//        +--------------------+-------------+
//        |(3,[0,1],[-2.0,2.3])|(2,[0],[2.3])|
//        |[-2.0,2.3,0.0]      |[2.3,0.0]    |
//        +--------------------+-------------+

        sc.stop();
    }
}

RFormula演算法介紹:

        RFormula通過R模型公式來選擇列。支援R操作中的部分操作,包括‘~’, ‘.’, ‘:’, ‘+’以及‘-‘,基本操作如下:

1、 ~分隔目標和物件

2、 +合併物件,“+0”意味著刪除空格

3、-刪除一個物件,“-1”表示刪除空格

4、 :互動(數值相乘,類別二值化)

5、 . 除了目標列的全部列

        假設a和b為兩列:

1、 y ~ a + b表示模型y ~ w0 + w1 * a +w2 * b其中w0為截距,w1和w2為相關係數

2、 y ~a + b + a:b – 1表示模型y ~ w1* a + w2 * b + w3 * a * b,其中w1,w2,w3是相關係數

        RFormula產生一個向量特徵列以及一個double或者字串標籤列。如果用R進行線性迴歸,則對String型別的輸入列進行one-hot編碼、對數值型的輸入列進行double型別轉化。如果類別列是字串型別,它將通過StringIndexer轉換為double型別。如果標籤列不存在,則輸出中將通過規定的響應變數創造一個標籤列。

        示例:假設我們有一個DataFrame含有id,country, hour和clicked四列:

id | country | hour | clicked
---|---------|------|---------
 7 | "US"    | 18   | 1.0
 8 | "CA"    | 12   | 0.0
 9 | "NZ"    | 15   | 0.0
       如果我們使用RFormula公式clicked ~ country+ hour,則表明我們希望基於country和hour預測clicked,通過轉換我們可以得到如DataFrme:
id | country | hour | clicked | features         | label
---|---------|------|---------|------------------|-------
 7 | "US"    | 18   | 1.0     | [0.0, 0.0, 18.0] | 1.0
 8 | "CA"    | 12   | 0.0     | [0.0, 1.0, 12.0] | 0.0
 9 | "NZ"    | 15   | 0.0     | [1.0, 0.0, 15.0] | 0.0
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.ml.feature.RFormula;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import java.util.Arrays;
import java.util.List;

import static org.apache.spark.sql.types.DataTypes.*;

public class RFormulaDemo {
    public static void main(String[] args){
        SparkConf conf = new SparkConf().setAppName("RFoumula").setMaster("local");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);

        List<Row> data = Arrays.asList(
                RowFactory.create(7,"US",18,1.0),
                RowFactory.create(8,"CA",12,0.0),
                RowFactory.create(9,"NZ",15,0.0)
        );

        StructType schema = createStructType(new StructField[]{
                createStructField("id", IntegerType, false),
                createStructField("country", StringType, false),
                createStructField("hour", IntegerType, false),
                createStructField("clicked", DoubleType, false)
        });

        Dataset<Row> dataset = sqlContext.createDataFrame(data,schema);
        RFormula formula = new RFormula()
                .setFormula("clicked ~ country + hour")
                .setFeaturesCol("features")
                .setLabelCol("label");
        Dataset<Row> output = formula.fit(dataset).transform(dataset);
        output.select("features", "label").show(false);

//        +--------------+-----+
//        |features      |label|
//        +--------------+-----+
//        |[0.0,0.0,18.0]|1.0  |
//        |[1.0,0.0,12.0]|0.0  |
//        |[0.0,1.0,15.0]|0.0  |
//        +--------------+-----+

        sc.stop();
    }
}

ChiSqSelector演算法介紹:

        ChiSqSelector代表卡方特徵選擇。它適用於帶有類別特徵的標籤資料。ChiSqSelector根據獨立卡方檢驗,然後選取類別標籤主要依賴的特徵。它類似於選取最有預測能力的特徵。它支援三種特徵選取方法:

1、numTopFeatures:通過卡方檢驗選取最具有預測能力的Top(num)個特徵;

2、percentile:類似於上一種方法,但是選取一小部分特徵而不是固定(num)個特徵;

3、fpr:選擇P值低於門限值的特徵,這樣就可以控制false positive rate來進行特徵選擇;

        預設情況下特徵選擇方法是numTopFeatures(50),可以根據setSelectorType()選擇特徵選取方法。

        示例:假設我們有一個DataFrame含有id,features和clicked三列,其中clicked為需要預測的目標:

id | features              | clicked
---|-----------------------|---------
 7 | [0.0, 0.0, 18.0, 1.0] | 1.0
 8 | [0.0, 1.0, 12.0, 0.0] | 0.0
 9 | [1.0, 0.0, 15.0, 0.1] | 0.0
        如果我們使用ChiSqSelector並設定numTopFeatures為1,根據標籤clicked,features中最後一列將會是最有用特徵:
id | features              | clicked | selectedFeatures
---|-----------------------|---------|------------------
 7 | [0.0, 0.0, 18.0, 1.0] | 1.0     | [1.0]
 8 | [0.0, 1.0, 12.0, 0.0] | 0.0     | [0.0]
 9 | [1.0, 0.0, 15.0, 0.1] | 0.0     | [0.1]
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.ml.feature.ChiSqSelector;
import org.apache.spark.ml.linalg.VectorUDT;
import org.apache.spark.ml.linalg.Vectors;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.Metadata;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import java.util.Arrays;
import java.util.List;

public class ChiSqSelectorDemo {
    public static void main(String[] args){
        SparkConf conf = new SparkConf().setAppName("Demo").setMaster("local");
        JavaSparkContext sc = new JavaSparkContext(conf);
        SQLContext sqlContext = new SQLContext(sc);

        JavaRDD<Row> data = sc.parallelize(Arrays.asList(
                RowFactory.create(7, Vectors.dense(0.0, 0.0, 18.0, 1.0), 1.0),
                RowFactory.create(8, Vectors.dense(0.0, 1.0, 12.0, 0.0), 0.0),
                RowFactory.create(9, Vectors.dense(1.0, 0.0, 15.0, 0.1), 0.0)
        ));

        StructType schema = new StructType(new StructField[]{
                new StructField("id", DataTypes.IntegerType, false, Metadata.empty()),
                new StructField("features", new VectorUDT(), false, Metadata.empty()),
                new StructField("clicked", DataTypes.DoubleType, false, Metadata.empty())
        });


        Dataset<Row> df = sqlContext.createDataFrame(data, schema);

        ChiSqSelector selector = new ChiSqSelector()
                .setNumTopFeatures(2)
                .setFeaturesCol("features")
                .setLabelCol("clicked")
                .setOutputCol("selectedFeatures");

        Dataset<Row> result = selector.fit(df).transform(df);
        result.show(false);

//        +---+------------------+-------+----------------+
//        |id |features          |clicked|selectedFeatures|
//        +---+------------------+-------+----------------+
//        |7  |[0.0,0.0,18.0,1.0]|1.0    |[18.0,1.0]      |
//        |8  |[0.0,1.0,12.0,0.0]|0.0    |[12.0,0.0]      |
//        |9  |[1.0,0.0,15.0,0.1]|0.0    |[15.0,0.1]      |
//        +---+------------------+-------+----------------+

        sc.stop();
    }
}

參考網址:

http://spark.apache.org/docs/latest/ml-features.html

相關推薦

SparkML特徵選擇演算法VectorSlicer/RFormula/ChiSqSelector

        在SparkML中關於特徵的演算法可分為Extractors(特徵提取)、Transformers(特徵轉換)、Selectors(特徵選擇)三部分:         上一章理解了基於SparkML的文字特徵提取(Feature Extractors)

機器學習: python特徵選擇方法

特徵選擇的三種方法介紹: 過濾型: 選擇與目標變數相關性較強的特徵。缺點:忽略了特徵之間的關聯性。 包裹型: 基於線性模型相關係數以及模型結果AUC逐步剔除特徵。如果剔除相關係數絕對值較小特徵後

常用排序演算法冒泡、選擇、快速的Java實現

       學習Java有一陣子了,現在還處於比較初級的水平,能夠把簡單的程式寫對就不錯了,更不用談現在能夠拿Java做什麼了。        學完了兩段網路視訊課程,接下來找本書簡單看看。只要有了一個初步的認識,接下來的東西應該可以更加順利一些。學習程式設計最好的方法就

特徵選擇方法及Spark MLlib呼叫例項Scala/Java/python

VectorSlicer 演算法介紹:         VectorSlicer是一個轉換器輸入特徵向量,輸出原始特徵向量子集。VectorSlicer接收帶有特定索引的向量列,通過對這些索引的值進行篩選得到新的向量集。可接受如下兩種索引 1.整數索引,setIndice

035捷聯慣導姿態更新演算法說明

看到了不同的姿態更新演算法,很迷惑,陷入了誰相對於誰的思考中。翻翻嚴老師部落格,貼出來如下: 原文地址:http://blog.sina.com.cn/s/blog_40edfdc90102v6il.html#cmt_556E9C77-7F000001-41D46DB9-790-8

排序演算法():簡單選擇排序Simple Selection Sort

基本思想: 在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。 簡單選擇排序的示例: 操作方法: 第一趟,從n

PYTHON取整函式// int round的區別

>>> 5//3 1 >>> -5//3 -2 >>> int(5.3) 5 >>> int(5.6) 5 >>> round(5.3) 5 >>> round(5.6

鳶尾花聚類演算法K-means,AGNES,DBScan的python實現

一.分散性聚類(kmeans) 演算法流程: 1.選擇聚類的個數k. 2.任意產生k個聚類,然後確定聚類中心,或者直接生成k箇中心。 3.對每個點確定其聚類中心點。 4.再計算其聚類新中心。 5.重複以上步驟直到滿足收斂要求。(通常就是確定的中心點不再改變。

mRMR特徵選擇演算法feature_selection的使用

源程式下載地址,本機電腦安裝java環境,具體環境安裝可自行百度,google. 用以實現用 mRMR 從特徵集中提取特徵的程式(python) #inport neccesary bags import csv#用來儲存csv檔案 import pa

樹的遍歷方式C語言實現

//************************************************************************* // 【前序】遍歷演算法 //二叉樹不空,先訪問根結點,然後前序遍歷左子樹,再前序遍歷右子樹 //***********************

簡述python網路傳輸方式UDP,TCP

簡述python中網路傳輸方式(UDP,TCP) socket 套接字 socket(簡稱 套接字) 是程序間通訊一個工具,它能實現把資料從一方傳輸到另外一方,完成不同電腦上程序之間的通訊, 它好比資料的搬運工 在建立socket連線時,有TCP和UDP兩種連線方式。 UDP

常見14經典排序演算法Java程式碼實現

尊重原創,轉載請標明出處   http://blog.csdn.net/abcdef314159 ,想了解更多演算法題可以關注微信公眾號“資料結構和演算法”,每天一題為你精彩解答。 一,氣泡排序 排序演算法其實有很多,氣泡排序基本上算是最簡單的一種

angularjs2 常用的型別String,Number

let a:Number=1;//數值型別 let b:String = 'angularjs2';//字元型別 let c:boolean = true; //布林型別 let d:Number [

10機器學習演算法附Python程式碼

sklearn python API from sklearn.linear_model import LinearRegression # 線性迴歸 # module = LinearRegression() module.fit(x

Coursera視訊無法觀看的不同解決方法親測有效

最近在coursera上課時出現了視訊黑屏,網頁緩衝,無法觀看等問題,經過查詢發現很多人也有同樣的問題。對於不同的原因,一般來說解決方法也不同。這裡有三種辦法,大家可以挨個嘗試,肯定有一個能用。1. 瀏覽器原因在win7和部分WIN10上用的chrome會出現黑屏現象。有兩個

C語言冒泡法、選擇法、插入法常見排序演算法分析

一、冒泡法(起泡法)  演算法要求:用起泡法對10個整數按升序排序。     演算法分析:如果有n個數,則要進行n-1趟比較。在第1趟比較中要進行n-1次相鄰元素的兩兩比較,在第j趟比較中要進行n-j次兩兩比較。比較的順序從前往後,經過一趟比較後,將最值沉底(換到最後一個元

Android常用解析XML的方式DOM、SAX、PULL簡介及區別

字符串 lan win name屬性 Coding 空間 toc log fin XML在各種開發中都廣泛應用,Android也不例外。作為承載數據的一個重要角色,如何讀寫XML成為Android開發中一項重要的技能。今天就由我向大家介紹一下在Android平臺下幾種常見的

C++類的繼承方式public公有繼承、protected保護繼承、private私有繼承之間的差別附思維導圖【轉】

(轉自:https://blog.csdn.net/coco56/article/details/80467975) 注:若不指明繼承方式,則預設是私有繼承。 一:對於公有繼承(public)方式: 基類的public和protected成員的訪問屬性在派生類中保持不變,但基類的p

SparkSQLJoin及其實現broadcast join、shuffle hash join和sort merge join

1.小表對大表(broadcast join) 將小表的資料分發到每個節點上,供大表使用。executor儲存小表的全部資料,一定程度上犧牲了空間,換取shuffle操作大量的耗時,這在SparkSQL中稱作Broadcast Join Broadcast Jo

排序演算法1——圖解氣泡排序及其實現方法,基於模板及函式指標

排序演算法1——圖解氣泡排序及其實現(三種方法,基於模板及函式指標) 排序演算法2——圖解簡單選擇排序及其實現 排序演算法3——圖解直接插入排序以及折半(二分)插入排序及其實現 排序演算法4——圖解希爾排序及其實現 排序演算法5——圖解堆排序及其實現 排序演算法6——圖解歸併排序及其遞迴與非