【问题标题】:IllegalArgumentException: Column must be of type struct<type:tinyint,size:int,indices:array<int>,values:array<double>> but was actually double.'IllegalArgumentException:列必须是 struct<type:tinyint,size:int,indices:array<int>,values:array<double>> 类型,但实际上是双精度的。
【发布时间】:2020-07-18 05:40:24
【问题描述】:

我有一个包含多个分类列的数据框。我正在尝试使用两列之间的内置函数查找卡方统计信息:

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)

你能帮我解决这个问题吗?

【问题讨论】:

    标签: apache-spark pyspark apache-spark-ml


    【解决方案1】:

    spark-ml 不是典型的统计库。它非常面向机器学习。因此,它假定您希望在标签和特征或一组特征之间运行测试。

    因此,与训练模型时类似,您需要根据标签组装要测试的特征。

    在您的情况下,您可以按如下方式组装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)
    

    【讨论】:

      【解决方案2】:

      为了扩展 Oli 的答案,Spark ML 期望将功能存储在 pyspark.ml.linalg.Vector 的实例中。有两种向量:

      • 密集向量 - 这些是简单的数组,包含向量的所有元素,包括全零,并由 Spark 数组类型 array&lt;T&gt; 表示
      • 稀疏向量 - 这些是更复杂的数据结构,仅存储向量的非零元素,允许紧凑存储仅包含少量非零元素的巨大向量。稀疏向量具有三个组成部分:
        • 一个整数size,表示向量的全维度
        • 一个 indices 数组,用于保存非零元素的位置
        • 一个 values 数组,用于保存非零元素的值

      这两种向量类型实际上都使用稀疏向量的结构来表示,而对于密集向量,indices 数组未使用,values 存储所有值。第一个结构元素type用于区分这两种。

      因此,如果您看到需要 struct&lt;type:tinyint,size:int,indices:array&lt;int&gt;,values:array&lt;double&gt;&gt; 的错误,这意味着您应该传递 pyspark.ml.linagl.Vector 的实例,而不仅仅是数字。

      为了产生Vectors,您可以使用pyspark.ml.feature.VectorAssembler将一个或多个独立的特征列组装成一个向量列,或者使用工厂方法Vectors.dense()(用于密集向量)和@手动构造它们工厂对象pyspark.ml.linalg.Vectors 的987654335@(用于稀疏向量)。使用 VectorAssembler 可能更容易也更快,因为它是在 Scala 中实现的。要使用显式矢量创建,请参阅 PySpark 文档中的 example for ChiSquareTest

      【讨论】:

        猜你喜欢
        • 2021-07-18
        • 2018-09-18
        • 2018-10-05
        • 1970-01-01
        • 2016-12-31
        • 2016-10-19
        • 2021-08-28
        • 2012-01-13
        • 2014-12-09
        相关资源
        最近更新 更多