python - gbt - Ajustar un marco de datos en randomForest pyspark
spark random forest regression (2)
Tengo un DataFrame
que se ve así:
+--------------------+------------------+
| features| labels |
+--------------------+------------------+
|[-0.38475, 0.568...]| label1 |
|[0.645734, 0.699...]| label2 |
| ..... | ... |
+--------------------+------------------+
Ambas columnas son de tipo String (StringType ()), me gustaría ajustar esto en spark ml randomForest. Para hacerlo, necesito convertir las columnas de características en un vector que contenga flotadores. ¿Alguien tiene alguna idea de cómo hacerlo?
Si entiendo correctamente tu pregunta, tienes dos columnas que contienen cadenas que quieres convertir en dobles. No tengo ninguna oportunidad de probar mi código en este momento, sin embargo, creo que puedes hacer algo como esto. La solución usa una user defined function
(udf).
import org.apache.spark.sql.functions._
val strToDoubleVec = udf((str: String) => {
Vectors.toDense(str.split(",").map(_.trim.toDouble).toArray)
})
val df = data.withColumn("features", vecToDouble($(features)))
.withColumn("label", $"labels").cast(DoubleType))
Supuse que la primera de las columnas era una sola cadena, en el caso de una lista de cadenas, simplemente puede modificar la udf.
Si está utilizando Spark 2.x , creo que esto es lo que necesita:
from pyspark.sql.functions import udf
from pyspark.mllib.linalg import Vectors
from pyspark.ml.linalg import VectorUDT
from pyspark.ml.feature import StringIndexer
df = spark.createDataFrame([("[-0.38475, 0.568]", "label1"), ("[0.645734, 0.699]", "label2")], ("features", "label"))
def parse(s):
try:
return Vectors.parse(s).asML()
except:
return None
parse_ = udf(parse, VectorUDT())
parsed = df.withColumn("features", parse_("features"))
indexer = StringIndexer(inputCol="label", outputCol="label_indexed")
indexer.fit(parsed).transform(parsed).show()
## +----------------+------+-------------+
## | features| label|label_indexed|
## +----------------+------+-------------+
## |[-0.38475,0.568]|label1| 0.0|
## |[0.645734,0.699]|label2| 1.0|
## +----------------+------+-------------+
Con Spark 1.6 , no es muy diferente:
from pyspark.sql.functions import udf
from pyspark.ml.feature import StringIndexer
from pyspark.mllib.linalg import Vectors, VectorUDT
df = sqlContext.createDataFrame([("[-0.38475, 0.568]", "label1"), ("[0.645734, 0.699]", "label2")], ("features", "label"))
parse_ = udf(Vectors.parse, VectorUDT())
parsed = df.withColumn("features", parse_("features"))
indexer = StringIndexer(inputCol="label", outputCol="label_indexed")
indexer.fit(parsed).transform(parsed).show()
## +----------------+------+-------------+
## | features| label|label_indexed|
## +----------------+------+-------------+
## |[-0.38475,0.568]|label1| 0.0|
## |[0.645734,0.699]|label2| 1.0|
## +----------------+------+-------------+
Vectors
tiene una función de parse
que puede ayudarlo a lograr lo que está tratando de hacer.