如何将矢量转换为数组进行频繁模式分析

时间:2018-01-23 08:51:42

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

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

首先,我使用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。

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

2 个答案:

答案 0 :(得分:2)

FPGrowth采用数组而不是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'))

答案 1 :(得分: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模型提供这些数据,我们也可以跳过vectorassembler并使用udf直接创建数组特征,

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']))