【问题标题】:How to transform vector into array for Frequent Pattern Analysis如何将向量转换为数组以进行频繁模式分析
【发布时间】:2018-07-02 00:37:57
【问题描述】:

我正在应用频繁的模式分析,需要一些有关输入类型的帮助。

首先,我使用 stringindexer 将分类变量转换为数字。

之后,我为每个分类值创建一个唯一编号,如下所示:

add_100=udf(lambda x:x+100,returnType=FloatType())
add_1000=udf(lambda x:x+1000,returnType=FloatType())
df = df.select('cat_var_1', add_1000('cat_var_2').alias('cat_var_2_final'), add_10000('cat_var_3').alias('cat_var_3_final'))

我的下一步是创建一个具有特征的向量:

featuresCreator = ft.VectorAssembler(inputCols=[col for col in features], outputCol='features')
df=featuresCreator.transform(df)

最后,我尝试拟合我的模型:

from pyspark.ml.fpm import FPGrowth
fpGrowth = FPGrowth(itemsCol="features", minSupport=0.5, minConfidence=0.6)

model = fpGrowth.fit(df)

并得到这个错误:

u'requirement failed: 输入列必须是ArrayType,但是得到了 org.apache.spark.ml.linalg.VectorUDT@3bfc3ba7.

那么,问题是,如何将向量转换为数组?或者,我还有其他方法可以解决这个问题吗?

【问题讨论】:

    标签: python apache-spark machine-learning pyspark user-defined-functions


    【解决方案1】:

    FPGrowth 采用 Array 而不是 Vector。由于VectorAssembler 会给你一个向量作为输出,一个可能且简单的解决方案是使用UDF 将该输出转换为一个数组。

    to_array = udf(lambda x: x.toArray(), ArrayType(DoubleType()))
    df = df.withColumn('features', to_array('features'))
    

    更好的解决方案是一次做所有事情,即根本不使用VectorAssembler。这样做的好处是根本不需要UDF,因此速度更快。这利用了 pyspark 中内置的 array 函数。

    from pyspark.sql import functions as F
    df2 = df.withColumn('features', F.array('cat_var_1', 'cat_var_2', 'cat_var_3'))
    

    【讨论】:

    • @Toutsos:添加了一个新的、改进的解决方案,无需使用 UDF,它应该更快。
    • 新解决方案似乎对我不起作用。我收到一个错误:TypeError: array() 最多接受 2 个参数(给定 8 个)
    • @Toutsos:确保使用正确的array,使用from pyspark.sql.functions import array
    • 这样做了,还是不行:(。出于某种原因,它使用了python ..也许是它的python2造成了这个混乱。
    • 感谢您的回复!出于好奇,我会尝试一下!
    【解决方案2】:

    我认为,您不需要 udf 来创建唯一编号。或者您可以直接使用 withColumn ,

    df = df.withColumn('cat_var_2_final',df['cat_var_2']+100).withColumn('cat_var_3_final',df['cat_var_3']+1000)
    

    另外,如果您只为 FPGrowth 模型获取这些数据,我们也可以跳过向量组装器并使用 udf as 直接创建 Array 特征,

    udf1 = udf(lambda c1,c2,c3 : (c1,c2,c3),ArrayType(IntegerType()))
    df = df.withColumn('features',udf1(df['cat_var_1'],df['cat_var_2_final'],df['cat_var_3_final']))
    

    【讨论】:

    • 你说你不需要UDF,但你创建了一个UDF。我很困惑...
    • 我的意思是,不需要 udf 来为来自 stringIndexer 的分类数据创建唯一编号。 udf 他的代码中的任何内容。
    • 由于某种原因,Shaido 的回答不起作用,但这个回答起作用了。谢谢你的信息。
    • @eliasah 我回答的是 Toutsos 的问题,而不是 Shaido。
    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    相关资源
    最近更新 更多