我想对数据进行虚拟编码(或类似)以将其提供给Keras。
现在,我用Spark处理表格数据,然后用Keras训练它。
事情是我有一个包含字符串数据的列,无法将其直接提供给Keras,所以我需要将其转换为整数。
我已经做过StringIndexer
+ OneHotEncoding
,但是问题是我得到了一列稀疏向量,这不是我想要的,我的意思是交给Keras。
data = sqlContext.createDataFrame(
[(1, "a", 23.0, "mak"), (3, "B", -23.0, "kaks"), (3, "a", -22.0, "kaks"), (3, "a", -22.0, "chochon")], ("x1", "x2", "x3", "x4"))
data.show()
+---+---+-----+-------+--------+--------+-------------+-------------+
| x1| x2| x3| x4|x2_index|x4_index| x2_vector| x4_vector|
+---+---+-----+-------+--------+--------+-------------+-------------+
| 1| a| 23.0| mak| 0.0| 1.0|(1,[0],[1.0])|(2,[1],[1.0])|
| 3| B|-23.0| kaks| 1.0| 0.0| (1,[],[])|(2,[0],[1.0])|
| 3| a|-22.0| kaks| 0.0| 0.0|(1,[0],[1.0])|(2,[0],[1.0])|
| 3| a|-22.0|chochon| 0.0| 2.0|(1,[0],[1.0])| (2,[],[])|
+---+---+-----+-------+--------+--------+-------------+-------------+
您有什么事要做才能为keras提供“良好的数据”?
I though something like that :
+---+---+-----+-------+--------+--------+-------------+-------------+-------------+-------------+
| x1| x2| x3| x4|x2_index|x4_index| x2_vector| x4_0| x4_1| x4_2|
+---+---+-----+-------+--------+--------+-------------+-------------+-------------+-------------+
| 1| a| 23.0| mak| 0.0| 1.0|(1,[0],[1.0])| 1| 0| 0|
| 3| B|-23.0| kaks| 1.0| 0.0| (1,[],[])| 0| 1| 0|
| 3| a|-22.0| kaks| 0.0| 0.0|(1,[0],[1.0])| 0| 1| 0|
| 3| a|-22.0|chochon| 0.0| 2.0|(1,[0],[1.0])| 0| 0| 1|
+---+---+-----+-------+--------+--------+-------------+-------------+-------------+-------------+
但是我不知道这是否也是一件好事。
我将使用x4
列部分复制您的想法。了解它后,它将帮助您实施自己的解决方案。
代码
from pyspark.ml.feature import StringIndexer
from pyspark.ml.feature import OneHotEncoderEstimator
data = spark.createDataFrame(
[('mak',), ('kaks',), ('kaks',), ('chochon',)], ('x4',))
indexer = StringIndexer(inputCol='x4', outputCol='x4_index')
indexed = indexer.fit(data).transform(data)
encoder = OneHotEncoderEstimator(inputCols=['x4_index'],outputCols=['x4_vector'], dropLast=False)
encoded = encoder.fit(indexed).transform(indexed)
#at this stage, you have
#encoded.show()
#+-------+--------+-------------+
#| x4|x4_index| x4_vector|
#+-------+--------+-------------+
#| mak| 2.0|(3,[2],[1.0])|
#| kaks| 0.0|(3,[0],[1.0])|
#| kaks| 0.0|(3,[0],[1.0])|
#|chochon| 1.0|(3,[1],[1.0])|
#+-------+--------+-------------+
#further process it one more step to get what you have in mind
def mfunc(row):
return [row['x4'],row['x4_index']] + list(map(int,row['x4_vector'].toArray().tolist()))
encoded.rdd.map(mfunc).toDF(['x4','x4_index', 'x4_0', 'x4_1', 'x4_2']).show()
#+-------+--------+----+----+----+
#| x4|x4_index|x4_0|x4_1|x4_2|
#+-------+--------+----+----+----+
#| mak| 2.0| 0| 0| 1|
#| kaks| 0.0| 1| 0| 0|
#| kaks| 0.0| 1| 0| 0|
#|chochon| 1.0| 0| 1| 0|
#+-------+--------+----+----+----+
#alternatively, if you want to input a dense vector to keras, then use this
from pyspark.mllib.linalg import DenseVector
def mfunc1(row):
return [row['x4'],row['x4_index']] + [list(map(int, DenseVector(row['x4_vector'])))]
encoded.rdd.map(mfunc1).toDF(['x4','x4_index', 'x4_dense']).show()
#+-------+--------+---------+
#| x4|x4_index| x4_dense|
#+-------+--------+---------+
#| mak| 2.0|[0, 0, 1]|
#| kaks| 0.0|[1, 0, 0]|
#| kaks| 0.0|[1, 0, 0]|
#|chochon| 1.0|[0, 1, 0]|
#+-------+--------+---------+
我希望其中一个可以和keras一起工作。