从 Spark Dataframe 创建标记点以及如何将名称列表传递给 VectorAssembler
Create labledpoints from Spark Dataframe & how to pass list of names to VectorAssembler
我还有其他问题
我正在尝试从数据框构建 labledPoints,其中我在列中具有特征和标签。这些特征都是带有 1/0 的布尔值。
这是数据框中的示例行:
| 0| 0| 0| 0| 0| 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1| 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1|
#Using the code from above answer,
#create a list of feature names from the column names of the dataframe
df_columns = []
for c in df.columns:
if c == 'is_item_return': continue
df_columns.append(c)
#using VectorAssembler for transformation, am using only first 4 columns names
assembler = VectorAssembler()
assembler.setInputCols(df_columns[0:5])
assembler.setOutputCol('features')
transformed = assembler.transform(df)
#mapping also from above link
from pyspark.mllib.regression import LabeledPoint
from pyspark.sql.functions import col
new_df = transformed.select(col('is_item_return'), col("features")).map(lambda row: LabeledPoint(row.is_item_return, row.features))
当我检查RDD的内容时,我得到了正确的标签,但是特征向量是错误的。
(0.0,(5,[],[]))
有人可以帮助我理解如何将现有数据框的列名作为特征名称传递给 VectorAssembler 吗?
这里没有任何问题。您得到的是 SparseVector
的字符串表示形式,它准确地反映了您的输入:
- 您取前五列 (
assembler.setInputCols(df_columns[0:5])
),输出向量的长度为 5
- 因为示例输入的第一列不包含非零条目
indices
和 values
数组为空
为了说明这一点,让我们使用 Scala,它提供了有用的 toSparse
/ toDense
方法:
import org.apache.spark.mllib.linalg.Vectors
val v = Vectors.dense(Array(0.0, 0.0, 0.0, 0.0, 0.0))
v.toSparse.toString
// String = (5,[],[])
v.toSparse.toDense.toString
// String = [0.0,0.0,0.0,0.0,0.0]
PySpark 也是如此:
from pyspark.ml.feature import VectorAssembler
df = sc.parallelize([
tuple([0.0] * 5),
tuple([1.0] * 5),
(1.0, 0.0, 1.0, 0.0, 1.0),
(0.0, 1.0, 0.0, 1.0, 0.0)
]).toDF()
features = (VectorAssembler(inputCols=df.columns, outputCol="features")
.transform(df)
.select("features"))
features.show(4, False)
## +---------------------+
## |features |
## +---------------------+
## |(5,[],[]) |
## |[1.0,1.0,1.0,1.0,1.0]|
## |[1.0,0.0,1.0,0.0,1.0]|
## |(5,[1,3],[1.0,1.0]) |
## +---------------------+
它还表明汇编程序根据非零条目的数量选择不同的表示形式。
features.flatMap(lambda x: x).map(type).collect()
## [pyspark.mllib.linalg.SparseVector,
## pyspark.mllib.linalg.DenseVector,
## pyspark.mllib.linalg.DenseVector,
## pyspark.mllib.linalg.SparseVector]
我还有其他问题
这是数据框中的示例行:
| 0| 0| 0| 0| 0| 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1| 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1|
#Using the code from above answer,
#create a list of feature names from the column names of the dataframe
df_columns = []
for c in df.columns:
if c == 'is_item_return': continue
df_columns.append(c)
#using VectorAssembler for transformation, am using only first 4 columns names
assembler = VectorAssembler()
assembler.setInputCols(df_columns[0:5])
assembler.setOutputCol('features')
transformed = assembler.transform(df)
#mapping also from above link
from pyspark.mllib.regression import LabeledPoint
from pyspark.sql.functions import col
new_df = transformed.select(col('is_item_return'), col("features")).map(lambda row: LabeledPoint(row.is_item_return, row.features))
当我检查RDD的内容时,我得到了正确的标签,但是特征向量是错误的。
(0.0,(5,[],[]))
有人可以帮助我理解如何将现有数据框的列名作为特征名称传递给 VectorAssembler 吗?
这里没有任何问题。您得到的是 SparseVector
的字符串表示形式,它准确地反映了您的输入:
- 您取前五列 (
assembler.setInputCols(df_columns[0:5])
),输出向量的长度为 5 - 因为示例输入的第一列不包含非零条目
indices
和values
数组为空
为了说明这一点,让我们使用 Scala,它提供了有用的 toSparse
/ toDense
方法:
import org.apache.spark.mllib.linalg.Vectors
val v = Vectors.dense(Array(0.0, 0.0, 0.0, 0.0, 0.0))
v.toSparse.toString
// String = (5,[],[])
v.toSparse.toDense.toString
// String = [0.0,0.0,0.0,0.0,0.0]
PySpark 也是如此:
from pyspark.ml.feature import VectorAssembler
df = sc.parallelize([
tuple([0.0] * 5),
tuple([1.0] * 5),
(1.0, 0.0, 1.0, 0.0, 1.0),
(0.0, 1.0, 0.0, 1.0, 0.0)
]).toDF()
features = (VectorAssembler(inputCols=df.columns, outputCol="features")
.transform(df)
.select("features"))
features.show(4, False)
## +---------------------+
## |features |
## +---------------------+
## |(5,[],[]) |
## |[1.0,1.0,1.0,1.0,1.0]|
## |[1.0,0.0,1.0,0.0,1.0]|
## |(5,[1,3],[1.0,1.0]) |
## +---------------------+
它还表明汇编程序根据非零条目的数量选择不同的表示形式。
features.flatMap(lambda x: x).map(type).collect()
## [pyspark.mllib.linalg.SparseVector,
## pyspark.mllib.linalg.DenseVector,
## pyspark.mllib.linalg.DenseVector,
## pyspark.mllib.linalg.SparseVector]