2016-04-04 6 views
0

Aynı sütunlarla iki tane DataFrames var ve kategorik bir sütunu Tek Sıcak Kodlama kullanarak bir vektöre dönüştürmek istiyorum. Sorun, test setindeki eğitim setindeki 3 benzersiz değerlerin olabileceğinden şeklindedir. OneHotEncoder eğitim ve test grubu farklı uzunlukta (vektörün her bir elemanı, bir tek değer mevcudiyetini temsil eder çünkü) sahip vektörler oluşturur Bu durumdaKıvılcım: Aynı OneHotEncoder'ı birden çok veri çerçevesinde kullanın

Training Set:  Test Set: 

+------------+  +------------+ 
| Type |  | Type | 
+------------+  +------------+ 
|  0  |  |  0  | 
|  1  |  |  1  | 
|  1  |  |  1  | 
|  3  |  |  1  | 
+------------+  +------------+ 

.

DataFrames numaralı telefondan aynı OneHotEncoder kullanılabilir mi? fit işlev yok ve bu yüzden bunu nasıl yapabileceğimi bilmiyorum. Teşekkürler.

cevap

4

OneHotEncoder tek başına kullanılmak üzere tasarlanmamıştır. Bunun yerine, sütun meta verilerini kaldırabileceği Pipeline'un bir parçası olmalıdır. Örneğin aşağıdaki düşünün: Eğer kodlayıcı kullandığınızda

training = sc.parallelize([(0.,), (1.,), (1.,), (3.,)]).toDF(["type"]) 
testing = sc.parallelize([(0.,), (1.,), (1.,), (1.,)]).toDF(["type"]) 

doğrudan bağlam hakkında hiçbir bilgiye sahip:

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])| 
## +----+-------------+ 

Şimdi gerekli meta verileri eklemenize olanak tanır. Bu StringIndexer kullanarak örneğin şunlar olabilir:

(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])| 
## +----+--------+-------------+ 

(kodlayıcı .setInputCol ("type_idx: Eğer endeksli sütun üzerinde kodlayıcı uygularsanız

indexer = (StringIndexer() 
    .setInputCol("type") 
    .setOutputCol("type_idx") 
    .fit(training)) 

hem veri kümeleri üzerinde tutarlı kodlama alırsınız ") .transform (indexer.transform (test)) .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])| 
## +----+--------+-------------+ 

unutmayınız Bu şekilde aldığınız etiketler giriş verilerindeki değerleri yansıtmaz. Tutarlı kodlama el şema vermelidir sert gereklilik ise:

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 
) 
0

Biz meta matrisi oluşturma ve çoklu OneHotEncoders oluşturarak birden fazla sütunlu veri kümesi için bu uzatabilirsiniz. Bu adımlar boru hattında sahnelenebilir.