我一直在尝试为spark中的某些选定用户生成推荐内容。这是通过使用每个乘积因子(n个浮点数的向量)生成用户因子(n个浮点数的向量),然后按顺序排序来完成的。
所以,假设我的客户因素为(customerId, Array[Float])
,我的产品系数为(productId, Array[Float])
。我必须为每个客户创建每个产品的分数,并生成(customerId, productId, score)
,其中保留每个客户的前N个结果。所以我这样做:
val customers = ... // (customerId, Array[Float])
val products = ... // (productId, Array[Float])
val combination = customers.cartesian(products)
val result = combination.map(x => (combination._1._1, combination._2._1,
dotProd(combination._1._2, combination._2._2))
... then filter top N for each customer using dataframe
但这需要很长时间,其中一个原因是笛卡尔结果使数据量变得庞大,为每个客户重复相同的产品因素。
正如您可以看到这100 TB客户和300K产品的11 TB数据。这是创建的DAG(我选择并保留分数的前N个,因此分区):
你会建议什么?如何改进流程来绕过巨大的IO?
由于
最后,在48个核心上运行它需要10个小时。 并拥有80TB的IO!
我怀疑解决方案是收集然后广播两个RDD并仅在ID上创建笛卡尔,然后查找因子。这将大大减少IO。
我会试一试。