PySpark&Tensorflow-虚拟编码字符串数据

问题描述 投票:0回答:1

我想对数据进行虚拟编码(或类似)以将其提供给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|
+---+---+-----+-------+--------+--------+-------------+-------------+-------------+-------------+

但是我不知道这是否也是一件好事。

python apache-spark keras pyspark
1个回答
0
投票

我将使用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一起工作。

© www.soinside.com 2019 - 2024. All rights reserved.