OneHotEncoder
は単独で使用することを意図していません。代わりに、列メタデータを利用できるPipeline
の一部である必要があります。たとえば次のよう考えてみましょう:あなたはエンコーダーを使用する場合
training = sc.parallelize([(0.,), (1.,), (1.,), (3.,)]).toDF(["type"])
testing = sc.parallelize([(0.,), (1.,), (1.,), (1.,)]).toDF(["type"])
は、直接それがコンテキストに関する知識がない:
from pyspark.ml.feature import OneHotEncoder
encoder = OneHotEncoder().setOutputCol("encoded").setDropLast(False)
encoder.setInputCol("type").transform(training).show()
## +----+-------------+
## |type| encoded|
## +----+-------------+
## | 0.0|(4,[0],[1.0])|
## | 1.0|(4,[1],[1.0])|
## | 1.0|(4,[1],[1.0])|
## | 3.0|(4,[3],[1.0])|
## +----+-------------+
encoder.setInputCol("type").transform(testing).show()
## +----+-------------+
## |type| encoded|
## +----+-------------+
## | 0.0|(2,[0],[1.0])|
## | 1.0|(2,[1],[1.0])|
## | 1.0|(2,[1],[1.0])|
## | 1.0|(2,[1],[1.0])|
## +----+-------------+
は今すぐ必要なメタデータを追加することができます。それはStringIndexer
を使用することによって、たとえばことができます。
indexer = (StringIndexer()
.setInputCol("type")
.setOutputCol("type_idx")
.fit(training))
あなたは、インデックス付きの列にエンコーダを適用する場合は、両方のデータセットに一貫性のエンコーディングを取得します:
(encoder.setInputCol("type_idx")
.transform(indexer.transform(training))
.show())
## +----+--------+-------------+
## |type|type_idx| encoded|
## +----+--------+-------------+
## | 0.0| 1.0|(3,[1],[1.0])|
## | 1.0| 0.0|(3,[0],[1.0])|
## | 1.0| 0.0|(3,[0],[1.0])|
## | 3.0| 2.0|(3,[2],[1.0])|
## +----+--------+-------------+
(エンコーダ .setInputCol(「type_idx 「) .transform(indexer.transform(テスト)) .SHOW())
## +----+--------+-------------+
## |type|type_idx| encoded|
## +----+--------+-------------+
## | 0.0| 1.0|(3,[1],[1.0])|
## | 1.0| 0.0|(3,[0],[1.0])|
## | 1.0| 0.0|(3,[0],[1.0])|
## | 1.0| 0.0|(3,[0],[1.0])|
## +----+--------+-------------+
ことに注意してくださいこの方法で取得したラベルは、入力データの値を反映しません。一貫性のあるエンコードが困難な要件である場合は、手動でスキーマを提供する必要があります:
from pyspark.sql.types import StructType, StructField, DoubleType
meta = {"ml_attr": {
"name": "type",
"type": "nominal",
"vals": ["0.0", "1.0", "3.0"]
}}
schema = StructType([StructField("type", DoubleType(), False, meta)])
training = sc.parallelize([(0.,), (1.,), (1.,), (3.,)]).toDF(schema)
testing = sc.parallelize([(0.,), (1.,), (1.,), (1.,)]).toDF(schema)
assert (
encoder.setInputCol("type").transform(training).first()[-1].size ==
encoder.setInputCol("type").transform(testing).first()[-1].size
)