推荐系统系列:商品关联分析

商品关联分析

关联
relevance: 主要用在互联网的内容和文档上,比如搜索引擎算法文档中之间的关联性。

association: 用在实际的事物之上,比如电子商务网站上的商品之间的关联度。

支持度(support):数据集中包含某几个特定项的概率。
比如在1000次的商品交易中同时出现了啤酒和尿布的次数是50次,那么此关联的支持度为5%。

置信度(Confidence):在数据集中已经出现A时,B发生的概率,置信度的计算公式是 :A与B同时出现的概率/A出现的概率。


假设有10000个人购买了产品,其中购买A产品的人是1000个,购买B产品的人是2000个,AB同时购买的人是800个。

支持度指的是关联的产品(假定A产品和B产品关联)同时购买的人数占总人数的比例,即800/10000=8%,有8%的用户同时购买了A和B两个产品;

可信度指的是在购买了一个产品之后购买另外一个产品的可能性,例如购买了A产品之后购买B产品的可信度=800/1000=80%,即80%的用户在购买了A产品之后会购买B产品;

提升度就是在购买A产品这个条件下购买B产品的可能性与没有这个条件下购买B产品的可能性之比,没有任何条件下购买B产品可能性=2000/10000=20%,那么提升度=80%/20%=4。


数据关联是数据库中存在的一类重要的可被发现的知识。若两个或多个变量的取值之间存在某种规律性,就称为关联。关联可分为简单关联、时序关联、因果关联等。关联分析的目的是找出数据库中隐藏的关联网。有时并不知道数据库中数据的关联函数,或者即使知道也是不确定的,因此关联分析生成的规则带有置信度。

关联规则挖掘的一个典型例子是购物篮分析(MBA,Market Basket Analysis)。关联规则研究有助于发现交易数据库中不同商品(项)之间的联系,找出顾客购买行为模式,如购买了某一商品对购买其他商品的影响。分析结果可以应用于商品货架布局、货存安排以及根据购买模式对用户进行分类。

关联规则的发现过程可分为如下两步:

第一步是迭代识别所有的频繁项目集(Frequent Itemsets),要求频繁项目集的支持度不低于用户设定的最低值;

第二步是从频繁项目集中构造置信度不低于用户设定的最低值的规则,产生关联规则。识别或发现所有频繁项目集是关联规则发现算法的核心,也是计算量最大的部分。

最小支持度(min-support)和最小置信度(min-confidence)
支持度和置信度两个阈值是描述关联规则的两个最重要的概念。一项目组出现的频率称为支持度,反映关联规则在数据库中的重要性。而置信度衡量关联规则的可信程度。如果某条规则同时满足最小支持度(min-support)和最小置信度(min-confidence),则称它为强关联规则。

关联规则数据挖掘阶段

第一阶段必须从原始资料集合中,找出所有高频项目组(Large Itemsets)。高频的意思是指某一项目组出现的频率相对于所有记录而言,必须达到某一水平。以一个包含A与B两个项目的2-itemset为例,我们可以求得包含{A,B}项目组的支持度,若支持度大于等于所设定的最小支持度(Minimum Support)门槛值时,则{A,B}称为高频项目组。一个满足最小支持度的k-itemset,则称为高频k-项目组(Frequent k-itemset),一般表示为Large k或Frequent k。算法并从Large k的项目组中再试图产生长度超过k的项目集Large k+1,直到无法再找到更长的高频项目组为止。

关联规则挖掘的第二阶段是要产生关联规则。从高频项目组产生关联规则,是利用前一步骤的高频k-项目组来产生规则,在最小可信度(Minimum Confidence)的条件门槛下,若一规则所求得的可信度满足最小可信度,则称此规则为关联规则。

例如:经由高频k-项目组{A,B}所产生的规则,若其可信度大于等于最小可信度,则称{A,B}为关联规则。

就“啤酒+尿布”这个案例而言,使用关联规则挖掘技术,对交易资料库中的记录进行资料挖掘,首先必须要设定最小支持度与最小可信度两个门槛值,在此假设最小支持度min-support=5% 且最小可信度min-confidence=65%。因此符合需求的关联规则将必须同时满足以上两个条件。若经过挖掘所找到的关联规则 {尿布,啤酒}满足下列条件,将可接受{尿布,啤酒} 的关联规则。用公式可以描述为:

Support(尿布,啤酒)≥5% and Confidence(尿布,啤酒)≥65%。

其中,Support(尿布,啤酒)≥5%于此应用范例中的意义为:在所有的交易记录资料中,至少有5%的交易呈现尿布与啤酒这两项商品被同时购买的交易行为。Confidence(尿布,啤酒)≥65%于此应用范例中的意义为:在所有包含尿布的交易记录资料中,至少有65%的交易会同时购买啤酒。

因此,今后若有某消费者出现购买尿布的行为,我们将可推荐该消费者同时购买啤酒。这个商品推荐的行为则是根据{尿布,啤酒}关联规则而定,因为就过去的交易记录而言,支持了“大部分购买尿布的交易,会同时购买啤酒”的消费行为。

从上面的介绍还可以看出,关联规则挖掘通常比较适用于记录中的指标取离散值的情况。

如果原始数据库中的指标值是取连续的数据,则在关联规则挖掘之前应该进行适当的数据离散化(实际上就是将某个区间的值对应于某个值),数据的离散化是数据挖掘前的重要环节,离散化的过程是否合理将直接影响关联规则的挖掘结果。


FP-Growth算法

FP-Growth(频繁模式增长)算法是韩家炜老师在2000年提出的关联分析算法,它采取如下分治策略:将提供频繁项集的数据库压缩到一棵频繁模式树(FP-Tree),但仍保留项集关联信息;该算法和Apriori算法最大的不同有两点:第一,不产生候选集,第二,只需要两次遍历数据库,大大提高了效率。

Apiorio 算法

如果一个项集是非频繁的,那么它的超集必然也是非频繁的。

参考

电商数据挖掘之关联算法(一)



如何理解皮尔逊相关系数(Pearson Correlation Coefficient)?

LLR

  private double doItemSimilarity(long itemID1, long itemID2, long preferring1, long numUsers) throws TasteException {
    DataModel dataModel = getDataModel();
    long preferring1and2 = dataModel.getNumUsersWithPreferenceFor(itemID1, itemID2);
    if (preferring1and2 == 0) {
      return Double.NaN;
    }
    long preferring2 = dataModel.getNumUsersWithPreferenceFor(itemID2);
    double logLikelihood =
        LogLikelihood.logLikelihoodRatio(preferring1and2,
                                         preferring2 - preferring1and2,
                                         preferring1 - preferring1and2,
                                         numUsers - preferring1 - preferring2 + preferring1and2);
    return 1.0 - 1.0 / (1.0 + logLikelihood);
  }

long preferring1and2 = dataModel.getNumUsersWithPreferenceFor(itemID1, itemID2);
long preferring1 = dataModel.getNumUsersWithPreferenceFor(itemID1);
long preferring2 = dataModel.getNumUsersWithPreferenceFor(itemID2);
long numUsers = dataModel.getNumUsers();

k11: preferring1and2
k12: preferring2 - preferring1and2
k21: preferring1 - preferring1and2
k22: numUsers - preferring1 - preferring2 + preferring1and2

Event A Everything but A
Event B k11 k12
Everything but B k21 k22

LLR = 2 sum(k) (H(k) - H(rowSums(k)) - H(colSums(k)))

H = function(k) {N = sum(k) ; return (sum(k/N * log(k/N + (k==0)))}

/**
   * Calculates the Raw Log-likelihood ratio for two events, call them A and B.  Then we have:
   * <p/>
   * <table border="1" cellpadding="5" cellspacing="0">
   * <tbody><tr><td>&nbsp;</td><td>Event A</td><td>Everything but A</td></tr>
   * <tr><td>Event B</td><td>A and B together (k_11)</td><td>B, but not A (k_12)</td></tr>
   * <tr><td>Everything but B</td><td>A without B (k_21)</td><td>Neither A nor B (k_22)</td></tr></tbody>
   * </table>
   *
   * @param k11 The number of times the two events occurred together
   * @param k12 The number of times the second event occurred WITHOUT the first event
   * @param k21 The number of times the first event occurred WITHOUT the second event
   * @param k22 The number of times something else occurred (i.e. was neither of these events
   * @return The raw log-likelihood ratio
   *
   * <p/>
   * Credit to http://tdunning.blogspot.com/2008/03/surprise-and-coincidence.html for the table and the descriptions.
   */
  public static double logLikelihoodRatio(long k11, long k12, long k21, long k22) {
    Preconditions.checkArgument(k11 >= 0 && k12 >= 0 && k21 >= 0 && k22 >= 0);
    // note that we have counts here, not probabilities, and that the entropy is not normalized.
    double rowEntropy = entropy(k11 + k12, k21 + k22);
    double columnEntropy = entropy(k11 + k21, k12 + k22);
    double matrixEntropy = entropy(k11, k12, k21, k22);
    if (rowEntropy + columnEntropy < matrixEntropy) {
      // round off error
      return 0.0;
    }
    return 2.0 * (rowEntropy + columnEntropy - matrixEntropy);
  }
  /**
   * Merely an optimization for the common two argument case of {@link #entropy(long...)}
   * @see #logLikelihoodRatio(long, long, long, long)
   */
  private static double entropy(long a, long b) {
    return xLogX(a + b) - xLogX(a) - xLogX(b);
  }

信息熵是衡量分布的混乱程度或分散程度的一种度量。分布越分散(或者说分布越平均),信息熵就越大。分布越有序(或者说分布越集中),信息熵就越小。


Information retrieval

Entropy (information theory)

reference
Mahout Recommender Document: non-distributed
机器学习中的相似性度量
Mahout on Spark: What’s New in Recommenders
Mahout on Spark: What’s New in Recommenders, part 2
Intro to Cooccurrence Recommenders with Spark
Mahout: Scala & Spark Bindings
Surprise and Coincidence
How to create and App using Mahout
FAQ for using Mahout with Spark


Mahout on Spark: What’s New in Recommenders, part 2

Here similar means that they were liked by the same people. We’ll use another technique to narrow the items down to ones of the same genre later.


Intro to Cooccurrence Recommenders with Spark

rp = recommendations for a given user
hp = history of purchases for a given user
A = the matrix of all purchases by all users
rp = [A^tA]hp

This would produce reasonable recommendations, but is subject to skewed results due to the dominance of popular items. To avoid that, we can apply a weighting called the log likelihood ratio (LLR), which is a probabilistic measure of the importance of a cooccurrence.

The magnitude of the value in the matrix determines the strength of similarity of row item to the column item. We can use the LLR weights as a similarity measure that is nicely immune to unimportant similarities.

ItemSimilarityDriver

Creating the indicator matrix [AtA] is the core of this type of recommender. We have a quick flexible way to create this using text log files and creating output that’s in an easy form to digest. The job of data prep is greatly streamlined in the Mahout 1.0 snapshot. In the past a user would have to do all the data prep themselves. Translating their own user and item ids into Mahout ids, putting the data into text files, one element per line, and feeding them to the recommender. Out the other end you’d get a Hadoop binary file called a sequence file and you’d have to translate the Mahout ids into something your application could understand. No more.


Part 4: Tuning Your Recommender
两点改进

MAP

https://www.kaggle.com/wiki/MeanAveragePrecision
What you wanted to know about Mean Average Precision

《基于mahout on spark + elastic search搭建item推荐系统》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章