Spark StringIndexer和IndexToString


1、StringIndexer

   標簽索引器,它將標簽的字符串列映射到標簽索引的ML列。
  如果輸入列為數字,則將其強制轉換為字符串並為字符串值編制索引。
  索引在[0,numLabels)中。

  索引構建的順序為標簽的頻率,優先編碼頻率較大的標簽,所以出現頻率最高的標簽為0號

  默認情況下,按標簽頻率排序,因此最常使用的標簽的索引為0。

  StringIndexer轉換器可以把一列類別型的特征(或標簽)進行編碼,使其數值化,
  索引的范圍從0開始,該過程可以使得相應的特征索引化,
  使得某些無法接受類別型特征的算法可以使用,並提高諸如決策樹等機器學習算法的效率

//定義一個StringIndexerModel,將label轉換成indexedlabel
StringIndexerModel labelIndexerModel=new StringIndexer().
                setInputCol("label")
                .setOutputCol("indexedLabel")
                .fit(rawData);
//加labelIndexerModel加入到Pipeline中
Pipeline pipeline=new Pipeline()
                 .setStages(new PipelineStage[]
                         {labelIndexerModel,
                         featureIndexerModel,
                         dtClassifier,
                         converter});
//查看結果
pipeline.fit(rawData).transform(rawData).select("label","indexedLabel").show(20,false);
 
按label出現的頻次,轉換成0~num numOfLabels-1(分類個數),頻次最高的轉換為0,以此類推:
label=3,出現次數最多,出現了4次,轉換(編號)為0
其次是label=2,出現了3次,編號為1,以此類推
+-----+------------+
|label|indexedLabel|
+-----+------------+
|3.0  |0.0         |
|4.0  |3.0         |
|1.0  |2.0         |
|3.0  |0.0         |
|2.0  |1.0         |
|3.0  |0.0         |
|2.0  |1.0         |
|3.0  |0.0         |
|2.0  |1.0         |
|1.0  |2.0         |
+-----+------------+
    StringIndexer對String按頻次進行編號
     id | category | categoryIndex
    ----|----------|---------------
     0  | a        | 0.0
     1  | b        | 2.0
     2  | c        | 1.0
     3  | a        | 0.0
     4  | a        | 0.0
     5  | c        | 1.0
     如果轉換模型(關系)是基於上面數據得到的 (a,b,c)->(0.0,2.0,1.0),如果用此模型轉換category多於(a,b,c)的數據,比如多了d,e,就會遇到麻煩:
     id | category | categoryIndex
    ----|----------|---------------
     0  | a        | 0.0
     1  | b        | 2.0
     2  | d        | ?
     3  | e        | ?
     4  | a        | 0.0
     5  | c        | 1.0
     Spark提供了兩種處理方式:
     StringIndexerModel labelIndexerModel=new StringIndexer().
                    setInputCol("label")
                    .setOutputCol("indexedLabel")
                    //.setHandleInvalid("error")
                    .setHandleInvalid("skip")
                    .fit(rawData);
     (1)默認設置,也就是.setHandleInvalid("error"):會拋出異常
     org.apache.spark.SparkException: Unseen label: d,e
     (2).setHandleInvalid("skip") 忽略這些label所在行的數據,正常運行,將輸出如下結果:
     id | category | categoryIndex
    ----|----------|---------------
     0  | a        | 0.0
     1  | b        | 2.0
     4  | a        | 0.0
     5  | c        | 1.0

 

2、IndexToString

是一個轉換器“ Transformer”,它將一列索引映射回對應字符串值的新列。

索引字符串映射既可以來自輸入列的ML屬性,也可以來自用戶提供的標簽(優先於ML屬性)。

相應的,有StringIndexer,就應該有IndexToString。
在應用StringIndexer對labels進行重新編號后,帶着這些編號后的label對數據進行了訓練,並接着對其他數據進行了預測,
得到預測結果,預測結果的label也是重新編號過的,因此需要轉換回來。
見下面例子,轉換回來的convetedPrediction才和原始的label對應。
IndexToString converter=new IndexToString()
                .setInputCol("prediction")//Spark默認預測label行
                .setOutputCol("convetedPrediction")//轉換回來的預測label
                .setLabels(labelIndexerModel.labels());//需要指定前面建好模型
Pipeline pipeline=new Pipeline()
                 .setStages(new PipelineStage[]
                         {labelIndexerModel,
                         featureIndexerModel,
                         dtClassifier,
                         converter});
pipeline.fit(rawData).transform(rawData)
        .select("label","prediction","convetedPrediction").show(20,false);  
|label|prediction|convetedPrediction|
+-----+----------+------------------+
|3.0  |0.0       |3.0               |
|4.0  |1.0       |2.0               |
|1.0  |2.0       |1.0               |
|3.0  |0.0       |3.0               |
|2.0  |1.0       |2.0               |
|3.0  |0.0       |3.0               |
|2.0  |1.0       |2.0               |
|3.0  |0.0       |3.0               |
|2.0  |1.0       |2.0               |
|1.0  |2.0       |1.0               |
+-----+----------+------------------+


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM