FPGrowth是一种数据频繁项挖掘算法,著名的应用有啤酒和尿布的例子。通过分析购物篮物品数据,挖掘出几种物品经常出现在一起的组合,在用户选取其中一个物品后,通过频繁项为其推荐其他有一定关联的物品,实现个性化服务。
简单概念:
支持度:如上文中1000条购物篮数据中,含有尿布的有600条,则尿布的支持度为600/1000*100%=60%
置信度:如上文中同含有尿布的有600条,同时含有啤酒和尿布的有300条,则尿布 ==》啤酒的置信度为300/600*100%=50%
FPGrowth算法过程
购物篮数据:
0 a,b,c
1 b,c
2 a,d
3 b,c,d
4 c,d
支持度为40%,就是支持度小于40%的除去,不考虑。
5*40%=2
第一步 扫描整个购物篮数据,并按照支持度从高到底排序
a b c d
2 3 4 3
a的支持度小于40%,除去
排序后得到:
c 4
b 3
d 3
第二步 构造Tree
从第一条记录开始,到最后一条记录结束,进行过滤淘汰的物品,然后按照支持度从高到底对物品进行排序,若根节点的儿子不含有过滤排序后的第一个物品,则需要重新建立儿子节点,直到最后一条记录。
(还需建立表头和索引,可以进行百度。)
O
c(2) d(1)
b(2) d(1)
d(1)
例如寻找与d组合的频繁项时,遍历树,寻找所以包含d的路径,c=>b=>d(1),c=>d(1),d(1)
通过置信度,过滤不符合项。
发现与d经常组合的有c,因此在用户选取d后,可以给用户推荐c物品。
Spark平台使用FPGrowth算法:
测试数据地址:链接: https://pan.baidu.com/s/113Vb704n00neylvj0nkEuA 密码: rtrs
import org.apache.spark.mllib.fpm.FPGrowth import org.apache.spark.sql.SparkSession object FPGrowthTest { def main(args : Array[String]): Unit={ val spark = SparkSession.builder().appName("FPGrowthTest").master("local[*]").getOrCreate() val path = "file:/home/enche/Downloads/Groceries.txt" val data = spark.read.textFile(path).rdd //去除包含items行 val dataNoHead = data.filter(line=> !line.contains("items")) // 过滤出只含物品名称的数据 val dataS = dataNoHead.map(line => line.split("\\{")) val dataGoods = dataS.map(data => data(1).replaceAll("}\"","")) // 转成fpgrowth.run方法所需要的格式。 val fpData = dataGoods.map(line => line.trim().split(",")) //设置支持度和分区 val fpGrowth = new FPGrowth().setMinSupport(0.05).setNumPartitions(4) val fpModel = fpGrowth.run(fpData) val test = fpData.take(3)(2) // 设置置信度 val aid = 0.1 //使用了累加器,获取executor变量。 var goodsFreq = spark.sparkContext.longAccumulator val freqItemsets = fpModel.freqItemsets.cache() //获取支持度 freqItemsets.foreach{f => if(f.items.mkString == test.mkString){ goodsFreq.add(f.freq) println("value1:"+goodsFreq) } } println("value2:"+goodsFreq) var result = goodsFreq.value //进行置信度过滤 freqItemsets.foreach{f => if(f.items.mkString.contains(test.mkString) && f.items.length>test.length){ var conf = f.freq.toDouble/result.toDouble if( conf > aid){ for(i <- 0 until f.items.length){ for(i <- f.items){} println(f.items(i)+"====="+conf) } } } } } }