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根據獨立卡方檢驗,然後選取類別標籤主要依賴的特徵。它類似於選取最有預測能力的特徵。它支援三種特徵選取方法:
預設情況下特徵選擇方法是numTopFeatures(50),可以根據setSelectorType()選擇特徵選取方法。1、numTopFeatures:通過卡方檢驗選取最具有預測能力的Top(num)個特徵;
2、percentile:類似於上一種方法,但是選取一小部分特徵而不是固定(num)個特徵;
3、fpr:選擇P值低於門限值的特徵,這樣就可以控制false positive rate來進行特徵選擇;
示例:假設我們有一個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
SparkSQL中的三種Join及其實現(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——圖解歸併排序及其遞迴與非