Apache spark 基于预排序输入的Spark特征向量变换
我在HDFS上以制表符分隔的文件中有一些数据,如下所示:Apache spark 基于预排序输入的Spark特征向量变换,apache-spark,apache-spark-mllib,naivebayes,Apache Spark,Apache Spark Mllib,Naivebayes,我在HDFS上以制表符分隔的文件中有一些数据,如下所示: label | user_id | feature ------------------------------ pos | 111 | www.abc.com pos | 111 | www.xyz.com pos | 111 | Firefox pos | 222 | www.example.com pos | 222 | www.xyz.com pos | 222
label | user_id | feature
------------------------------
pos | 111 | www.abc.com
pos | 111 | www.xyz.com
pos | 111 | Firefox
pos | 222 | www.example.com
pos | 222 | www.xyz.com
pos | 222 | IE
neg | 333 | www.jkl.com
neg | 333 | www.xyz.com
neg | 333 | Chrome
我需要对其进行转换,为每个用户id创建一个特征向量,以训练org.apache.spark.ml.classification.NaiveBayes
模型
我目前的做法基本上是:
val featurization = (vals: (String,Iterable[Row])) => {
// create a Seq of all the feature indices
// Note: the indexing was done in a previous step not shown
val seq = vals._2.map(x => (x.getDouble(1).toInt,1.0D)).toSeq
// create the sparse vector
val featureVector = Vectors.sparse(maxIndex, seq)
// convert the string label into a Double
val label = if (vals._2.head.getString(2) == "pos") 1.0 else 0.0
(label, vals._1, featureVector)
}
d.rdd
.groupBy(_.getString(1))
.map(featurization)
.toDF("label","user_id","features")
让我们从
如果我在磁盘上的数据保证按密钥进行预排序,该密钥将用于组聚合或缩减,Spark有没有办法利用这一点
视情况而定。若您应用的操作可以从映射端聚合中获益,那个么通过预排序数据而无需在代码中进行任何进一步的干预,您可以获得很多好处。共享同一密钥的数据应该位于相同的分区上,并且可以在洗牌之前在本地聚合
不幸的是,在这种特殊情况下,它不会有多大帮助。即使您启用地图端聚合(groupBy(Key)
没有使用is,因此您需要自定义实现)或聚合特征向量(您可以在我的答案中找到一些示例),也没有多少好处。您可以在这里和那里保存一些工作,但仍然需要在节点之间传输所有索引
如果你想获得更多,你就必须多做一点工作。我可以看到两种利用现有订单的基本方法:
NLineInputFormat
,然后将mapPartitions
应用于聚合记录
这无疑是一个更详细的解决方案,但不需要额外的Spark洗牌groupBy
使用自定义分区器。据我所知,使用rangePartitioner
应该可以正常工作,但请确保您可以尝试以下过程:
- 使用
查找每个分区的最小/最大id李>mapPartitionsWithIndex
- 创建一个分区器,它可以保持最小值非常有洞察力。谢谢你的帮助。