跳到主要内容

Apriori 算法(支持度、置信度、提升度)

一、直观理解:从购物小票里找“经常一起出现”的组合​

关联规则挖掘要在大量交易(事务)中发现形如

A⇒BA\Rightarrow B

的规则,读作:“买了 A 的人,也常常买 B”。

经典例子:{尿布} ⇒ {啤酒}。这不一定是因果,而是共现模式,可用于货架、捆绑销售、故障共现、课程同修等。

Apriori 是早期最著名的频繁项集算法,核心观察是:

频繁项集的子集一定频繁;若某集合不频繁,其超集也不频繁。

于是可以从小到大逐层扩展候选项集,并剪掉不可能频繁的分支。

二、适用场景与优缺点​

类型说明
适用场景购物篮、点击流、共病、文本共现(需离散化);目标是可解释的 if-then 规则而非黑盒预测。
核心优点指标直观(支持度/置信度/提升度);规则可业务解读;Apriori 原理清晰,便于手写与教学。
局限与缺点候选项多时昂贵(可用 FP-Growth 更快);阈值敏感,稀有但重要的规则易被漏;高度共线物品产生冗余规则;关联≠因果。

三、核心原理​

1. 三项核心指标​

设 NN 为事务总数,项集 A,BA,B 不交。

支持度(规则或项集有多常见):

supp(A∪B)=P(A∪B)=#{t:A∪B⊆t}N\mathrm{supp}(A\cup B)=P(A\cup B)=\frac{\#\{t:A\cup B\subseteq t\}}{N}

置信度(在 A 出现时 B 的条件概率):

conf(A⇒B)=P(B∣A)=supp(A∪B)supp(A)\mathrm{conf}(A\Rightarrow B)=P(B\mid A)=\frac{\mathrm{supp}(A\cup B)}{\mathrm{supp}(A)}

提升度(相对“B 本来就常见”是否更进一步):

lift(A⇒B)=conf(A⇒B)supp(B)=P(A∪B)P(A)P(B)\mathrm{lift}(A\Rightarrow B)=\frac{\mathrm{conf}(A\Rightarrow B)}{\mathrm{supp}(B)}=\frac{P(A\cup B)}{P(A)P(B)}
  • lift>1\mathrm{lift}>1:正向关联;
  • =1=1:独立;
  • <1<1:负向关联。

只靠置信度会把“因为 B 本身很热门”的规则抬上来,所以提升度几乎总是要报。

2. Apriori 流程​

  1. 设定最小支持度 min_sup、最小置信度 min_conf;
  2. 扫描数据得频繁 1-项集 L1L_1;
  3. 由 Lk−1L_{k-1} 连接生成候选 CkC_k,剪枝(若某 k-子集不在 Lk−1L_{k-1} 则删);
  4. 扫描计数,过滤得 LkL_k;
  5. 直到 LkL_k 空;
  6. 由频繁项集生成规则,过滤置信度,并计算 lift。

四、关键决策​

1. 阈值如何定​

  • min_sup 太高:规则少、全是大路货;太低:组合爆炸。
  • 可按业务最小可操作频次反推,如每天至少 30 单。
  • 对稀有高价值物品用分层或分类关联规则。

2. 规则筛选​

在 conf、lift 之外可加 leverage、conviction;去掉冗余(更长规则未提升 conf);按 lift 排序人工复核。

3. 数据预处理​

  • 事务 ID + 物品列表;
  • 连续变量先离散化(注意切割方式影响结果);
  • 极度热门物品可单独处理,避免统治所有规则。

五、MATLAB 示例​

下面给出可运行的迷你 Apriori(事务量小、教学用)。大规模请用专用工具或 Python mlxtend,思路相同。

% 事务库:每行一个购买集合(cell)
transactions = {
["面包","牛奶","尿布"];
["面包","尿布","啤酒","鸡蛋"];
["牛奶","尿布","啤酒","可乐"];
["面包","牛奶","尿布","啤酒"];
["面包","牛奶","可乐"];
["尿布","啤酒"];
["牛奶","尿布","啤酒","可乐"];
["面包","牛奶"];
};

minSup = 0.3; % 相对支持度
minConf = 0.6;

% ---- 统计所有物品 ----
items = string([]);
for i = 1:numel(transactions)
items = [items, transactions{i}]; %#ok<AGROW>
end
items = unique(items);

% 布尔矩阵
T = false(numel(transactions), numel(items));
for i = 1:numel(transactions)
T(i,:) = ismember(items, transactions{i});
end
N = size(T,1);

% ---- 频繁 1-项集 ----
sup1 = mean(T, 1);
L = items(sup1 >= minSup);
Lsup = sup1(sup1 >= minSup);

fprintf("频繁1-项集:\n");
for i = 1:numel(L)
fprintf(" {%s} supp=%.2f\n", L(i), Lsup(i));
end

% ---- 频繁 2-项集(示意;可推广到 k)----
rules = [];
cand = nchoosek(1:numel(L), 2);
fprintf("\n频繁2-项集与规则:\n");
for c = 1:size(cand,1)
is = cand(c,:);
mask = all(T(:, ismember(items, L(is))), 2);
supAB = mean(mask);
if supAB < minSup, continue; end
Aset = L(is);
fprintf(" {%s, %s} supp=%.2f\n", Aset(1), Aset(2), supAB);
% 生成 A=>B 与 B=>A
for dir = 1:2
if dir==1
A = Aset(1); B = Aset(2);
supA = mean(T(:, items==A)); supB = mean(T(:, items==B));
else
A = Aset(2); B = Aset(1);
supA = mean(T(:, items==A)); supB = mean(T(:, items==B));
end
conf = supAB / supA;
lift = conf / supB;
if conf >= minConf
fprintf(" %s => %s | conf=%.2f, lift=%.2f\n", A, B, conf, lift);
end
end
end

六、如何解释结果​

  1. 数据事务定义与物品字典;
  2. min_sup / min_conf 及理由;
  3. 高频项集表;
  4. 规则表:前件、后件、support、confidence、lift;
  5. 业务解读与可行动建议;
  6. 局限性:观测共现、可能混杂、阈值敏感。

优先展示 lift 高且 support 不太低 的规则,避免“置信度高但 lift≈1”的假强规则。

七、常见误区​

1. 只报置信度​

后件热门时 conf 天然高,必须看 lift。

2. 把关联规则写成因果​

货架干预效果需要实验或因果识别。

3. 阈值拍脑袋且不敏感性分析​

换一组阈值规则名单大变,要报告稳健规则。

4. 忽略时间与场景​

工作日/节假日、地区差异应分层挖掘。

八、小结​

Apriori 的核心是:

用“频繁子集”性质逐层找频繁项集,再导出满足支持度、置信度的规则,并用提升度判断是否超越独立基线。

它是可解释模式挖掘的代表。写结果时三项指标齐全、强调非因果,并做阈值敏感性,才符合数学建模的严谨表达。