spark2.4 ML聚类数据源结构问题

博客主要讨论了ML使用数据源时的格式问题,其要求向量features格式nullable=false,但多数数据源读取到dataframe时StructField默认是nullable=true,直接聚类fit会报错。介绍了手动创建dataframe满足要求,还提及改用MLLIB及使用时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:ML使用的数据源要求向量features格式必须是nullable=false,比如这样:

StructType(StructField(id,IntegerType,false), StructField(features,ArrayType(DoubleType,false),true))
[id: int, features: array<double>]

然而,我们大部分数据源(如ALS的itemFactors)读取到dataframe时候StructField默认都是nullable=true,若直接将源df聚类fit如:

val kModel=new KMeans()
  .setK(3)
  .setFeaturesCol("features")
  .setPredictionCol("prediction")
  .fit(df)

则会报错:Column features must be .... array<float> but was actually of type array<float>

咋看其实我们的array<float>明明属于要求的类型,其实这个报错信息是不完善的;

 

那怎么才能正确运行呢?如下手动创建dataframe则满足nullable=false:

val df: DataFrame = spark.sqlContext.createDataFrame(Seq(
  (6, Array(1.6, 0.6, 0.2))
)).toDF("id", "features")

若将(6, Array(1.6, 0.6, 0.2))存到文件123.txt然后通过

val df=spark.sqlContext.read.format("json").load(kmPath+"123.txt").selectExpr("cast(id as int)","cast(features as array<double>) ") 读出来则nullable=true,直接fit就会报上面那个错!这就比较恶心了,然后我们看官网给的例子使用的libsvm格式文件,参考官网介绍: http://spark.apache.org/docs/latest/ml-clustering.html

 

没办法,后面只能改用MLLIB了,有一点需要注意的是alsModel.itemFactors特征向量部分不能直接r.getAs[Array[Double]](1),如:

val alsModel= ALSModel.load(alsPath)
val songDF: DataFrame =alsModel.itemFactors
val songRDD =songDF.map(r=> {
//      (r.getInt(0), Vectors.dense( r.getAs[Array[Double]](1) ) ) //不能直接这样
  val f: mutable.WrappedArray[Float] =r.getAs[mutable.WrappedArray[Float]](1)
  (r.getInt(0), Vectors.dense( f.map(_.toDouble).toArray ))
}).rdd

否则后面训练的时候会报一个不完整的错,说要求向量为Array[Double]...:

val kmodel=new KMeans()
  .setK(10)
  .run(songRDD.map(_._2))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值