我在Spark中使用FpGrowth算法生成了关联规则。 这是代码源:
public Class Data : MonoBehaviour
但是如何使用生成的规则进行预测呢?
答案 0 :(得分:1)
我自己仍在努力处理无类型的Dataframe-Rows,所以我无法告诉你应该如何使用这些规则。所以我只会告诉你如何使用它们。解决方案可能不是很惯用。
无论如何......以下是似乎有效的代码:
import org.apache.spark.ml.fpm._
val dataset = spark.createDataset(Seq(
"a b e","b c e", "a b", "a b e", "a b d e",
"a e c f", "a b f e", "a f c e",
"c d w x", "c x p d", "p q c d", "c p d r a",
"a c b d", "c d p q", "c r p d"
)).map(t => t.split(" ")).toDF("items")
val fpgrowth = new FPGrowth().setItemsCol("items").
setMinSupport(0.3).setMinConfidence(0.5)
val model = fpgrowth.fit(dataset)
val rules = model.associationRules
val exampleShoppingCart = Array("a", "b", "c", "d")
val proposals = rules.rdd.map{ rule =>
val antecedent = rule.getAs[Seq[String]]("antecedent")
val consequent = rule.getAs[Seq[String]]("consequent")
if (antecedent.forall(exampleShoppingCart.contains)) {
consequent.toSet
} else {
Set.empty[String]
}
}.reduce(_ ++ _)
val nonTrivialProposals = proposals.filterNot(exampleShoppingCart.contains)
println(
"Your shopping cart: " + exampleShoppingCart.mkString(",") +
"; You might also be interested in: " + nonTrivialProposals
)
// Output:
// Your shopping cart: a,b,c,d; You might also be interested in: Set(e, p)
简要说明:model.associationRules
为您提供了一个包含三列的Dataframe
:antecedent
,consequent
和confidence
。如果您要使用此类规则为特定交易exampleShoppingCart
的扩展程序提出建议,则必须检查antecedent
中的所有项目是否都出现在交易exampleShoppingCart
中。如果是这种情况,您可以将consequent
的所有元素添加到提案中。如果antecedent
中的某些项目未在事务中出现,则规则不匹配,并且您不提议任何内容(Set.empty
)。一旦您计算了所有规则中的所有提案,只需将它们简化为一个提案即可。最后,您可能希望删除事务中已包含的项目(这是filter
有用的内容)。
有趣的是找出如何将规则集减少到较小的等效规则集,例如,如果包含{x} => {y}
,则{x, z} => {y}
不会重复。
答案 1 :(得分:1)
但是如何使用生成的规则进行预测呢?
这很简单:
const arr = [{"label":"label-1","published":1,"draft":2,"id":"some1"},{"label":"label-1","published":2,"status":0,"draft":1,"id":"some4"},{"label":"label-2","published":1,"draft":14,"id":"some2"},{"label":"label-2","published":12,"status":0,"draft":14,"id":"some3"}]
const result = [...arr.reduce((m, o) => {
m.has(o.label) || m.set(o.label, {})
const obj = m.get(o.label)
Object.keys(o).forEach((k) => {
if(k === 'id') return
obj[k] = typeof o[k] === 'number' ? (obj[k] || 0) + o[k] : o[k]
})
return m
}, new Map()).values()]
console.log(result)