IllegalArgumentException: Column 必须是 struct<type:tinyint,size:int,indices:array<int>,values:array<double>> 类型,但实际上是 double。
IllegalArgumentException: Column must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.'
我有一个包含多个分类列的数据框。我正在尝试使用两列之间的内置函数查找卡方统计数据:
from pyspark.ml.stat import ChiSquareTest
r = ChiSquareTest.test(df, 'feature1', 'feature2')
但是,它给了我错误:
IllegalArgumentException: 'requirement failed: Column feature1 must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.'
feature1
的数据类型是:
feature1: double (nullable = true)
你能帮我解决这方面的问题吗?
spark-ml
不是典型的统计库。它非常面向机器学习。因此,它假设您想要 运行 标签和特征或一组特征之间的测试。
因此,与训练模型时类似,您需要assemble根据标签测试要测试的特征。
对于你的情况,你可以 assemble feature1
如下:
from pyspark.ml.stat import ChiSquareTest
from pyspark.ml.feature import VectorAssembler
data = [(1, 2), (3, 4), (2, 1), (4, 3)]
df = spark.createDataFrame(data, ['feature1', 'feature2'])
assembler = VectorAssembler().setInputCols(['feature1']).setOutputCol('features')
ChiSquareTest.test(assembler.transform(df), 'features', 'feature2').show(false)
以防万一,scala中的代码:
import org.apache.spark.ml.stat.ChiSquareTest
import org.apache.spark.ml.feature.VectorAssembler
val df = Seq((1, 2, 3), (1, 2, 3), (4, 5, 6), (6, 5, 4))
.toDF("features", "feature2", "feature3")
val assembler = new VectorAssembler()
.setInputCols(Array("feature1"))
.setOutputCol("features")
ChiSquareTest.test(assembler.transform(df), "features", "feature2").show(false)
为了扩展 Oli 的回答,Spark ML 希望将特征存储在 pyspark.ml.linalg.Vector
的实例中。有两种向量:
- 密集向量 - 这些只是包含向量所有元素(包括所有零)的数组,并由 Spark 数组类型表示
array<T>
- 稀疏向量 - 那些更复杂的数据结构,只存储向量的非零元素,允许紧凑存储只有少量非零元素的巨大向量。稀疏向量具有三个组成部分:
- 表示向量全维的整数
size
- 保存非零元素位置的
indices
数组
- 保存非零元素值的
values
数组
这两种向量类型实际上都使用稀疏向量的结构表示,而对于密集向量,indices
数组未被使用,values
存储所有值。第一个结构元素type
用来区分这两种。
因此,如果您看到预期 struct<type:tinyint,size:int,indices:array<int>,values:array<double>>
的错误,这意味着您应该传递 pyspark.ml.linagl.Vector
的实例,而不仅仅是数字。
为了生成Vector
s,您可以使用pyspark.ml.feature.VectorAssembler
到assemble一个或多个独立的特征列到一个向量列中,或者使用工厂方法手动构造它们工厂对象 pyspark.ml.linalg.Vectors
的 Vectors.dense()
(对于密集向量)和 Vectors.sparse()
(对于稀疏向量)。使用 VectorAssembler
可能更容易也更快,因为它是在 Scala 中实现的。要使用显式向量创建,请参阅 PySpark 文档中的 example for ChiSquareTest
。
我有一个包含多个分类列的数据框。我正在尝试使用两列之间的内置函数查找卡方统计数据:
from pyspark.ml.stat import ChiSquareTest
r = ChiSquareTest.test(df, 'feature1', 'feature2')
但是,它给了我错误:
IllegalArgumentException: 'requirement failed: Column feature1 must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.'
feature1
的数据类型是:
feature1: double (nullable = true)
你能帮我解决这方面的问题吗?
spark-ml
不是典型的统计库。它非常面向机器学习。因此,它假设您想要 运行 标签和特征或一组特征之间的测试。
因此,与训练模型时类似,您需要assemble根据标签测试要测试的特征。
对于你的情况,你可以 assemble feature1
如下:
from pyspark.ml.stat import ChiSquareTest
from pyspark.ml.feature import VectorAssembler
data = [(1, 2), (3, 4), (2, 1), (4, 3)]
df = spark.createDataFrame(data, ['feature1', 'feature2'])
assembler = VectorAssembler().setInputCols(['feature1']).setOutputCol('features')
ChiSquareTest.test(assembler.transform(df), 'features', 'feature2').show(false)
以防万一,scala中的代码:
import org.apache.spark.ml.stat.ChiSquareTest
import org.apache.spark.ml.feature.VectorAssembler
val df = Seq((1, 2, 3), (1, 2, 3), (4, 5, 6), (6, 5, 4))
.toDF("features", "feature2", "feature3")
val assembler = new VectorAssembler()
.setInputCols(Array("feature1"))
.setOutputCol("features")
ChiSquareTest.test(assembler.transform(df), "features", "feature2").show(false)
为了扩展 Oli 的回答,Spark ML 希望将特征存储在 pyspark.ml.linalg.Vector
的实例中。有两种向量:
- 密集向量 - 这些只是包含向量所有元素(包括所有零)的数组,并由 Spark 数组类型表示
array<T>
- 稀疏向量 - 那些更复杂的数据结构,只存储向量的非零元素,允许紧凑存储只有少量非零元素的巨大向量。稀疏向量具有三个组成部分:
- 表示向量全维的整数
size
- 保存非零元素位置的
indices
数组 - 保存非零元素值的
values
数组
- 表示向量全维的整数
这两种向量类型实际上都使用稀疏向量的结构表示,而对于密集向量,indices
数组未被使用,values
存储所有值。第一个结构元素type
用来区分这两种。
因此,如果您看到预期 struct<type:tinyint,size:int,indices:array<int>,values:array<double>>
的错误,这意味着您应该传递 pyspark.ml.linagl.Vector
的实例,而不仅仅是数字。
为了生成Vector
s,您可以使用pyspark.ml.feature.VectorAssembler
到assemble一个或多个独立的特征列到一个向量列中,或者使用工厂方法手动构造它们工厂对象 pyspark.ml.linalg.Vectors
的 Vectors.dense()
(对于密集向量)和 Vectors.sparse()
(对于稀疏向量)。使用 VectorAssembler
可能更容易也更快,因为它是在 Scala 中实现的。要使用显式向量创建,请参阅 PySpark 文档中的 example for ChiSquareTest
。